-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchar.dart
76 lines (67 loc) · 1.93 KB
/
char.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
part of '../../character.dart';
/// Parses one character with code [char] and returns that character.
///
/// Example:
/// ```dart
/// Char(0x30)
/// ```
class Char extends ParserBuilder<String, int> {
static const _template16 = '''
if (source.contains1(state.pos, {{c0}})) {
state.ok = true;
state.pos++;
{{res0}} = {{cc}};
} else {
state.fail(state.pos, ParseError.expected, {{cc}});
}''';
static const _template16Fast = '''
if (source.contains1(state.pos, {{c0}})) {
state.ok = true;
state.pos++;
} else {
state.fail(state.pos, ParseError.expected, {{cc}});
}''';
static const _template32 = '''
if (source.contains2(state.pos, {{c0}}, {{c1}})) {
state.ok = true;
state.pos += 2;
{{res0}} = {{cc}};
} else {
state.fail(state.pos, ParseError.expected, {{cc}});
}''';
static const _template32Fast = '''
if (source.contains2(state.pos, {{c0}}, {{c1}})) {
state.ok = true;
state.pos += 2;
} else {
state.fail(state.pos, ParseError.expected, {{cc}});
}''';
final int char;
const Char(this.char);
@override
String build(Context context, ParserResult? result) {
if (!(char >= 0 && char <= 0xd7ff || char >= 0xe000 && char <= 0x10ffff)) {
throw ArgumentError.value(char, 'char', 'Invalid character code');
}
context.refersToStateSource = true;
final fast = result == null;
final str = String.fromCharCode(char);
final isUnicode = str.length > 1;
final String template;
if (isUnicode) {
ParseRuntime.addCapability(
context, ParseRuntimeCapability.contains2, true);
template = fast ? _template32Fast : _template32;
} else {
ParseRuntime.addCapability(
context, ParseRuntimeCapability.contains1, true);
template = fast ? _template16Fast : _template16;
}
final values = {
'c0': '${str.codeUnitAt(0)}',
'c1': isUnicode ? '${str.codeUnitAt(1)}' : '',
'cc': '$char',
};
return render(template, values, [result]);
}
}