parseman 0.6.2 → 0.7.1
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.
- package/README.md +25 -3
- package/dist/combinators/grammar.d.ts +30 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +9 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/index.cjs +151 -72
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +151 -72
- package/dist/index.js.map +2 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +155 -74
- package/dist/plugin/index.cjs.map +2 -2
- package/dist/plugin/index.js +155 -74
- package/dist/plugin/index.js.map +2 -2
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA8ShE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAuGzC;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
|
package/dist/plugin/index.cjs
CHANGED
|
@@ -1049,8 +1049,10 @@ function optional(combinator) {
|
|
|
1049
1049
|
_meta: meta,
|
|
1050
1050
|
_def: { tag: "optional", parser: combinator },
|
|
1051
1051
|
parse(input, pos, ctx) {
|
|
1052
|
+
const mark = saveTriviaMark(ctx);
|
|
1052
1053
|
const result = combinator.parse(input, pos, ctx);
|
|
1053
1054
|
if (result.ok) return result;
|
|
1055
|
+
rollbackTrivia(ctx, mark);
|
|
1054
1056
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1055
1057
|
}
|
|
1056
1058
|
};
|
|
@@ -1071,7 +1073,7 @@ function sepBy(combinator, separator) {
|
|
|
1071
1073
|
const values = [first.value];
|
|
1072
1074
|
let cur = first.span.end;
|
|
1073
1075
|
while (cur < input.length) {
|
|
1074
|
-
|
|
1076
|
+
const loopMark = saveTriviaMark(ctx);
|
|
1075
1077
|
let sepPos = cur;
|
|
1076
1078
|
if (ctx.trivia) {
|
|
1077
1079
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1084,10 +1086,9 @@ function sepBy(combinator, separator) {
|
|
|
1084
1086
|
}
|
|
1085
1087
|
const sep = separator.parse(input, sepPos, ctx);
|
|
1086
1088
|
if (!sep.ok) {
|
|
1087
|
-
rollbackTrivia(ctx,
|
|
1089
|
+
rollbackTrivia(ctx, loopMark);
|
|
1088
1090
|
break;
|
|
1089
1091
|
}
|
|
1090
|
-
mark = saveTriviaMark(ctx);
|
|
1091
1092
|
let nextPos = sep.span.end;
|
|
1092
1093
|
if (ctx.trivia) {
|
|
1093
1094
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1100,7 +1101,7 @@ function sepBy(combinator, separator) {
|
|
|
1100
1101
|
}
|
|
1101
1102
|
const next = combinator.parse(input, nextPos, ctx);
|
|
1102
1103
|
if (!next.ok) {
|
|
1103
|
-
rollbackTrivia(ctx,
|
|
1104
|
+
rollbackTrivia(ctx, loopMark);
|
|
1104
1105
|
break;
|
|
1105
1106
|
}
|
|
1106
1107
|
values.push(next.value);
|
|
@@ -1229,13 +1230,15 @@ function annotateSpan(span, index) {
|
|
|
1229
1230
|
|
|
1230
1231
|
// src/combinators/grammar.ts
|
|
1231
1232
|
function parser(opts, root) {
|
|
1233
|
+
const clearTrivia = opts.trivia === null;
|
|
1232
1234
|
return {
|
|
1233
1235
|
_tag: "grammar",
|
|
1234
1236
|
_meta: root._meta,
|
|
1235
1237
|
_def: {
|
|
1236
1238
|
tag: "grammar",
|
|
1237
1239
|
parser: root,
|
|
1238
|
-
triviaParser: opts.trivia,
|
|
1240
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
1241
|
+
clearTrivia,
|
|
1239
1242
|
trackLines: opts.trackLines ?? false
|
|
1240
1243
|
},
|
|
1241
1244
|
parse(input, pos, _ctx) {
|
|
@@ -1243,7 +1246,11 @@ function parser(opts, root) {
|
|
|
1243
1246
|
const ctx = {
|
|
1244
1247
|
..._ctx,
|
|
1245
1248
|
trackLines,
|
|
1246
|
-
|
|
1249
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
1250
|
+
...clearTrivia ? {
|
|
1251
|
+
trivia: void 0,
|
|
1252
|
+
triviaKindLabels: void 0
|
|
1253
|
+
} : opts.trivia != null ? {
|
|
1247
1254
|
trivia: opts.trivia,
|
|
1248
1255
|
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
1249
1256
|
} : {},
|
|
@@ -1258,6 +1265,9 @@ function parser(opts, root) {
|
|
|
1258
1265
|
}
|
|
1259
1266
|
};
|
|
1260
1267
|
}
|
|
1268
|
+
function noTrivia(root) {
|
|
1269
|
+
return parser({ trivia: null }, root);
|
|
1270
|
+
}
|
|
1261
1271
|
|
|
1262
1272
|
// src/compiler/trivia-fast-path.ts
|
|
1263
1273
|
var BLOCK_COMMENT = String.raw`\/\*(?:[^*]|\*(?!\/))*\*\/`;
|
|
@@ -1580,6 +1590,41 @@ function v(ctx, prefix = "_v") {
|
|
|
1580
1590
|
function ind(ctx) {
|
|
1581
1591
|
return " ".repeat(ctx.indent);
|
|
1582
1592
|
}
|
|
1593
|
+
function reindentStmts(stmts, targetLevels) {
|
|
1594
|
+
const nonEmpty = stmts.filter((s) => s.trim().length > 0);
|
|
1595
|
+
if (nonEmpty.length === 0) return stmts;
|
|
1596
|
+
const minLeading = Math.min(...nonEmpty.map((s) => s.length - s.trimStart().length));
|
|
1597
|
+
const targetPrefix = " ".repeat(targetLevels);
|
|
1598
|
+
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
1599
|
+
}
|
|
1600
|
+
function failReturn(expected, posExpr) {
|
|
1601
|
+
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1602
|
+
}
|
|
1603
|
+
function failReturnArr(expectedArr, posExpr) {
|
|
1604
|
+
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1605
|
+
}
|
|
1606
|
+
function failBody(ctx, expected, posExpr) {
|
|
1607
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1608
|
+
return failReturn(expected, posExpr);
|
|
1609
|
+
}
|
|
1610
|
+
function failArrBody(ctx, expectedArr, posExpr) {
|
|
1611
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1612
|
+
return failReturnArr(expectedArr, posExpr);
|
|
1613
|
+
}
|
|
1614
|
+
function emitIfFail(ctx, cond, body) {
|
|
1615
|
+
return [
|
|
1616
|
+
`${ind(ctx)}if (${cond}) {`,
|
|
1617
|
+
`${ind(ctx)} ${body}`,
|
|
1618
|
+
`${ind(ctx)}}`
|
|
1619
|
+
];
|
|
1620
|
+
}
|
|
1621
|
+
function emitElseFail(ctx, body) {
|
|
1622
|
+
return [
|
|
1623
|
+
`${ind(ctx)}else {`,
|
|
1624
|
+
`${ind(ctx)} ${body}`,
|
|
1625
|
+
`${ind(ctx)}}`
|
|
1626
|
+
];
|
|
1627
|
+
}
|
|
1583
1628
|
var NAMED_FN_FAIL = "_pfFail";
|
|
1584
1629
|
var NAMED_FN_END = "_pfEnd";
|
|
1585
1630
|
function namedFnPrelude() {
|
|
@@ -1590,8 +1635,10 @@ function pushNamedFnDecl(ctx, fnName, bodyStmts, valueVar, endVar) {
|
|
|
1590
1635
|
`function ${fnName}(input, _pos, _ctx) {`,
|
|
1591
1636
|
` let _pfok = false, _pfv, _pfe = _pos`,
|
|
1592
1637
|
` _pfail: {`,
|
|
1593
|
-
...bodyStmts,
|
|
1594
|
-
`
|
|
1638
|
+
...reindentStmts(bodyStmts, 2),
|
|
1639
|
+
` _pfv = ${valueVar}`,
|
|
1640
|
+
` _pfe = ${endVar}`,
|
|
1641
|
+
` _pfok = true`,
|
|
1595
1642
|
` }`,
|
|
1596
1643
|
` if (!_pfok) return ${NAMED_FN_FAIL}`,
|
|
1597
1644
|
` ${NAMED_FN_END} = _pfe`,
|
|
@@ -1605,7 +1652,7 @@ function emitNamedFnCall(ctx, fnName, pos, failExpected) {
|
|
|
1605
1652
|
return {
|
|
1606
1653
|
stmts: [
|
|
1607
1654
|
`${ind(ctx)}const ${vv} = ${fnName}(input, ${pos}, _ctx)`,
|
|
1608
|
-
|
|
1655
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, failExpected, pos)),
|
|
1609
1656
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
1610
1657
|
],
|
|
1611
1658
|
valueVar: vv,
|
|
@@ -1688,7 +1735,7 @@ function ensureTriviaFn(ctx) {
|
|
|
1688
1735
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
1689
1736
|
` let _e = _pos`,
|
|
1690
1737
|
` _triv: {`,
|
|
1691
|
-
...r.stmts,
|
|
1738
|
+
...reindentStmts(r.stmts, 2),
|
|
1692
1739
|
` _e = ${r.endVar}`,
|
|
1693
1740
|
` }`,
|
|
1694
1741
|
` if (_cap && _e > _pos) {`,
|
|
@@ -1703,14 +1750,6 @@ function ensureTriviaFn(ctx) {
|
|
|
1703
1750
|
function ensureTriviaCaptureFn(ctx) {
|
|
1704
1751
|
return ensureTriviaFn(ctx);
|
|
1705
1752
|
}
|
|
1706
|
-
function failStmt(ctx, expected, posExpr) {
|
|
1707
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1708
|
-
return `${ind(ctx)}return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1709
|
-
}
|
|
1710
|
-
function failArr(ctx, expectedArr, posExpr) {
|
|
1711
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1712
|
-
return `${ind(ctx)}return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1713
|
-
}
|
|
1714
1753
|
function firstSetCond(codeVar, fs) {
|
|
1715
1754
|
if (fs.kind === "any") return "true";
|
|
1716
1755
|
if (fs.kind === "empty") return "false";
|
|
@@ -1726,19 +1765,32 @@ function emitFallible(inner, ctx, pos) {
|
|
|
1726
1765
|
const savedLabel = ctx.failLabel;
|
|
1727
1766
|
const savedIndent = ctx.indent;
|
|
1728
1767
|
ctx.failLabel = lbl;
|
|
1729
|
-
ctx.indent =
|
|
1768
|
+
ctx.indent = savedIndent + 1;
|
|
1730
1769
|
const r = emit(inner, ctx, pos);
|
|
1731
1770
|
ctx.failLabel = savedLabel;
|
|
1732
1771
|
ctx.indent = savedIndent;
|
|
1733
1772
|
const ind0 = ind(ctx);
|
|
1773
|
+
const mL = ctx.capturing ? v(ctx, "_fcl") : null;
|
|
1774
|
+
const mR = ctx.capturing ? v(ctx, "_fcr") : null;
|
|
1775
|
+
const mTl = ctx.capturing ? v(ctx, "_fctl") : null;
|
|
1776
|
+
const mLg = ctx.capturing ? v(ctx, "_fclg") : null;
|
|
1734
1777
|
const stmts = [
|
|
1735
1778
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
1779
|
+
...mL ? [
|
|
1780
|
+
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
1781
|
+
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
1782
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
1783
|
+
`${ind0}const ${mLg} = _ctx._triviaLog?.length ?? 0`
|
|
1784
|
+
] : [],
|
|
1736
1785
|
`${ind0}${lbl}: {`,
|
|
1737
1786
|
...r.stmts,
|
|
1738
1787
|
`${ind0} ${valV} = ${r.valueVar}`,
|
|
1739
1788
|
`${ind0} ${endV} = ${r.endVar}`,
|
|
1740
1789
|
`${ind0} ${okV} = true`,
|
|
1741
|
-
`${ind0}}
|
|
1790
|
+
`${ind0}}`,
|
|
1791
|
+
...mL ? [
|
|
1792
|
+
`${ind0}if (!${okV}) { if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg} }`
|
|
1793
|
+
] : []
|
|
1742
1794
|
];
|
|
1743
1795
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
1744
1796
|
}
|
|
@@ -1751,9 +1803,9 @@ function emitLit(def, ctx, pos) {
|
|
|
1751
1803
|
if (caseInsensitive) {
|
|
1752
1804
|
ctx.needsCollator = true;
|
|
1753
1805
|
stmts.push(
|
|
1754
|
-
|
|
1806
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length`, failBody(ctx, expectedStr, pos)),
|
|
1755
1807
|
`${ind(ctx)}const ${vv}_s = input.slice(${pos}, ${pos} + ${len})`,
|
|
1756
|
-
|
|
1808
|
+
...emitIfFail(ctx, `_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0`, failBody(ctx, expectedStr, pos)),
|
|
1757
1809
|
`${ind(ctx)}const ${vv} = ${vv}_s`
|
|
1758
1810
|
);
|
|
1759
1811
|
} else if (len === 0) {
|
|
@@ -1761,7 +1813,7 @@ function emitLit(def, ctx, pos) {
|
|
|
1761
1813
|
} else if (len === 1) {
|
|
1762
1814
|
const code = value.codePointAt(0);
|
|
1763
1815
|
stmts.push(
|
|
1764
|
-
|
|
1816
|
+
...emitIfFail(ctx, `${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}`, failBody(ctx, expectedStr, pos)),
|
|
1765
1817
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1766
1818
|
);
|
|
1767
1819
|
} else if (len <= 4) {
|
|
@@ -1770,12 +1822,12 @@ function emitLit(def, ctx, pos) {
|
|
|
1770
1822
|
(_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
|
|
1771
1823
|
).join(" || ");
|
|
1772
1824
|
stmts.push(
|
|
1773
|
-
|
|
1825
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length || ${checks}`, failBody(ctx, expectedStr, pos)),
|
|
1774
1826
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1775
1827
|
);
|
|
1776
1828
|
} else {
|
|
1777
1829
|
stmts.push(
|
|
1778
|
-
|
|
1830
|
+
...emitIfFail(ctx, `!input.startsWith(${JSON.stringify(value)}, ${pos})`, failBody(ctx, expectedStr, pos)),
|
|
1779
1831
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1780
1832
|
);
|
|
1781
1833
|
}
|
|
@@ -1803,7 +1855,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
1803
1855
|
const stmts = [
|
|
1804
1856
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1805
1857
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1806
|
-
|
|
1858
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, '"keyword"', pos)),
|
|
1807
1859
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1808
1860
|
];
|
|
1809
1861
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1825,7 +1877,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
1825
1877
|
const stmts = [
|
|
1826
1878
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1827
1879
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1828
|
-
|
|
1880
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, expectedStr, pos)),
|
|
1829
1881
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1830
1882
|
];
|
|
1831
1883
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1906,11 +1958,12 @@ function emitChoice(def, ctx, pos) {
|
|
|
1906
1958
|
ctx.indent++;
|
|
1907
1959
|
const r = emit(p, ctx, pos);
|
|
1908
1960
|
stmts.push(...r.stmts);
|
|
1909
|
-
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}
|
|
1961
|
+
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}`);
|
|
1962
|
+
stmts.push(`${ind(ctx)}${endV} = ${r.endVar}`);
|
|
1910
1963
|
ctx.indent--;
|
|
1911
1964
|
stmts.push(`${ind(ctx)}}`);
|
|
1912
1965
|
}
|
|
1913
|
-
stmts.push(
|
|
1966
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
1914
1967
|
return { stmts, valueVar: valV, endVar: endV };
|
|
1915
1968
|
}
|
|
1916
1969
|
return emitNonDisjoint(def, def.strategy, allExpected, ctx, pos);
|
|
@@ -1933,7 +1986,7 @@ function emitGreedyClassify(def, superIndex, allExpected, ctx, pos) {
|
|
|
1933
1986
|
const stmts = [
|
|
1934
1987
|
`${ind(ctx)}${reVar}.lastIndex = ${pos}`,
|
|
1935
1988
|
`${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
|
|
1936
|
-
|
|
1989
|
+
...emitIfFail(ctx, `${matchV} === null`, failArrBody(ctx, allExpected, pos)),
|
|
1937
1990
|
`${ind(ctx)}const ${wordV} = ${matchV}[0]`,
|
|
1938
1991
|
`${ind(ctx)}const ${endV} = ${pos} + ${wordV}.length`,
|
|
1939
1992
|
`${ind(ctx)}let ${valV}`
|
|
@@ -1982,12 +2035,13 @@ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos) {
|
|
|
1982
2035
|
stmts.push(
|
|
1983
2036
|
...emitLeafCapture(ctx, JSON.stringify(litVal), pos, litEnd),
|
|
1984
2037
|
...tR.stmts,
|
|
1985
|
-
`${ind(ctx)}${valV} = ${tR.valueVar}
|
|
2038
|
+
`${ind(ctx)}${valV} = ${tR.valueVar}`,
|
|
2039
|
+
`${ind(ctx)}${endV} = ${litEnd}`
|
|
1986
2040
|
);
|
|
1987
2041
|
ctx.indent--;
|
|
1988
2042
|
stmts.push(`${ind(ctx)}}`);
|
|
1989
2043
|
}
|
|
1990
|
-
stmts.push(
|
|
2044
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
1991
2045
|
return { stmts, valueVar: valV, endVar: endV };
|
|
1992
2046
|
}
|
|
1993
2047
|
function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
@@ -2033,17 +2087,26 @@ function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
|
2033
2087
|
const rejectCond = autoNot.map(
|
|
2034
2088
|
(check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${endVar})`
|
|
2035
2089
|
).join(" || ");
|
|
2036
|
-
stmts.push(
|
|
2037
|
-
|
|
2038
|
-
);
|
|
2090
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2091
|
+
stmts.push(`${ind0} const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1`);
|
|
2092
|
+
stmts.push(`${ind0} if (!(${rejectCond})) {`);
|
|
2093
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2094
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2095
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2096
|
+
stmts.push(`${ind0} }`);
|
|
2097
|
+
stmts.push(`${ind0} }`);
|
|
2039
2098
|
if (rollback) stmts.push(`${ind0} if (!${resOkV}) { ${rollback} }`);
|
|
2040
2099
|
} else {
|
|
2041
|
-
stmts.push(`${ind0} if (${okVar}) {
|
|
2100
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2101
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2102
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2103
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2104
|
+
stmts.push(`${ind0} }`);
|
|
2042
2105
|
if (rollback) stmts.push(`${ind0} else { ${rollback} }`);
|
|
2043
2106
|
}
|
|
2044
2107
|
stmts.push(`${ind0}}`);
|
|
2045
2108
|
}
|
|
2046
|
-
stmts.push(
|
|
2109
|
+
stmts.push(...emitIfFail(ctx, `!${resOkV}`, failArrBody(ctx, allExpected, pos)));
|
|
2047
2110
|
return { stmts, valueVar: resValV, endVar: resEndV };
|
|
2048
2111
|
}
|
|
2049
2112
|
function emitNonDisjoint(def, strategy, allExpected, ctx, pos) {
|
|
@@ -2168,32 +2231,26 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2168
2231
|
const markV = v(ctx, "_mk");
|
|
2169
2232
|
const markTl = v(ctx, "_mktl");
|
|
2170
2233
|
const markLog = v(ctx, "_mklg");
|
|
2234
|
+
const markLv = v(ctx, "_mklv");
|
|
2171
2235
|
const spV = v(ctx, "_sp");
|
|
2172
2236
|
stmts.push(
|
|
2173
2237
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2174
2238
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2175
2239
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2240
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2176
2241
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`
|
|
2177
2242
|
);
|
|
2178
2243
|
sepAtPos = spV;
|
|
2179
|
-
const
|
|
2244
|
+
const rollbackToSep = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${markLog}; `;
|
|
2180
2245
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2181
|
-
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${
|
|
2182
|
-
const mark2V = v(ctx, "_mk2");
|
|
2183
|
-
const mark2Tl = v(ctx, "_mktl2");
|
|
2184
|
-
const mark2Log = v(ctx, "_mklg2");
|
|
2246
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}break }`);
|
|
2185
2247
|
const npV = v(ctx, "_np");
|
|
2186
|
-
stmts.push(
|
|
2187
|
-
`${ind(ctx)}const ${mark2V} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2188
|
-
`${ind(ctx)}const ${mark2Tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2189
|
-
`${ind(ctx)}const ${mark2Log} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2190
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`
|
|
2191
|
-
);
|
|
2192
|
-
const nextRollback = `if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mark2V}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mark2Tl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mark2Log}; `;
|
|
2248
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`);
|
|
2193
2249
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
|
|
2194
2250
|
stmts.push(
|
|
2195
2251
|
...nextStmts,
|
|
2196
|
-
|
|
2252
|
+
// item failed → unwind the separator too, back to the end of the last item
|
|
2253
|
+
`${ind(ctx)}if (!${nextOk}) { ${rollbackToSep}break }`,
|
|
2197
2254
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2198
2255
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2199
2256
|
);
|
|
@@ -2215,12 +2272,21 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2215
2272
|
);
|
|
2216
2273
|
}
|
|
2217
2274
|
} else {
|
|
2275
|
+
const markLv = ctx.capturing ? v(ctx, "_mklv") : null;
|
|
2276
|
+
const markRw = ctx.capturing ? v(ctx, "_mkrw") : null;
|
|
2277
|
+
if (markLv) {
|
|
2278
|
+
stmts.push(
|
|
2279
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2280
|
+
`${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
|
|
2281
|
+
);
|
|
2282
|
+
}
|
|
2218
2283
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2219
2284
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
|
|
2285
|
+
const nextRb = markLv ? `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markRw}; ` : "";
|
|
2220
2286
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd);
|
|
2221
2287
|
stmts.push(
|
|
2222
2288
|
...nextStmts,
|
|
2223
|
-
`${ind(ctx)}if (!${nextOk}) break`,
|
|
2289
|
+
`${ind(ctx)}if (!${nextOk}) { ${nextRb}break }`,
|
|
2224
2290
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2225
2291
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2226
2292
|
);
|
|
@@ -2264,12 +2330,12 @@ function emitScanTo(def, ctx, pos) {
|
|
|
2264
2330
|
if (!def.orEOF) {
|
|
2265
2331
|
const sentDef = def.sentinel._def;
|
|
2266
2332
|
const expectedStr = sentDef.tag === "literal" ? JSON.stringify([JSON.stringify(sentDef.value)]) : `["sentinel"]`;
|
|
2267
|
-
stmts.push(
|
|
2333
|
+
stmts.push(...emitIfFail(ctx, `!${foundV}`, failArrBody(ctx, expectedStr, pos)));
|
|
2268
2334
|
}
|
|
2269
2335
|
const valV = v(ctx);
|
|
2270
2336
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
2271
2337
|
if (ctx.capturing) {
|
|
2272
|
-
const cap = emitLeafCapture(ctx, valV, pos, curV).
|
|
2338
|
+
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
2273
2339
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
2274
2340
|
}
|
|
2275
2341
|
return { stmts, valueVar: valV, endVar: curV };
|
|
@@ -2279,7 +2345,7 @@ function emitNot(def, ctx, pos) {
|
|
|
2279
2345
|
return {
|
|
2280
2346
|
stmts: [
|
|
2281
2347
|
...stmts,
|
|
2282
|
-
|
|
2348
|
+
...emitIfFail(ctx, okVar, failBody(ctx, '"not"', pos))
|
|
2283
2349
|
],
|
|
2284
2350
|
valueVar: "null",
|
|
2285
2351
|
endVar: pos
|
|
@@ -2306,7 +2372,7 @@ function emitNode(def, ctx, pos) {
|
|
|
2306
2372
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
2307
2373
|
stmts.push(...innerStmts);
|
|
2308
2374
|
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
|
|
2309
|
-
stmts.push(
|
|
2375
|
+
stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
|
|
2310
2376
|
const stV = v(ctx, "_nst");
|
|
2311
2377
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
2312
2378
|
const ndV = v(ctx, "_nd");
|
|
@@ -2326,7 +2392,7 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
2326
2392
|
const ev = v(ctx, "_rte");
|
|
2327
2393
|
const stmts = [
|
|
2328
2394
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
2329
|
-
|
|
2395
|
+
...emitIfFail(ctx, `!${rv}.ok`, failBody(ctx, '"runtime"', pos)),
|
|
2330
2396
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
2331
2397
|
`${ind(ctx)}const ${ev} = ${rv}.span.end`
|
|
2332
2398
|
];
|
|
@@ -2360,16 +2426,14 @@ function emitRecover(def, ctx, pos) {
|
|
|
2360
2426
|
const ind0 = ind(ctx);
|
|
2361
2427
|
const scanV = v(ctx, "_sc");
|
|
2362
2428
|
const errV = v(ctx, "_err");
|
|
2363
|
-
const
|
|
2364
|
-
ctx.indent += 2;
|
|
2429
|
+
const whileBodyLevels = ctx.indent + 2;
|
|
2365
2430
|
const { stmts: sentStmts, okVar: sentOk } = emitFallible(def.sentinel, ctx, scanV);
|
|
2366
|
-
ctx.indent = savedIndent;
|
|
2367
2431
|
const stmts = [
|
|
2368
2432
|
...innerStmts,
|
|
2369
2433
|
`${ind0}if (!${okVar}) {`,
|
|
2370
2434
|
`${ind0} let ${scanV} = ${pos}`,
|
|
2371
2435
|
`${ind0} while (${scanV} < input.length) {`,
|
|
2372
|
-
...sentStmts,
|
|
2436
|
+
...reindentStmts(sentStmts, whileBodyLevels),
|
|
2373
2437
|
`${ind0} if (${sentOk}) break`,
|
|
2374
2438
|
`${ind0} ${scanV}++`,
|
|
2375
2439
|
`${ind0} }`,
|
|
@@ -2451,7 +2515,7 @@ function emit(p, ctx, pos) {
|
|
|
2451
2515
|
// try skipped; if fails, keep main end
|
|
2452
2516
|
`${ind(ctx)}let ${endV} = ${mainR.endVar}`,
|
|
2453
2517
|
`${ind(ctx)}try {`,
|
|
2454
|
-
...skipR.stmts.
|
|
2518
|
+
...reindentStmts(skipR.stmts, ctx.indent + 1),
|
|
2455
2519
|
`${ind(ctx)} ${endV} = ${skipR.endVar}`,
|
|
2456
2520
|
`${ind(ctx)}} catch {}`
|
|
2457
2521
|
],
|
|
@@ -2468,7 +2532,10 @@ function emit(p, ctx, pos) {
|
|
|
2468
2532
|
case "grammar": {
|
|
2469
2533
|
const savedTrivia = ctx.activeTrivia;
|
|
2470
2534
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
2471
|
-
if (def.
|
|
2535
|
+
if (def.clearTrivia) {
|
|
2536
|
+
ctx.activeTrivia = void 0;
|
|
2537
|
+
ctx.triviaKindLabels = void 0;
|
|
2538
|
+
} else if (def.triviaParser) {
|
|
2472
2539
|
ctx.activeTrivia = def.triviaParser;
|
|
2473
2540
|
if (def.triviaParser._meta.triviaKindLabels) {
|
|
2474
2541
|
ctx.triviaKindLabels = def.triviaParser._meta.triviaKindLabels;
|
|
@@ -2493,7 +2560,7 @@ function emit(p, ctx, pos) {
|
|
|
2493
2560
|
const vv = v(ctx);
|
|
2494
2561
|
return {
|
|
2495
2562
|
stmts: [
|
|
2496
|
-
|
|
2563
|
+
...emitIfFail(ctx, `!_mf[${fnIdx}](_ctx.state)`, failBody(ctx, '"gate"', pos)),
|
|
2497
2564
|
`${ind(ctx)}const ${vv} = null`
|
|
2498
2565
|
],
|
|
2499
2566
|
valueVar: vv,
|
|
@@ -2525,7 +2592,7 @@ function emit(p, ctx, pos) {
|
|
|
2525
2592
|
stmts: [
|
|
2526
2593
|
`${ind(ctx)}const ${rv} = { ..._ctx, state: _mf[${evIdx}]() }`,
|
|
2527
2594
|
`${ind(ctx)}const ${vv} = ${fn}(input, ${pos}, ${rv})`,
|
|
2528
|
-
|
|
2595
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, '"withCtx"', pos)),
|
|
2529
2596
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
2530
2597
|
],
|
|
2531
2598
|
valueVar: vv,
|
|
@@ -2602,7 +2669,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2602
2669
|
...ctx.regexDecls,
|
|
2603
2670
|
"",
|
|
2604
2671
|
...namedPrelude,
|
|
2605
|
-
|
|
2672
|
+
ctx.namedFnDecls.join("\n\n"),
|
|
2606
2673
|
`${collatorDecl}function _parse(input, _pos, _rp, _mf, _build, _ctx) {`,
|
|
2607
2674
|
` let pos = _pos`,
|
|
2608
2675
|
...r.stmts,
|
|
@@ -2613,7 +2680,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2613
2680
|
...ctx.regexDecls,
|
|
2614
2681
|
collatorDecl,
|
|
2615
2682
|
...namedPrelude,
|
|
2616
|
-
...ctx.namedFnDecls,
|
|
2683
|
+
...ctx.namedFnDecls.flatMap((decl, i) => i > 0 ? ["", decl] : [decl]),
|
|
2617
2684
|
`let pos = _pos`,
|
|
2618
2685
|
...r.stmts,
|
|
2619
2686
|
`return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
@@ -2648,7 +2715,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2648
2715
|
function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources) {
|
|
2649
2716
|
const bodyLines = [
|
|
2650
2717
|
` let pos = _pos`,
|
|
2651
|
-
...r.stmts
|
|
2718
|
+
...r.stmts,
|
|
2652
2719
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
2653
2720
|
];
|
|
2654
2721
|
const innerFn = [
|
|
@@ -2661,17 +2728,23 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
|
|
|
2661
2728
|
const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
|
|
2662
2729
|
if (!needsWrapper) return innerFn;
|
|
2663
2730
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
2664
|
-
|
|
2665
|
-
`/* @__PURE__ */ (() => {`,
|
|
2731
|
+
const hoistedDecls = [
|
|
2666
2732
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
2667
2733
|
collatorDecl ? ` ${collatorDecl.trim()}` : "",
|
|
2668
2734
|
mfDecl,
|
|
2669
2735
|
buildDecl,
|
|
2670
2736
|
...namedPrelude.map((l) => ` ${l}`),
|
|
2671
|
-
...ctx.namedFnDecls.flatMap((
|
|
2737
|
+
...ctx.namedFnDecls.flatMap((decl, i) => {
|
|
2738
|
+
const lines = decl.split("\n").map((l) => ` ${l}`);
|
|
2739
|
+
return i > 0 ? ["", ...lines] : lines;
|
|
2740
|
+
})
|
|
2741
|
+
].filter(Boolean);
|
|
2742
|
+
return [
|
|
2743
|
+
`/* @__PURE__ */ (() => {`,
|
|
2744
|
+
...hoistedDecls,
|
|
2672
2745
|
` return ${innerFn}`,
|
|
2673
2746
|
`})()`
|
|
2674
|
-
].
|
|
2747
|
+
].join("\n");
|
|
2675
2748
|
}
|
|
2676
2749
|
|
|
2677
2750
|
// src/combinators/scanTo.ts
|
|
@@ -2722,7 +2795,11 @@ function scanTo(sentinel, { skip: skip2 = [], orEOF = false } = {}) {
|
|
|
2722
2795
|
};
|
|
2723
2796
|
}
|
|
2724
2797
|
function balanced(open, close, options = {}) {
|
|
2725
|
-
const
|
|
2798
|
+
const self = ref();
|
|
2799
|
+
const inner = scanTo(literal(close), {
|
|
2800
|
+
...options,
|
|
2801
|
+
skip: [self, ...options.skip ?? []]
|
|
2802
|
+
});
|
|
2726
2803
|
const combi = transform(
|
|
2727
2804
|
sequence(literal(open), inner, literal(close)),
|
|
2728
2805
|
([o, content, c]) => o + content + c
|
|
@@ -2730,6 +2807,7 @@ function balanced(open, close, options = {}) {
|
|
|
2730
2807
|
if (combi._def.tag === "transform") {
|
|
2731
2808
|
combi._def.fnSrc = "([o, content, c]) => o + content + c";
|
|
2732
2809
|
}
|
|
2810
|
+
self.define(combi);
|
|
2733
2811
|
return combi;
|
|
2734
2812
|
}
|
|
2735
2813
|
|
|
@@ -2749,7 +2827,8 @@ var SUPPORTED = {
|
|
|
2749
2827
|
optional: (...a) => optional(a[0]),
|
|
2750
2828
|
sepBy: (...a) => sepBy(a[0], a[1]),
|
|
2751
2829
|
trivia: (...a) => trivia(a[0]),
|
|
2752
|
-
label: (...a) => label(a[0], a[1])
|
|
2830
|
+
label: (...a) => label(a[0], a[1]),
|
|
2831
|
+
noTrivia: (...a) => noTrivia(a[0])
|
|
2753
2832
|
};
|
|
2754
2833
|
function isScopeEntry(v2) {
|
|
2755
2834
|
return !!v2 && typeof v2 === "object" && "combi" in v2 && "mfSrcs" in v2;
|
|
@@ -3205,7 +3284,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
3205
3284
|
replacements.push({
|
|
3206
3285
|
start: init.start,
|
|
3207
3286
|
end: init.end,
|
|
3208
|
-
replacement: `{
|
|
3287
|
+
replacement: `{
|
|
3288
|
+
${compiledRules.entries.map(([k, expr]) => ` ${k}: ${expr}`).join(",\n")}
|
|
3289
|
+
}`
|
|
3209
3290
|
});
|
|
3210
3291
|
continue;
|
|
3211
3292
|
}
|