@thomasfosterau/effect-parse 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +247 -230
  2. package/dist/Ascii.d.ts +32 -53
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +576 -571
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts +6 -29
  7. package/dist/Binary.d.ts.map +1 -1
  8. package/dist/Binary.js +129 -116
  9. package/dist/Binary.js.map +1 -1
  10. package/dist/Bits.d.ts +4 -2
  11. package/dist/Bits.d.ts.map +1 -1
  12. package/dist/Bits.js +121 -123
  13. package/dist/Bits.js.map +1 -1
  14. package/dist/Compiler.d.ts +39 -0
  15. package/dist/Compiler.d.ts.map +1 -0
  16. package/dist/Compiler.js +48 -0
  17. package/dist/Compiler.js.map +1 -0
  18. package/dist/Encoding.d.ts +29 -46
  19. package/dist/Encoding.d.ts.map +1 -1
  20. package/dist/Encoding.js +76 -75
  21. package/dist/Encoding.js.map +1 -1
  22. package/dist/Expression.d.ts +15 -49
  23. package/dist/Expression.d.ts.map +1 -1
  24. package/dist/Expression.js +143 -131
  25. package/dist/Expression.js.map +1 -1
  26. package/dist/Input.d.ts +206 -177
  27. package/dist/Input.d.ts.map +1 -1
  28. package/dist/Input.js +317 -299
  29. package/dist/Input.js.map +1 -1
  30. package/dist/Nom.d.ts +44 -84
  31. package/dist/Nom.d.ts.map +1 -1
  32. package/dist/Nom.js +423 -453
  33. package/dist/Nom.js.map +1 -1
  34. package/dist/ParseError.d.ts +54 -49
  35. package/dist/ParseError.d.ts.map +1 -1
  36. package/dist/ParseError.js +233 -275
  37. package/dist/ParseError.js.map +1 -1
  38. package/dist/Parser.d.ts +345 -313
  39. package/dist/Parser.d.ts.map +1 -1
  40. package/dist/Parser.js +2010 -1802
  41. package/dist/Parser.js.map +1 -1
  42. package/dist/ParserSchema.d.ts +8 -7
  43. package/dist/ParserSchema.d.ts.map +1 -1
  44. package/dist/ParserSchema.js +49 -49
  45. package/dist/ParserSchema.js.map +1 -1
  46. package/dist/ParserStream.d.ts +26 -20
  47. package/dist/ParserStream.d.ts.map +1 -1
  48. package/dist/ParserStream.js +267 -255
  49. package/dist/ParserStream.js.map +1 -1
  50. package/dist/Syntax.d.ts +401 -0
  51. package/dist/Syntax.d.ts.map +1 -0
  52. package/dist/Syntax.js +717 -0
  53. package/dist/Syntax.js.map +1 -0
  54. package/dist/Text.d.ts +98 -134
  55. package/dist/Text.d.ts.map +1 -1
  56. package/dist/Text.js +534 -496
  57. package/dist/Text.js.map +1 -1
  58. package/dist/Token.d.ts +60 -42
  59. package/dist/Token.d.ts.map +1 -1
  60. package/dist/Token.js +331 -265
  61. package/dist/Token.js.map +1 -1
  62. package/dist/index.d.ts +16 -17
  63. package/dist/index.js +16 -17
  64. package/dist/internal/compiler/closure.d.ts +14 -16
  65. package/dist/internal/compiler/closure.d.ts.map +1 -1
  66. package/dist/internal/compiler/closure.js +1458 -1637
  67. package/dist/internal/compiler/closure.js.map +1 -1
  68. package/dist/internal/compiler/entries.d.ts +11 -11
  69. package/dist/internal/compiler/entries.d.ts.map +1 -1
  70. package/dist/internal/compiler/entries.js +36 -26
  71. package/dist/internal/compiler/entries.js.map +1 -1
  72. package/dist/internal/compiler/first.d.ts +19 -19
  73. package/dist/internal/compiler/first.d.ts.map +1 -1
  74. package/dist/internal/compiler/first.js +251 -227
  75. package/dist/internal/compiler/first.js.map +1 -1
  76. package/dist/internal/compiler/jit.d.ts +6 -17
  77. package/dist/internal/compiler/jit.d.ts.map +1 -1
  78. package/dist/internal/compiler/jit.js +860 -988
  79. package/dist/internal/compiler/jit.js.map +1 -1
  80. package/dist/internal/compiler/registry.d.ts +20 -21
  81. package/dist/internal/compiler/registry.d.ts.map +1 -1
  82. package/dist/internal/compiler/registry.js +21 -41
  83. package/dist/internal/compiler/registry.js.map +1 -1
  84. package/dist/internal/compiler/sets.d.ts +9 -13
  85. package/dist/internal/compiler/sets.d.ts.map +1 -1
  86. package/dist/internal/compiler/sets.js +76 -73
  87. package/dist/internal/compiler/sets.js.map +1 -1
  88. package/dist/internal/entries.d.ts +3 -3
  89. package/dist/internal/entries.d.ts.map +1 -1
  90. package/dist/internal/entries.js +38 -30
  91. package/dist/internal/entries.js.map +1 -1
  92. package/dist/internal/node.d.ts +177 -173
  93. package/dist/internal/node.d.ts.map +1 -1
  94. package/dist/internal/node.js +77 -66
  95. package/dist/internal/node.js.map +1 -1
  96. package/dist/internal/numbers.d.ts +7 -8
  97. package/dist/internal/numbers.d.ts.map +1 -1
  98. package/dist/internal/numbers.js +246 -276
  99. package/dist/internal/numbers.js.map +1 -1
  100. package/dist/internal/resume.d.ts +6 -24
  101. package/dist/internal/resume.d.ts.map +1 -1
  102. package/dist/internal/resume.js +30 -29
  103. package/dist/internal/resume.js.map +1 -1
  104. package/dist/internal/run.d.ts +15 -0
  105. package/dist/internal/run.d.ts.map +1 -0
  106. package/dist/internal/run.js +36 -0
  107. package/dist/internal/run.js.map +1 -0
  108. package/dist/internal/stack.d.ts +16 -0
  109. package/dist/internal/stack.d.ts.map +1 -0
  110. package/dist/internal/stack.js +26 -0
  111. package/dist/internal/stack.js.map +1 -0
  112. package/dist/internal/syntax.d.ts +146 -0
  113. package/dist/internal/syntax.d.ts.map +1 -0
  114. package/dist/internal/syntax.js +305 -0
  115. package/dist/internal/syntax.js.map +1 -0
  116. package/dist/internal/text.d.ts +10 -2
  117. package/dist/internal/text.d.ts.map +1 -1
  118. package/dist/internal/text.js +295 -345
  119. package/dist/internal/text.js.map +1 -1
  120. package/dist/internal/tokens.d.ts +25 -30
  121. package/dist/internal/tokens.d.ts.map +1 -1
  122. package/dist/internal/tokens.js +369 -363
  123. package/dist/internal/tokens.js.map +1 -1
  124. package/package.json +42 -28
  125. package/src/Ascii.ts +278 -187
  126. package/src/Binary.ts +150 -44
  127. package/src/Bits.ts +6 -3
  128. package/src/Compiler.ts +98 -0
  129. package/src/Expression.ts +10 -5
  130. package/src/Input.ts +106 -28
  131. package/src/Nom.ts +4 -3
  132. package/src/ParseError.ts +48 -51
  133. package/src/Parser.ts +1163 -795
  134. package/src/ParserStream.ts +104 -80
  135. package/src/Syntax.ts +900 -0
  136. package/src/Text.ts +272 -187
  137. package/src/Token.ts +180 -87
  138. package/src/index.ts +2 -0
  139. package/src/internal/compiler/closure.ts +121 -88
  140. package/src/internal/compiler/entries.ts +21 -8
  141. package/src/internal/compiler/first.ts +17 -15
  142. package/src/internal/compiler/jit.ts +360 -157
  143. package/src/internal/compiler/registry.ts +12 -33
  144. package/src/internal/compiler/sets.ts +17 -11
  145. package/src/internal/entries.ts +4 -2
  146. package/src/internal/node.ts +51 -37
  147. package/src/internal/numbers.ts +22 -20
  148. package/src/internal/resume.ts +8 -4
  149. package/src/internal/run.ts +41 -0
  150. package/src/internal/stack.ts +36 -0
  151. package/src/internal/syntax.ts +421 -0
  152. package/src/internal/text.ts +32 -25
  153. package/src/internal/tokens.ts +96 -51
  154. package/dist/index.d.ts.map +0 -1
  155. package/dist/index.js.map +0 -1
@@ -1,400 +1,406 @@
1
- const isRange = (u) => typeof u === "object" && u !== null && u._tag === "TokenRange";
2
- const toCode = (u) => typeof u === "number" ? u : u.codePointAt(0);
1
+ import * as Predicate from "effect/Predicate";
2
+ import { charOf, firstCodePoint } from "./text.js";
3
+ //#region src/internal/tokens.ts
4
+ const isRange = (u) => Predicate.isObjectOrArray(u) && u._tag === "TokenRange";
5
+ const toCode = (u) => Predicate.isNumber(u) ? u : firstCodePoint(u);
3
6
  /** @internal */
4
- export const describeChar = (s) => JSON.stringify(s);
7
+ const describeChar = (s) => JSON.stringify(s);
5
8
  const describeSet = (u) => {
6
- if (typeof u === "string") {
7
- const chars = Array.from(u);
8
- return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`;
9
- }
10
- if (typeof u === "number")
11
- return `0x${u.toString(16).padStart(2, "0")}`;
12
- if (typeof u === "function")
13
- return u.name ? u.name : "a matching token";
14
- if (u instanceof Uint8Array)
15
- return `one of ${describeBytes(u)}`;
16
- if (isRange(u))
17
- return `${describeSet(u.from)}..=${describeSet(u.to)}`;
18
- if (Array.isArray(u))
19
- return u.map(describeSet).join(" or ");
20
- return JSON.stringify(u);
9
+ if (Predicate.isString(u)) return Array.from(u).length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`;
10
+ if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, "0")}`;
11
+ if (Predicate.isFunction(u)) return u.name ? u.name : "a matching token";
12
+ if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`;
13
+ if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`;
14
+ if (Array.isArray(u)) return u.map(describeSet).join(" or ");
15
+ return JSON.stringify(u);
21
16
  };
22
17
  /** Renders bytes as a Rust-style byte string literal: b"GET\r\n". */
23
- export const describeBytes = (bytes) => {
24
- let out = "b\"";
25
- for (const b of bytes) {
26
- if (b === 0x22)
27
- out += "\\\"";
28
- else if (b === 0x5c)
29
- out += "\\\\";
30
- else if (b === 0x0a)
31
- out += "\\n";
32
- else if (b === 0x0d)
33
- out += "\\r";
34
- else if (b === 0x09)
35
- out += "\\t";
36
- else if (b >= 0x20 && b < 0x7f)
37
- out += String.fromCharCode(b);
38
- else
39
- out += `\\x${b.toString(16).padStart(2, "0")}`;
40
- }
41
- return out + "\"";
18
+ const describeBytes = (bytes) => {
19
+ let out = "b\"";
20
+ for (const b of bytes) if (b === 34) out += "\\\"";
21
+ else if (b === 92) out += "\\\\";
22
+ else if (b === 10) out += "\\n";
23
+ else if (b === 13) out += "\\r";
24
+ else if (b === 9) out += "\\t";
25
+ else if (b >= 32 && b < 127) out += String.fromCharCode(b);
26
+ else out += `\\x${b.toString(16).padStart(2, "0")}`;
27
+ return out + "\"";
42
28
  };
43
29
  const compileCode = (u) => {
44
- if (typeof u === "string") {
45
- const codes = Array.from(u, (c) => c.codePointAt(0));
46
- if (codes.length === 1) {
47
- const c = codes[0];
48
- return (x) => x === c;
49
- }
50
- return bitmap(codes);
51
- }
52
- if (typeof u === "number")
53
- return (x) => x === u;
54
- if (typeof u === "function")
55
- return u;
56
- if (u instanceof Uint8Array)
57
- return bitmap(Array.from(u));
58
- if (isRange(u)) {
59
- const from = toCode(u.from);
60
- const to = toCode(u.to);
61
- return (x) => x >= from && x <= to;
62
- }
63
- if (Array.isArray(u)) {
64
- const tests = u.map(compileCode);
65
- if (tests.length === 1)
66
- return tests[0];
67
- return (x) => {
68
- for (let i = 0; i < tests.length; i++)
69
- if (tests[i](x))
70
- return true;
71
- return false;
72
- };
73
- }
74
- throw new TypeError(`invalid token set: ${String(u)}`);
30
+ if (Predicate.isString(u)) {
31
+ const codes = Array.from(u, firstCodePoint);
32
+ if (codes.length === 1) {
33
+ const c = codes[0];
34
+ return (x) => x === c;
35
+ }
36
+ return bitmap(codes);
37
+ }
38
+ if (Predicate.isNumber(u)) return (x) => x === u;
39
+ if (Predicate.isFunction(u)) return u;
40
+ if (u instanceof Uint8Array) return bitmap(Array.from(u));
41
+ if (isRange(u)) {
42
+ const from = toCode(u.from);
43
+ const to = toCode(u.to);
44
+ return (x) => x >= from && x <= to;
45
+ }
46
+ if (Array.isArray(u)) {
47
+ const tests = u.map(compileCode);
48
+ if (tests.length === 1) return tests[0];
49
+ return (x) => {
50
+ for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true;
51
+ return false;
52
+ };
53
+ }
54
+ throw new TypeError(`invalid token set: ${String(u)}`);
75
55
  };
76
56
  const bitmap = (codes) => {
77
- const ascii = new Uint8Array(256);
78
- let other;
79
- for (const c of codes) {
80
- if (c < 256)
81
- ascii[c] = 1;
82
- else
83
- (other ??= new Set()).add(c);
84
- }
85
- if (other === undefined)
86
- return (x) => x < 256 && ascii[x] === 1;
87
- const set = other;
88
- return (x) => x < 256 ? ascii[x] === 1 : set.has(x);
57
+ const ascii = /* @__PURE__ */ new Uint8Array(256);
58
+ let other;
59
+ for (const c of codes) if (c < 256) ascii[c] = 1;
60
+ else (other ??= /* @__PURE__ */ new Set()).add(c);
61
+ if (other === void 0) return (x) => x < 256 && ascii[x] === 1;
62
+ const set = other;
63
+ return (x) => x < 256 ? ascii[x] === 1 : set.has(x);
89
64
  };
90
65
  const compileToken = (u) => {
91
- if (typeof u === "function")
92
- return u;
93
- if (Array.isArray(u)) {
94
- const set = new Set(u);
95
- return (t) => set.has(t);
96
- }
97
- return (t) => t === u;
66
+ if (Predicate.isFunction(u)) return u;
67
+ if (Array.isArray(u)) {
68
+ const set = new Set(u);
69
+ return (t) => set.has(t);
70
+ }
71
+ return (t) => t === u;
98
72
  };
99
73
  /**
100
- * Marks a predicate over characters that also accepts a code point (a
101
- * number), so string inputs can call it without allocating a string per
102
- * character.
103
- */
104
- export const CodePointPredicate = Symbol.for("effect-parse/CodePointPredicate");
74
+ * Marks a predicate over characters that also accepts a code point (a
75
+ * number), so string inputs can call it without allocating a string per
76
+ * character.
77
+ */
78
+ const CodePointPredicate = /*#__PURE__*/ Symbol.for("effect-parse/CodePointPredicate");
105
79
  /**
106
- * The code points accepted by a predicate, as sorted, disjoint, inclusive
107
- * ranges, when they are known. The compiler turns such predicates into
108
- * comparisons or tables.
109
- */
110
- export const PredicateRanges = Symbol.for("effect-parse/PredicateRanges");
80
+ * The code points accepted by a predicate, as sorted, disjoint, inclusive
81
+ * ranges, when they are known. The compiler turns such predicates into
82
+ * comparisons or tables.
83
+ */
84
+ const PredicateRanges = /*#__PURE__*/ Symbol.for("effect-parse/PredicateRanges");
111
85
  /**
112
- * Marks `f` as a {@link CodePointPredicate} named `name` (used in error
113
- * messages), optionally recording the code point ranges it accepts.
114
- */
115
- export const codePointPredicate = (name, f, ranges) => {
116
- Object.defineProperty(f, "name", { value: name });
117
- f[CodePointPredicate] = true;
118
- if (ranges !== undefined)
119
- f[PredicateRanges] = ranges;
120
- return f;
86
+ * Marks `f` as a {@link CodePointPredicate} named `name` (used in error
87
+ * messages), optionally recording the code point ranges it accepts.
88
+ */
89
+ const codePointPredicate = (name, f, ranges) => {
90
+ Object.defineProperty(f, "name", { value: name });
91
+ f[CodePointPredicate] = true;
92
+ if (ranges !== void 0) f[PredicateRanges] = ranges;
93
+ return f;
121
94
  };
122
95
  /**
123
- * Compiles a token set. Predicates for string inputs receive the token as a
124
- * string, so they are wrapped here.
125
- */
126
- export const compile = (set, kind = "code") => {
127
- const description = describeSet(set);
128
- let code;
129
- if (typeof set === "function" && kind === "string" && !(CodePointPredicate in set)) {
130
- const pred = set;
131
- code = (x) => pred(String.fromCodePoint(x));
132
- }
133
- else {
134
- code = compileCodeSafe(set, kind);
135
- }
136
- return { code, token: compileToken(set), description };
96
+ * Compiles a token set. Predicates for string inputs receive the token as a
97
+ * string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,
98
+ * which is several times slower, for the Basic Multilingual Plane.
99
+ */
100
+ const compile = (set, kind = "code") => {
101
+ const description = describeSet(set);
102
+ let code;
103
+ if (Predicate.isFunction(set) && kind === "string" && !(CodePointPredicate in set)) {
104
+ const pred = set;
105
+ code = (x) => pred(charOf(x));
106
+ } else code = compileCodeSafe(set, kind);
107
+ return {
108
+ code,
109
+ token: compileToken(set),
110
+ description
111
+ };
137
112
  };
138
113
  const compileCodeSafe = (set, kind) => {
139
- if (Array.isArray(set) && kind === "string") {
140
- // Predicates nested in arrays also take strings
141
- const tests = set.map((s) => compile(s, kind).code);
142
- return (x) => {
143
- for (let i = 0; i < tests.length; i++)
144
- if (tests[i](x))
145
- return true;
146
- return false;
147
- };
148
- }
149
- try {
150
- return compileCode(set);
151
- }
152
- catch {
153
- return () => false;
154
- }
114
+ if (Array.isArray(set) && kind === "string") {
115
+ const tests = set.map((s) => compile(s, kind).code);
116
+ return (x) => {
117
+ for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true;
118
+ return false;
119
+ };
120
+ }
121
+ try {
122
+ return compileCode(set);
123
+ } catch {
124
+ return () => false;
125
+ }
155
126
  };
156
- export const compileAny = (set) => {
157
- const forCode = compile(set, "code");
158
- const needsString = typeof set === "function" || Array.isArray(set);
159
- return {
160
- forString: needsString ? compile(set, "string") : forCode,
161
- forCode,
162
- description: forCode.description
163
- };
127
+ /**
128
+ * A small cache keyed by value, for the parts of a parser that are costly to
129
+ * build and depend only on a string (compiled sets, descriptions). Parsers
130
+ * built inside `Parser.gen` bodies are rebuilt on every run, usually from the
131
+ * same few strings. Dynamic strings could grow it without bound, so it is
132
+ * cleared when full.
133
+ */
134
+ const cached = (cache, key, build) => {
135
+ let a = cache.get(key);
136
+ if (a === void 0) {
137
+ if (cache.size >= 1024) cache.clear();
138
+ a = build(key);
139
+ cache.set(key, a);
140
+ }
141
+ return a;
142
+ };
143
+ const literalDescriptions = /*#__PURE__*/ new Map();
144
+ /** Describes a literal for error messages: `"abc"`, `b"abc"` or `["a", 1]`. */
145
+ const describeLiteral = (lit) => Predicate.isString(lit) ? cached(literalDescriptions, lit, describeChar) : lit instanceof Uint8Array ? describeBytes(lit) : `[${lit.map((t) => JSON.stringify(t)).join(", ")}]`;
146
+ const stringMatchers = /*#__PURE__*/ new Map();
147
+ const compileAny = (set) => Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set);
148
+ const compileAnyImpl = (set) => {
149
+ const forCode = compile(set, "code");
150
+ return {
151
+ forString: Predicate.isFunction(set) || Array.isArray(set) ? compile(set, "string") : forCode,
152
+ forCode,
153
+ description: forCode.description
154
+ };
164
155
  };
165
156
  /**
166
- * Whether the string token at `i` is a high surrogate at the very end of a
167
- * partial input, i.e. the first half of a code point whose second half has
168
- * not arrived yet.
169
- */
170
- export const splitSurrogate = (state, i) => {
171
- if (!state.partial || i !== state.end - 1)
172
- return false;
173
- const c = state.input.charCodeAt(i);
174
- return c >= 0xd800 && c <= 0xdbff;
157
+ * Whether the string token at `i` is a high surrogate at the very end of a
158
+ * partial input, i.e. the first half of a code point whose second half has
159
+ * not arrived yet.
160
+ */
161
+ const splitSurrogate = (state, i) => {
162
+ if (!state.partial || i !== state.end - 1) return false;
163
+ const c = state.input.charCodeAt(i);
164
+ return c >= 55296 && c <= 56319;
175
165
  };
176
166
  /** Reads the code point at `i` of a string. */
177
- export const codePointAt = (s, i) => {
178
- const c = s.charCodeAt(i);
179
- if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
180
- const d = s.charCodeAt(i + 1);
181
- if (d >= 0xdc00 && d <= 0xdfff)
182
- return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000;
183
- }
184
- return c;
167
+ const codePointAt = (s, i) => {
168
+ const c = s.charCodeAt(i);
169
+ if (c >= 55296 && c <= 56319 && i + 1 < s.length) {
170
+ const d = s.charCodeAt(i + 1);
171
+ if (d >= 56320 && d <= 57343) return (c - 55296 << 10) + (d - 56320) + 65536;
172
+ }
173
+ return c;
185
174
  };
186
175
  /**
187
- * Tests the token at the current position. Returns the token (as the input's
188
- * token type) and advances, or returns `NoMatch`/`End`.
189
- */
190
- export const NoMatch = Symbol("NoMatch");
191
- export const End = Symbol("End");
192
- export const nextIf = (state, m, negate) => {
193
- const pos = state.pos;
194
- if (pos >= state.end)
195
- return End;
196
- switch (state.inputKind) {
197
- case 0: {
198
- const s = state.input;
199
- if (splitSurrogate(state, pos))
200
- return End;
201
- const cp = codePointAt(s, pos);
202
- if (m.forString.code(cp) === negate)
203
- return NoMatch;
204
- const len = cp > 0xffff ? 2 : 1;
205
- state.pos = pos + len;
206
- return len === 1 ? s[pos] : s.slice(pos, pos + 2);
207
- }
208
- case 1: {
209
- const b = state.input[pos];
210
- if (m.forCode.code(b) === negate)
211
- return NoMatch;
212
- state.pos = pos + 1;
213
- return b;
214
- }
215
- default: {
216
- const t = state.input[pos];
217
- if (m.forCode.token(t) === negate)
218
- return NoMatch;
219
- state.pos = pos + 1;
220
- return t;
221
- }
222
- }
176
+ * Tests the token at the current position. Returns the token (as the input's
177
+ * token type) and advances, or returns `NoMatch`/`End`.
178
+ */
179
+ const NoMatch = /*#__PURE__*/ Symbol("NoMatch");
180
+ const End = /*#__PURE__*/ Symbol("End");
181
+ const nextIf = (state, m, negate) => {
182
+ const pos = state.pos;
183
+ if (pos >= state.end) return End;
184
+ switch (state.inputKind) {
185
+ case 0: {
186
+ const s = state.input;
187
+ if (splitSurrogate(state, pos)) return End;
188
+ const cp = codePointAt(s, pos);
189
+ if (m.forString.code(cp) === negate) return NoMatch;
190
+ const len = cp > 65535 ? 2 : 1;
191
+ state.pos = pos + len;
192
+ return len === 1 ? s[pos] : s.slice(pos, pos + 2);
193
+ }
194
+ case 1: {
195
+ const b = state.input[pos];
196
+ if (m.forCode.code(b) === negate) return NoMatch;
197
+ state.pos = pos + 1;
198
+ return b;
199
+ }
200
+ default: {
201
+ const t = state.input[pos];
202
+ if (m.forCode.token(t) === negate) return NoMatch;
203
+ state.pos = pos + 1;
204
+ return t;
205
+ }
206
+ }
223
207
  };
224
208
  /**
225
- * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`
226
- * tokens. Returns the offset reached, the number of tokens matched, and
227
- * whether the end of input was hit before `max` tokens.
228
- */
229
- export const scan = (state, m, negate, max) => {
230
- let i = state.pos;
231
- const end = state.end;
232
- let count = 0;
233
- switch (state.inputKind) {
234
- case 0: {
235
- const s = state.input;
236
- const test = m.forString.code;
237
- while (count < max) {
238
- if (i >= end)
239
- return { offset: i, count, hitEnd: true };
240
- const c = s.charCodeAt(i);
241
- if (c < 0xd800 || c > 0xdbff) {
242
- if (test(c) === negate)
243
- break;
244
- i++;
245
- }
246
- else {
247
- if (splitSurrogate(state, i))
248
- return { offset: i, count, hitEnd: true };
249
- const cp = codePointAt(s, i);
250
- if (test(cp) === negate)
251
- break;
252
- i += cp > 0xffff ? 2 : 1;
253
- }
254
- count++;
255
- }
256
- return { offset: i, count, hitEnd: false };
257
- }
258
- case 1: {
259
- const bytes = state.input;
260
- const test = m.forCode.code;
261
- while (count < max) {
262
- if (i >= end)
263
- return { offset: i, count, hitEnd: true };
264
- if (test(bytes[i]) === negate)
265
- break;
266
- i++;
267
- count++;
268
- }
269
- return { offset: i, count, hitEnd: false };
270
- }
271
- default: {
272
- const arr = state.input;
273
- const test = m.forCode.token;
274
- while (count < max) {
275
- if (i >= end)
276
- return { offset: i, count, hitEnd: true };
277
- if (test(arr[i]) === negate)
278
- break;
279
- i++;
280
- count++;
281
- }
282
- return { offset: i, count, hitEnd: false };
283
- }
284
- }
209
+ * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`
210
+ * tokens. Returns the offset reached, the number of tokens matched, and
211
+ * whether the end of input was hit before `max` tokens.
212
+ */
213
+ const scan = (state, m, negate, max) => {
214
+ let i = state.pos;
215
+ const end = state.end;
216
+ let count = 0;
217
+ switch (state.inputKind) {
218
+ case 0: {
219
+ const s = state.input;
220
+ const test = m.forString.code;
221
+ while (count < max) {
222
+ if (i >= end) return {
223
+ offset: i,
224
+ count,
225
+ hitEnd: true
226
+ };
227
+ const c = s.charCodeAt(i);
228
+ if (c < 55296 || c > 56319) {
229
+ if (test(c) === negate) break;
230
+ i++;
231
+ } else {
232
+ if (splitSurrogate(state, i)) return {
233
+ offset: i,
234
+ count,
235
+ hitEnd: true
236
+ };
237
+ const cp = codePointAt(s, i);
238
+ if (test(cp) === negate) break;
239
+ i += cp > 65535 ? 2 : 1;
240
+ }
241
+ count++;
242
+ }
243
+ return {
244
+ offset: i,
245
+ count,
246
+ hitEnd: false
247
+ };
248
+ }
249
+ case 1: {
250
+ const bytes = state.input;
251
+ const test = m.forCode.code;
252
+ while (count < max) {
253
+ if (i >= end) return {
254
+ offset: i,
255
+ count,
256
+ hitEnd: true
257
+ };
258
+ if (test(bytes[i]) === negate) break;
259
+ i++;
260
+ count++;
261
+ }
262
+ return {
263
+ offset: i,
264
+ count,
265
+ hitEnd: false
266
+ };
267
+ }
268
+ default: {
269
+ const arr = state.input;
270
+ const test = m.forCode.token;
271
+ while (count < max) {
272
+ if (i >= end) return {
273
+ offset: i,
274
+ count,
275
+ hitEnd: true
276
+ };
277
+ if (test(arr[i]) === negate) break;
278
+ i++;
279
+ count++;
280
+ }
281
+ return {
282
+ offset: i,
283
+ count,
284
+ hitEnd: false
285
+ };
286
+ }
287
+ }
285
288
  };
286
289
  /** Advances `n` tokens from `start`, returning the offset reached and the count. */
287
- export const advance = (state, start, n) => {
288
- if (state.inputKind !== 0) {
289
- const offset = Math.min(state.end, start + n);
290
- return { offset, count: offset - start };
291
- }
292
- const s = state.input;
293
- let i = start;
294
- let count = 0;
295
- while (count < n && i < state.end) {
296
- if (splitSurrogate(state, i))
297
- break;
298
- const c = s.charCodeAt(i);
299
- i += c >= 0xd800 && c <= 0xdbff && i + 1 < s.length && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00 ? 2 : 1;
300
- count++;
301
- }
302
- return { offset: i, count };
290
+ const advance = (state, start, n) => {
291
+ if (state.inputKind !== 0) {
292
+ const offset = Math.min(state.end, start + n);
293
+ return {
294
+ offset,
295
+ count: offset - start
296
+ };
297
+ }
298
+ const s = state.input;
299
+ let i = start;
300
+ let count = 0;
301
+ while (count < n && i < state.end) {
302
+ if (splitSurrogate(state, i)) break;
303
+ const c = s.charCodeAt(i);
304
+ i += c >= 55296 && c <= 56319 && i + 1 < s.length && (s.charCodeAt(i + 1) & 64512) === 56320 ? 2 : 1;
305
+ count++;
306
+ }
307
+ return {
308
+ offset: i,
309
+ count
310
+ };
303
311
  };
304
312
  /** Counts tokens between two offsets. */
305
- export const countTokens = (state, start, end) => {
306
- if (state.inputKind !== 0)
307
- return end - start;
308
- const s = state.input;
309
- let count = 0;
310
- for (let i = start; i < end; i++) {
311
- const c = s.charCodeAt(i);
312
- if (c >= 0xd800 && c <= 0xdbff && i + 1 < end && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00)
313
- i++;
314
- count++;
315
- }
316
- return count;
313
+ const countTokens = (state, start, end) => {
314
+ if (state.inputKind !== 0) return end - start;
315
+ const s = state.input;
316
+ let count = 0;
317
+ for (let i = start; i < end; i++) {
318
+ const c = s.charCodeAt(i);
319
+ if (c >= 55296 && c <= 56319 && i + 1 < end && (s.charCodeAt(i + 1) & 64512) === 56320) i++;
320
+ count++;
321
+ }
322
+ return count;
317
323
  };
318
- /** Finds `needle` in the input at or after `from`; returns -1 if absent. */
319
- export const indexOf = (state, needle, from) => {
320
- switch (state.inputKind) {
321
- case 0:
322
- return state.input.indexOf(needle, from);
323
- case 1: {
324
- const hay = state.input;
325
- const n = needle;
326
- if (n.length === 0)
327
- return from <= hay.length ? from : -1;
328
- const first = n[0];
329
- let i = hay.indexOf(first, from);
330
- while (i !== -1 && i + n.length <= hay.length) {
331
- let j = 1;
332
- while (j < n.length && hay[i + j] === n[j])
333
- j++;
334
- if (j === n.length)
335
- return i;
336
- i = hay.indexOf(first, i + 1);
337
- }
338
- return -1;
339
- }
340
- default: {
341
- const hay = state.input;
342
- const n = needle;
343
- outer: for (let i = from; i + n.length <= hay.length; i++) {
344
- for (let j = 0; j < n.length; j++)
345
- if (hay[i + j] !== n[j])
346
- continue outer;
347
- return i;
348
- }
349
- return -1;
350
- }
351
- }
324
+ /** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
325
+ const indexOf = (state, needle, from) => {
326
+ const last = state.end - needle.length;
327
+ if (from > last) return -1;
328
+ switch (state.inputKind) {
329
+ case 0: {
330
+ const i = state.input.indexOf(needle, from);
331
+ return i <= last ? i : -1;
332
+ }
333
+ case 1: {
334
+ const hay = state.input;
335
+ const n = needle;
336
+ if (n.length === 0) return from;
337
+ const first = n[0];
338
+ let i = hay.indexOf(first, from);
339
+ while (i !== -1 && i <= last) {
340
+ let j = 1;
341
+ while (j < n.length && hay[i + j] === n[j]) j++;
342
+ if (j === n.length) return i;
343
+ i = hay.indexOf(first, i + 1);
344
+ }
345
+ return -1;
346
+ }
347
+ default: {
348
+ const hay = state.input;
349
+ const n = needle;
350
+ outer: for (let i = from; i <= last; i++) {
351
+ for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer;
352
+ return i;
353
+ }
354
+ return -1;
355
+ }
356
+ }
352
357
  };
353
358
  /**
354
- * Compares the input at the current position with a literal. Returns the
355
- * number of matching units if the literal matches completely (its length),
356
- * -1 on mismatch, or -2 when the input ends while matching a prefix.
357
- */
358
- export const matchLiteral = (state, lit, caseless) => {
359
- const pos = state.pos;
360
- const len = lit.length;
361
- const avail = state.end - pos;
362
- const n = Math.min(len, avail);
363
- switch (state.inputKind) {
364
- case 0: {
365
- const s = state.input;
366
- const l = lit;
367
- if (!caseless) {
368
- if (avail >= len)
369
- return s.startsWith(l, pos) ? len : -1;
370
- return l.startsWith(s.slice(pos)) ? -2 : -1;
371
- }
372
- for (let i = 0; i < n; i++) {
373
- if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i)))
374
- return -1;
375
- }
376
- return n === len ? len : -2;
377
- }
378
- case 1: {
379
- const b = state.input;
380
- const l = lit;
381
- for (let i = 0; i < n; i++) {
382
- const x = b[pos + i];
383
- const y = l[i];
384
- if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y)
385
- return -1;
386
- }
387
- return n === len ? len : -2;
388
- }
389
- default: {
390
- const a = state.input;
391
- const l = lit;
392
- for (let i = 0; i < n; i++)
393
- if (a[pos + i] !== l[i])
394
- return -1;
395
- return n === len ? len : -2;
396
- }
397
- }
359
+ * Compares the input at the current position with a literal. Returns the
360
+ * number of matching units if the literal matches completely (its length),
361
+ * -1 on mismatch, or -2 when the input ends while matching a prefix.
362
+ */
363
+ const matchLiteral = (state, lit, caseless) => {
364
+ const r = match(state, lit, caseless);
365
+ if (r < 0 && state.syntax !== void 0) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos));
366
+ return r;
367
+ };
368
+ const match = (state, lit, caseless) => {
369
+ const pos = state.pos;
370
+ const len = lit.length;
371
+ const avail = state.end - pos;
372
+ const n = Math.min(len, avail);
373
+ switch (state.inputKind) {
374
+ case 0: {
375
+ const s = state.input;
376
+ const l = lit;
377
+ if (!caseless) {
378
+ if (avail >= len) return s.startsWith(l, pos) ? len : -1;
379
+ return l.startsWith(s.slice(pos)) ? -2 : -1;
380
+ }
381
+ for (let i = 0; i < n; i++) if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i))) return -1;
382
+ return n === len ? len : -2;
383
+ }
384
+ case 1: {
385
+ const b = state.input;
386
+ const l = lit;
387
+ for (let i = 0; i < n; i++) {
388
+ const x = b[pos + i];
389
+ const y = l[i];
390
+ if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1;
391
+ }
392
+ return n === len ? len : -2;
393
+ }
394
+ default: {
395
+ const a = state.input;
396
+ const l = lit;
397
+ for (let i = 0; i < n; i++) if (a[pos + i] !== l[i]) return -1;
398
+ return n === len ? len : -2;
399
+ }
400
+ }
398
401
  };
399
402
  const lowerAscii = (c) => c >= 65 && c <= 90 ? c + 32 : c;
403
+ //#endregion
404
+ export { End, NoMatch, PredicateRanges, advance, codePointPredicate, compile, compileAny, countTokens, describeChar, describeLiteral, indexOf, matchLiteral, nextIf, scan, splitSurrogate };
405
+
400
406
  //# sourceMappingURL=tokens.js.map