parseman 0.61.4 → 0.61.6
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/dist/analysis/diagnostics.js +844 -522
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +846 -522
- package/dist/cli/index.js.map +3 -3
- package/dist/cst/capture-buffer.d.ts +3 -2
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +890 -523
- package/dist/index.js.map +3 -3
- package/dist/plugin/entry-supercompiler.d.ts +15 -0
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/index.js +959 -503
- package/dist/plugin/index.js.map +3 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/fail-clean.d.ts.map +1 -1
- package/dist/table/hold-gap.d.ts.map +1 -1
- package/dist/table/index.js +421 -54
- package/dist/table/index.js.map +3 -3
- package/dist/table/late-frame.d.ts +18 -0
- package/dist/table/late-frame.d.ts.map +1 -0
- package/dist/table/ops.d.ts +17 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/select-hot.d.ts +9 -0
- package/dist/table/select-hot.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +5 -1
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cst/capture-buffer.ts +20 -11
- package/src/plugin/entry-supercompiler.ts +110 -1
- package/src/table/assemble.ts +124 -4
- package/src/table/child-slots.ts +9 -1
- package/src/table/emit-assembly.ts +101 -14
- package/src/table/encode.ts +69 -6
- package/src/table/exec.ts +7 -1
- package/src/table/fail-clean.ts +8 -1
- package/src/table/hold-gap.ts +5 -1
- package/src/table/late-frame.ts +54 -0
- package/src/table/ops.ts +19 -0
- package/src/table/select-hot.ts +96 -18
- package/src/table/site-labels.ts +38 -14
- package/src/version.ts +1 -1
package/dist/table/index.js
CHANGED
|
@@ -742,26 +742,34 @@ function popCstChild(ctx) {
|
|
|
742
742
|
const b = ctx._cstBuf;
|
|
743
743
|
if (b) {
|
|
744
744
|
const ch2 = b.ch;
|
|
745
|
-
if (b.rawOnly !== true
|
|
746
|
-
ch2
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
745
|
+
if (b.rawOnly !== true) {
|
|
746
|
+
if (ch2) {
|
|
747
|
+
ch2.pop();
|
|
748
|
+
if (ch2.length === 1) {
|
|
749
|
+
b.single = ch2[0];
|
|
750
|
+
b.ch = void 0;
|
|
751
|
+
}
|
|
752
|
+
} else b.single = void 0;
|
|
751
753
|
}
|
|
752
|
-
if (b.noRaw === true)
|
|
753
|
-
|
|
754
|
-
|
|
754
|
+
if (b.noRaw === true) {
|
|
755
|
+
b.rawLen = (b.rawLen ?? 1) - 1;
|
|
756
|
+
return void 0;
|
|
757
|
+
}
|
|
758
|
+
if (b.raw) {
|
|
759
|
+
const entry2 = b.raw.pop();
|
|
755
760
|
if (b.raw.length === 1) {
|
|
756
761
|
b.rawSingle = b.raw[0];
|
|
757
762
|
b.raw = void 0;
|
|
758
763
|
}
|
|
759
|
-
|
|
760
|
-
|
|
764
|
+
return entry2;
|
|
765
|
+
}
|
|
766
|
+
const entry = b.rawSingle;
|
|
767
|
+
b.rawSingle = void 0;
|
|
768
|
+
return entry;
|
|
761
769
|
}
|
|
762
770
|
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
763
771
|
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
764
|
-
|
|
772
|
+
return ctx._cstRawChildren?.pop();
|
|
765
773
|
}
|
|
766
774
|
function cstRawLen(ctx) {
|
|
767
775
|
const b = ctx._cstBuf;
|
|
@@ -3628,7 +3636,7 @@ function regex(pattern, flags = "") {
|
|
|
3628
3636
|
}
|
|
3629
3637
|
|
|
3630
3638
|
// src/version.ts
|
|
3631
|
-
var PARSEMAN_VERSION = "0.61.
|
|
3639
|
+
var PARSEMAN_VERSION = "0.61.6";
|
|
3632
3640
|
|
|
3633
3641
|
// src/table/lex-body.ts
|
|
3634
3642
|
function buildLexBodyRecognizer(spec, constants) {
|
|
@@ -5797,6 +5805,8 @@ var OP_RGATE = 45;
|
|
|
5797
5805
|
var OP_GAPGATE = 46;
|
|
5798
5806
|
var OP_RGATE2 = 47;
|
|
5799
5807
|
var OP_STRICT = 48;
|
|
5808
|
+
var OP_CONT = 49;
|
|
5809
|
+
var OP_SEED = 50;
|
|
5800
5810
|
var OP_DISPATCH = 25;
|
|
5801
5811
|
var OP_ROUTED = 26;
|
|
5802
5812
|
var OP_NAMES = {
|
|
@@ -5847,7 +5857,9 @@ var OP_NAMES = {
|
|
|
5847
5857
|
[OP_LEX_PROGRAM]: "LEX_PROGRAM",
|
|
5848
5858
|
[OP_GAPGATE]: "GAPGATE",
|
|
5849
5859
|
[OP_RGATE2]: "RGATE2",
|
|
5850
|
-
[OP_STRICT]: "STRICT"
|
|
5860
|
+
[OP_STRICT]: "STRICT",
|
|
5861
|
+
[OP_CONT]: "CONT",
|
|
5862
|
+
[OP_SEED]: "SEED"
|
|
5851
5863
|
};
|
|
5852
5864
|
|
|
5853
5865
|
// src/table/scan-shapes.ts
|
|
@@ -6920,6 +6932,13 @@ function childSlotOffsets(code, ip, out) {
|
|
|
6920
6932
|
case OP_RGATE2:
|
|
6921
6933
|
out.push(ip + 2);
|
|
6922
6934
|
return true;
|
|
6935
|
+
// `CONT corner wrapper tail`: `tail` is reached through `wrapper`.
|
|
6936
|
+
case OP_CONT:
|
|
6937
|
+
out.push(ip + 1, ip + 2);
|
|
6938
|
+
return true;
|
|
6939
|
+
case OP_SEED:
|
|
6940
|
+
out.push(ip + 1);
|
|
6941
|
+
return true;
|
|
6923
6942
|
// `STRICT strict tolerant` — both encodings are reachable; an assembly keeps one.
|
|
6924
6943
|
case OP_STRICT:
|
|
6925
6944
|
out.push(ip + 1, ip + 2);
|
|
@@ -7016,7 +7035,7 @@ function passCollapse(code, ip, hostCst) {
|
|
|
7016
7035
|
else if (op === OP_RULE) at = code[at + 1];
|
|
7017
7036
|
else break;
|
|
7018
7037
|
}
|
|
7019
|
-
return code[at] === OP_NODE;
|
|
7038
|
+
return code[at] === OP_NODE || code[at] === OP_CONT;
|
|
7020
7039
|
}
|
|
7021
7040
|
function gatedPassCollapse(code, ip, hostCst) {
|
|
7022
7041
|
const flags = code[ip + 3];
|
|
@@ -7075,7 +7094,7 @@ function transfer(code, ip, at, hostCst) {
|
|
|
7075
7094
|
}
|
|
7076
7095
|
return at;
|
|
7077
7096
|
}
|
|
7078
|
-
function computeSiteLabels(code, roots, hostCst) {
|
|
7097
|
+
function computeSiteLabels(code, roots, hostCst, late) {
|
|
7079
7098
|
const labels = /* @__PURE__ */ new Map();
|
|
7080
7099
|
const work = [];
|
|
7081
7100
|
const push = (ip, l) => {
|
|
@@ -7090,16 +7109,33 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
7090
7109
|
labels.set(ip, next);
|
|
7091
7110
|
work.push(ip);
|
|
7092
7111
|
};
|
|
7093
|
-
|
|
7112
|
+
const opened = /* @__PURE__ */ new Set();
|
|
7094
7113
|
const kids = [];
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7114
|
+
const lateIps = /* @__PURE__ */ new Set();
|
|
7115
|
+
for (const r of roots) push(r, TOP);
|
|
7116
|
+
for (let pass = 0; pass < 2; pass++) {
|
|
7117
|
+
while (work.length > 0) {
|
|
7118
|
+
const ip = work.pop();
|
|
7119
|
+
const down = transfer(code, ip, labels.get(ip), hostCst);
|
|
7120
|
+
kids.length = 0;
|
|
7121
|
+
if (late === void 0 || code[ip] !== OP_SEED || opened.has(ip)) childSlots(code, ip, kids);
|
|
7122
|
+
for (const c of kids) push(c, down);
|
|
7123
|
+
}
|
|
7124
|
+
if (late === void 0 || pass === 1) break;
|
|
7125
|
+
for (const [ip, l] of [...labels]) {
|
|
7126
|
+
if (code[ip] !== OP_CONT) continue;
|
|
7127
|
+
if (late(ip, l.tri)) lateIps.add(ip);
|
|
7128
|
+
else {
|
|
7129
|
+
const seed = seedOf(code, ip);
|
|
7130
|
+
opened.add(seed);
|
|
7131
|
+
work.push(seed);
|
|
7132
|
+
}
|
|
7133
|
+
}
|
|
7101
7134
|
}
|
|
7102
|
-
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
7135
|
+
return { at: (ip) => labels.get(ip) ?? TOP, late: lateIps };
|
|
7136
|
+
}
|
|
7137
|
+
function seedOf(code, cont) {
|
|
7138
|
+
return code[code[code[cont + 2] + 2] + 2];
|
|
7103
7139
|
}
|
|
7104
7140
|
function scopeIsIdentity(code, ip, at) {
|
|
7105
7141
|
const op = code[ip];
|
|
@@ -7347,6 +7383,30 @@ function largeChoiceLiteralPretest(code, constants, armIp) {
|
|
|
7347
7383
|
}) ? family : void 0;
|
|
7348
7384
|
}
|
|
7349
7385
|
|
|
7386
|
+
// src/table/late-frame.ts
|
|
7387
|
+
function continuationGate(code, ip) {
|
|
7388
|
+
let at = ip;
|
|
7389
|
+
for (let n = 0; n < 8; n++) {
|
|
7390
|
+
const op2 = code[at];
|
|
7391
|
+
if (op2 === OP_RULE) at = code[at + 1];
|
|
7392
|
+
else if (op2 === OP_WITHCTX) at = code[at + 2];
|
|
7393
|
+
else break;
|
|
7394
|
+
}
|
|
7395
|
+
const op = code[at];
|
|
7396
|
+
if (op === OP_OPT) {
|
|
7397
|
+
const c = code[at + 1];
|
|
7398
|
+
return code[c] === OP_GATE ? { cls: code[c + 1], gapRow: -1, follow: -1, other: -1 } : void 0;
|
|
7399
|
+
}
|
|
7400
|
+
if (op !== OP_REP && op !== OP_REPV) return void 0;
|
|
7401
|
+
if (code[at + 2] !== 0 || code[at + 4] >= 0 || code[at + 7] < 0) return void 0;
|
|
7402
|
+
const item = code[at + 1];
|
|
7403
|
+
return code[item] === OP_GAPGATE ? { cls: code[at + 7], gapRow: code[item + 2], follow: code[item + 3], other: code[item + 4] } : { cls: code[at + 7], gapRow: -1, follow: -1, other: -1 };
|
|
7404
|
+
}
|
|
7405
|
+
function canDecide(code, ip, tri, triviaScan) {
|
|
7406
|
+
if (tri !== TRI_NONE && (tri < 0 || triviaScan[tri] == null)) return false;
|
|
7407
|
+
return continuationGate(code, code[ip + 3]) !== void 0;
|
|
7408
|
+
}
|
|
7409
|
+
|
|
7350
7410
|
// src/table/field-spec.ts
|
|
7351
7411
|
function fieldSpec(slot) {
|
|
7352
7412
|
return Array.isArray(slot) ? { name: slot[0], bits: slot[1] } : { name: slot, bits: 0 };
|
|
@@ -7394,6 +7454,10 @@ function rowNullable(code, k, ip, memo) {
|
|
|
7394
7454
|
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
7395
7455
|
} else if (op === OP_REP || op === OP_REPV) {
|
|
7396
7456
|
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
7457
|
+
} else if (op === OP_SEED) {
|
|
7458
|
+
out = rowNullable(code, k, code[ip + 1], memo);
|
|
7459
|
+
} else if (op === OP_CONT) {
|
|
7460
|
+
out = rowNullable(code, k, code[ip + 1], memo) && rowNullable(code, k, code[ip + 3], memo);
|
|
7397
7461
|
} else if (WRAPPERS.has(op)) {
|
|
7398
7462
|
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
7399
7463
|
}
|
|
@@ -7507,6 +7571,7 @@ var EMITTED_PARAMS = [
|
|
|
7507
7571
|
"skipDeferredTrivia",
|
|
7508
7572
|
// The pass-through collapse (`run-support.ts`).
|
|
7509
7573
|
"collapseEmpty",
|
|
7574
|
+
"popCstChild",
|
|
7510
7575
|
// Constructor-built tree objects (`cst/plain.d.ts`): a `new` call has no
|
|
7511
7576
|
// allocation site, so V8 cannot pretenure them.
|
|
7512
7577
|
"_SP",
|
|
@@ -7786,7 +7851,12 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
|
|
|
7786
7851
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
7787
7852
|
const reachable = [...reachableSites(code, roots)];
|
|
7788
7853
|
const GAP_ROWS = gapNeutral ? /* @__PURE__ */ new Set() : new Set([...gapRows(code, roots)].filter((row) => !gapRegexLowers(k[code[row + 1]])));
|
|
7789
|
-
const labels = computeSiteLabels(
|
|
7854
|
+
const labels = computeSiteLabels(
|
|
7855
|
+
code,
|
|
7856
|
+
roots,
|
|
7857
|
+
hostCst,
|
|
7858
|
+
cfg.tolerant || cfg.probe ? void 0 : (ip, tri) => canDecide(code, ip, tri, t.triviaScan)
|
|
7859
|
+
);
|
|
7790
7860
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
7791
7861
|
const nullable2 = /* @__PURE__ */ new Map();
|
|
7792
7862
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
@@ -8033,6 +8103,14 @@ return 1
|
|
|
8033
8103
|
if (leads.length === 0) return (c) => `${c}<55296`;
|
|
8034
8104
|
return (c) => `${c}<55296&&!(${leads.map((r) => r.lo === r.hi ? `${c}===${r.lo}` : `(${c}>=${r.lo}&&${c}<=${r.hi})`).join("||")})`;
|
|
8035
8105
|
}
|
|
8106
|
+
function skipCapturing(l) {
|
|
8107
|
+
if (l.tri < 0 || !swapLegal || triviaLabelled[l.tri] || t.triviaScan[l.tri] == null) return "true";
|
|
8108
|
+
return capturesHere(l);
|
|
8109
|
+
}
|
|
8110
|
+
function capturesHere(l) {
|
|
8111
|
+
const sink = l.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)";
|
|
8112
|
+
return l.cap === CAP_OFF ? "false" : l.cap === CAP_ON ? sink : `(ctx.captureTrivia===true&&${sink})`;
|
|
8113
|
+
}
|
|
8036
8114
|
function skipFor(l) {
|
|
8037
8115
|
if (l.tri < 0) return "_skipTrivia";
|
|
8038
8116
|
const ki = l.tri;
|
|
@@ -8125,9 +8203,12 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
8125
8203
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
8126
8204
|
if (op === OP_RULE || op === OP_GAPGATE) return code[ip + 1];
|
|
8127
8205
|
if (op === OP_STRICT) return code[cfg.tolerant || cfg.probe ? ip + 2 : ip + 1];
|
|
8206
|
+
if (op === OP_CONT && !labels.late.has(ip)) return code[ip + 2];
|
|
8207
|
+
if (op === OP_SEED) return code[ip + 1];
|
|
8128
8208
|
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
8129
8209
|
return void 0;
|
|
8130
8210
|
}
|
|
8211
|
+
let LATE;
|
|
8131
8212
|
function lower(ip, fname) {
|
|
8132
8213
|
const op = code[ip];
|
|
8133
8214
|
const head = `function ${fname}(input,pos,ctx){`;
|
|
@@ -8260,6 +8341,71 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
8260
8341
|
}
|
|
8261
8342
|
case OP_EMPTY:
|
|
8262
8343
|
return `${head}EC.e=pos;return ''}`;
|
|
8344
|
+
case OP_CONT: {
|
|
8345
|
+
const tri = L.tri;
|
|
8346
|
+
const g = continuationGate(code, code[ip + 3]);
|
|
8347
|
+
const missAt = (idx, at2) => {
|
|
8348
|
+
const resolved = t.cc[idx];
|
|
8349
|
+
const ci = classes.push([resolved]) - 1;
|
|
8350
|
+
classPlan.push([idx]);
|
|
8351
|
+
const ref2 = hoist("cg", `CLS[${ci}][0]`);
|
|
8352
|
+
return isAsciiOnlyClass(resolved) ? `${ref2}.ascii[input.charCodeAt(${at2})]!==1` : `!classHas(${ref2},lead(input,${at2}))`;
|
|
8353
|
+
};
|
|
8354
|
+
let scanned = "";
|
|
8355
|
+
if (tri >= 0) {
|
|
8356
|
+
const scan = hoist("cs", `TRIVIASCAN[${tri}]`);
|
|
8357
|
+
const miss = triviaMiss(tri);
|
|
8358
|
+
scanned = miss === void 0 ? `const q0=${scan}(input,c1)
|
|
8359
|
+
` : `const cc=input.charCodeAt(c1)
|
|
8360
|
+
const q0=${miss("cc")}?c1:${scan}(input,c1)
|
|
8361
|
+
`;
|
|
8362
|
+
}
|
|
8363
|
+
const at = tri >= 0 ? "q0" : "c1";
|
|
8364
|
+
let test;
|
|
8365
|
+
if (g.gapRow < 0) test = `if(c0!==undefined&&${missAt(g.cls, at)})return c0
|
|
8366
|
+
`;
|
|
8367
|
+
else {
|
|
8368
|
+
const re = hoist("cr", `K[${code[g.gapRow + 1]}]`);
|
|
8369
|
+
const other = g.other >= 0 ? missAt(g.other, at) : "true";
|
|
8370
|
+
test = `${re}.lastIndex=${at}
|
|
8371
|
+
const gq=${re}.test(input)?${re}.lastIndex:-1
|
|
8372
|
+
if(c0!==undefined&&(gq<0||${missAt(g.follow, "gq")})&&${other})return c0
|
|
8373
|
+
`;
|
|
8374
|
+
}
|
|
8375
|
+
const seq = code[code[ip + 2] + 2];
|
|
8376
|
+
const seqLabel = labels.at(seq);
|
|
8377
|
+
const tail = link(code[ip + 3]);
|
|
8378
|
+
const recorded = tri === TRI_NONE ? "" : `const tl0=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
8379
|
+
const lg0=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
8380
|
+
const rt0=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
8381
|
+
const s0=${skipFor(seqLabel)}(input,c1,ctx)
|
|
8382
|
+
const tl1=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
8383
|
+
const lg1=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
8384
|
+
const rt1=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
8385
|
+
v=${tail}(input,s0,ctx)
|
|
8386
|
+
if(v!==FAIL&&EC.e<=s0){rollbackScannedTriviaAt(ctx,tl0,tl1,lg0,lg1,rt0,rt1);EC.e=c1}`;
|
|
8387
|
+
const quiet = `v=${tail}(input,${at},ctx)
|
|
8388
|
+
if(v!==FAIL&&EC.e<=${at})EC.e=c1`;
|
|
8389
|
+
const capture = capturesHere(seqLabel);
|
|
8390
|
+
const body = `let v
|
|
8391
|
+
${tri === TRI_NONE ? `v=${tail}(input,c1,ctx)` : `if(q0===c1)v=${tail}(input,c1,ctx)
|
|
8392
|
+
else ${capture === "true" ? `{
|
|
8393
|
+
${recorded}
|
|
8394
|
+
}` : `if(ctx._triviaLog===undefined&&ctx._rootTriviaLog===undefined${capture === "false" ? "" : `&&!${capture}`}){
|
|
8395
|
+
${quiet}
|
|
8396
|
+
}else{
|
|
8397
|
+
${recorded}
|
|
8398
|
+
}`}`}`;
|
|
8399
|
+
const wrapperIp = code[ip + 2];
|
|
8400
|
+
LATE = {
|
|
8401
|
+
prefix: `const c0=${link(code[ip + 1])}(input,pos,ctx)
|
|
8402
|
+
if(c0===FAIL)return FAIL
|
|
8403
|
+
const c1=EC.e
|
|
8404
|
+
${scanned}${test}`,
|
|
8405
|
+
body
|
|
8406
|
+
};
|
|
8407
|
+
return lower(wrapperIp, fname);
|
|
8408
|
+
}
|
|
8263
8409
|
case OP_GATE: {
|
|
8264
8410
|
const child = link(code[ip + 2]);
|
|
8265
8411
|
const xf = fxRef(code[ip + 3]);
|
|
@@ -9222,7 +9368,9 @@ return out
|
|
|
9222
9368
|
case OP_NODE:
|
|
9223
9369
|
case OP_NODE_TRACK: {
|
|
9224
9370
|
const flags = code[ip + 3];
|
|
9225
|
-
const
|
|
9371
|
+
const late = LATE;
|
|
9372
|
+
LATE = void 0;
|
|
9373
|
+
const scalarChild = late === void 0 ? scalarTerminalNodeChild(code, ip) : -1;
|
|
9226
9374
|
if (scalarChild >= 0 && scalarSpecs.has(code[scalarChild + 1])) {
|
|
9227
9375
|
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
9228
9376
|
const spec = code[scalarChild] === OP_RX ? null : k[code[scalarChild + 1]];
|
|
@@ -9242,7 +9390,9 @@ EC.e=end
|
|
|
9242
9390
|
return nd
|
|
9243
9391
|
}`;
|
|
9244
9392
|
}
|
|
9245
|
-
const child = link(code[ip + 2]);
|
|
9393
|
+
const child = late === void 0 ? link(code[ip + 2]) : "";
|
|
9394
|
+
const runBody = late === void 0 ? `const v=${child}(input,pos,ctx)` : late.body;
|
|
9395
|
+
const takeBack = late === void 0 ? "" : "let c0Raw\nif(sBuf===undefined&&sRaw===undefined&&sCh!==undefined)sCh.pop()\nelse if(sBuf!==undefined||sCh!==undefined)c0Raw=popCstChild(ctx)\n";
|
|
9246
9396
|
const proj = code[ip + 4];
|
|
9247
9397
|
const buildIdx = code[ip + 1];
|
|
9248
9398
|
const type = k[code[ip + 5]];
|
|
@@ -9257,14 +9407,14 @@ return nd
|
|
|
9257
9407
|
const trailingTrivia = (flags & 128) !== 0;
|
|
9258
9408
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
9259
9409
|
const leanFlags = flags & ~128;
|
|
9260
|
-
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
9410
|
+
if (late === void 0 && build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
9261
9411
|
return `${head}
|
|
9262
9412
|
const v=${child}(input,pos,ctx)
|
|
9263
9413
|
if(v!==undefined)return v
|
|
9264
9414
|
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
9265
9415
|
}`;
|
|
9266
9416
|
}
|
|
9267
|
-
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
9417
|
+
const gated = late === void 0 && build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
9268
9418
|
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t.trivia);
|
|
9269
9419
|
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
9270
9420
|
if(!(${[
|
|
@@ -9311,9 +9461,9 @@ sCh.push(nd)
|
|
|
9311
9461
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
9312
9462
|
}`;
|
|
9313
9463
|
return `${head}
|
|
9314
|
-
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
9464
|
+
${late?.prefix ?? ""}${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
9315
9465
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
9316
|
-
const flat
|
|
9466
|
+
${takeBack}const flat=${late === void 0 ? "[]" : "[c0]"}
|
|
9317
9467
|
ctx._cstBuf=undefined
|
|
9318
9468
|
ctx._cstChildren=flat
|
|
9319
9469
|
ctx._cstLeaves=flat
|
|
@@ -9321,7 +9471,7 @@ ctx._cstRawChildren=undefined
|
|
|
9321
9471
|
ctx._cstTriviaLog=undefined
|
|
9322
9472
|
ctx.captureTrivia=false
|
|
9323
9473
|
ctx._fields=${fields ? "[]" : "undefined"}
|
|
9324
|
-
|
|
9474
|
+
${runBody}
|
|
9325
9475
|
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
9326
9476
|
` : ""}const captured=_capturedFlatChildren(flat)
|
|
9327
9477
|
${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
|
|
@@ -9385,16 +9535,17 @@ const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
|
9385
9535
|
const hostKids=kids
|
|
9386
9536
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
9387
9537
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
9538
|
+
const seedCapture = late === void 0 ? "" : omitsRaw ? "buf.single=c0\nbuf.rawLen=1\n" : "buf.single=c0\nbuf.rawSingle=c0Raw!==undefined?c0Raw:rawEntry(c0,input,pos,c1)\n";
|
|
9388
9539
|
return `${head}
|
|
9389
|
-
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
9540
|
+
${late?.prefix ?? ""}${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
9390
9541
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
9391
|
-
${openCapture}
|
|
9392
|
-
ctx.captureTrivia=${captureWide}
|
|
9542
|
+
${takeBack}${openCapture}
|
|
9543
|
+
${seedCapture}ctx.captureTrivia=${captureWide}
|
|
9393
9544
|
const savedFields=ctx._fields
|
|
9394
9545
|
ctx._fields=${wantFields ? "[]" : "undefined"}
|
|
9395
9546
|
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
9396
9547
|
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
9397
|
-
` : ""}
|
|
9548
|
+
` : ""}${runBody}
|
|
9398
9549
|
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
9399
9550
|
` : ""}const fieldMap=${wantFields ? "buildFieldMap(ctx._fields)" : "undefined"}
|
|
9400
9551
|
ctx._fields=savedFields
|
|
@@ -9612,6 +9763,13 @@ function failCleanAnalysis(code) {
|
|
|
9612
9763
|
case OP_ROUTED:
|
|
9613
9764
|
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
9614
9765
|
break;
|
|
9766
|
+
case OP_SEED:
|
|
9767
|
+
out = clean(code[ip + 1]);
|
|
9768
|
+
break;
|
|
9769
|
+
// The corner may fail; the wrapper fails only through a tail that can.
|
|
9770
|
+
case OP_CONT:
|
|
9771
|
+
out = clean(code[ip + 1]) && neverFails(code[ip + 3]);
|
|
9772
|
+
break;
|
|
9615
9773
|
// An arm's failure and the fallback's are committed; only the selector's is
|
|
9616
9774
|
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
9617
9775
|
case OP_DISPATCH:
|
|
@@ -9837,7 +9995,8 @@ function assemble(t, prog, cfg) {
|
|
|
9837
9995
|
const closureLabels = computeSiteLabels(
|
|
9838
9996
|
code,
|
|
9839
9997
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
9840
|
-
hostCst
|
|
9998
|
+
hostCst,
|
|
9999
|
+
cfg.tolerant || cfg.probe ? void 0 : (ip, tri) => canDecide(code, ip, tri, t.triviaScan)
|
|
9841
10000
|
);
|
|
9842
10001
|
let SCAN = null;
|
|
9843
10002
|
let HYBRID;
|
|
@@ -10234,6 +10393,32 @@ function assemble(t, prog, cfg) {
|
|
|
10234
10393
|
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
10235
10394
|
return cur;
|
|
10236
10395
|
}
|
|
10396
|
+
function startsTail(cls, input, at) {
|
|
10397
|
+
const c = input.charCodeAt(at);
|
|
10398
|
+
return c < 128 ? cls.ascii[c] === 1 : classHas2(cls, lead(input, at));
|
|
10399
|
+
}
|
|
10400
|
+
function lateTail(tail, input, end, at, ctx, frame) {
|
|
10401
|
+
if (at === end) return tail(input, end, ctx);
|
|
10402
|
+
if (ctx._triviaLog === void 0 && ctx._rootTriviaLog === void 0 && (frame.cap === CAP_OFF || !((frame.cap === CAP_ON || ctx.captureTrivia === true) && (frame.buf || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0)))) {
|
|
10403
|
+
const v2 = tail(input, at, ctx);
|
|
10404
|
+
if (v2 !== FAIL && EC.e <= at) EC.e = end;
|
|
10405
|
+
return v2;
|
|
10406
|
+
}
|
|
10407
|
+
const need = rollbackNeeded(ctx);
|
|
10408
|
+
const mTl = need ? cstTlLen(ctx) : 0;
|
|
10409
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10410
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10411
|
+
const scanEnd = skipTrivia(input, end, ctx);
|
|
10412
|
+
const scanTl = need ? cstTlLen(ctx) : 0;
|
|
10413
|
+
const scanLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10414
|
+
const scanRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10415
|
+
const v = tail(input, scanEnd, ctx);
|
|
10416
|
+
if (v !== FAIL && EC.e <= scanEnd) {
|
|
10417
|
+
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
10418
|
+
EC.e = end;
|
|
10419
|
+
}
|
|
10420
|
+
return v;
|
|
10421
|
+
}
|
|
10237
10422
|
function nextTermBuffered(child, input, cur, ctx) {
|
|
10238
10423
|
const t2 = ctx.trivia;
|
|
10239
10424
|
if (t2 === void 0 || cannotStartTrivia(input, cur, t2)) {
|
|
@@ -10849,6 +11034,79 @@ function assemble(t, prog, cfg) {
|
|
|
10849
11034
|
EC.e = pos;
|
|
10850
11035
|
return "";
|
|
10851
11036
|
};
|
|
11037
|
+
case OP_SEED:
|
|
11038
|
+
return link(code[ip + 1]);
|
|
11039
|
+
case OP_CONT: {
|
|
11040
|
+
const wrapper = code[ip + 2];
|
|
11041
|
+
if (!closureLabels.late.has(ip)) return lower(wrapper);
|
|
11042
|
+
const corner = link(code[ip + 1]);
|
|
11043
|
+
const tail = link(code[ip + 3]);
|
|
11044
|
+
const g = continuationGate(code, code[ip + 3]);
|
|
11045
|
+
const tri = closureLabels.at(ip).tri;
|
|
11046
|
+
const scan = tri === TRI_NONE ? void 0 : t.triviaScan[tri];
|
|
11047
|
+
const leads = tri === TRI_NONE ? null : LEAD_TABLES[tri];
|
|
11048
|
+
const cls = cc[g.cls];
|
|
11049
|
+
const gapRe = g.gapRow < 0 ? void 0 : k[code[g.gapRow + 1]];
|
|
11050
|
+
const follow = g.follow < 0 ? void 0 : cc[g.follow];
|
|
11051
|
+
const other = g.other < 0 ? void 0 : cc[g.other];
|
|
11052
|
+
const mayStartPastGap = (input, at) => {
|
|
11053
|
+
gapRe.lastIndex = at;
|
|
11054
|
+
const q2 = gapRe.test(input) ? gapRe.lastIndex : -1;
|
|
11055
|
+
return q2 >= 0 && classHas2(follow, lead(input, q2)) || other !== void 0 && classHas2(other, lead(input, at));
|
|
11056
|
+
};
|
|
11057
|
+
const frame = closureLabels.at(code[wrapper + 2]);
|
|
11058
|
+
const flags = code[wrapper + 3];
|
|
11059
|
+
const buildIdx = code[wrapper + 1];
|
|
11060
|
+
let held;
|
|
11061
|
+
let heldRaw;
|
|
11062
|
+
let heldEnd = 0;
|
|
11063
|
+
let heldAt = 0;
|
|
11064
|
+
const omitsRaw = !hostCst && buildIdx >= 0 && code[wrapper + 4] < 0 && (flags & 2) !== 0;
|
|
11065
|
+
const body = omitsRaw ? (input, _pos, ctx) => {
|
|
11066
|
+
const b = ctx._cstBuf;
|
|
11067
|
+
if (b !== void 0) {
|
|
11068
|
+
b.single = held;
|
|
11069
|
+
b.rawLen = 1;
|
|
11070
|
+
} else ctx._cstChildren.push(held);
|
|
11071
|
+
held = void 0;
|
|
11072
|
+
heldRaw = void 0;
|
|
11073
|
+
return lateTail(tail, input, heldEnd, heldAt, ctx, frame);
|
|
11074
|
+
} : (input, pos, ctx) => {
|
|
11075
|
+
const b = ctx._cstBuf;
|
|
11076
|
+
if (b !== void 0) {
|
|
11077
|
+
b.single = held;
|
|
11078
|
+
b.rawSingle = heldRaw ?? rawEntry(held, input, pos, heldEnd);
|
|
11079
|
+
} else ctx._cstChildren.push(held);
|
|
11080
|
+
held = void 0;
|
|
11081
|
+
heldRaw = void 0;
|
|
11082
|
+
return lateTail(tail, input, heldEnd, heldAt, ctx, frame);
|
|
11083
|
+
};
|
|
11084
|
+
let open;
|
|
11085
|
+
if (!hostCst && !cfg.trackLines && code[wrapper] === OP_NODE && code[wrapper + 4] < 0 && (flags === 32 || flags === 34)) {
|
|
11086
|
+
const build = fns[buildIdx];
|
|
11087
|
+
open = flags === 34 ? childrenOnlyCollapseBuildNode(body, build) : collapseBuildNode(body, build);
|
|
11088
|
+
} else {
|
|
11089
|
+
NODE_BODY = body;
|
|
11090
|
+
open = lower(wrapper);
|
|
11091
|
+
}
|
|
11092
|
+
return (input, pos, ctx) => {
|
|
11093
|
+
const v = corner(input, pos, ctx);
|
|
11094
|
+
if (v === FAIL) return FAIL;
|
|
11095
|
+
const end = EC.e;
|
|
11096
|
+
let at = end;
|
|
11097
|
+
if (scan !== void 0) {
|
|
11098
|
+
const c = input.charCodeAt(end);
|
|
11099
|
+
if (leads === null || !(c < 128) || leads[c] !== 0) at = scan(input, end);
|
|
11100
|
+
}
|
|
11101
|
+
if (v !== void 0 && !(gapRe === void 0 ? startsTail(cls, input, at) : mayStartPastGap(input, at))) return v;
|
|
11102
|
+
if (ctx._cstBuf === void 0 && ctx._cstRawChildren === void 0 && ctx._cstChildren !== void 0) ctx._cstChildren.pop();
|
|
11103
|
+
else if (ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0) heldRaw = popCstChild(ctx);
|
|
11104
|
+
held = v;
|
|
11105
|
+
heldEnd = end;
|
|
11106
|
+
heldAt = at;
|
|
11107
|
+
return open(input, pos, ctx);
|
|
11108
|
+
};
|
|
11109
|
+
}
|
|
10852
11110
|
/* ── transparent / structural ────────────────────────────────────────── */
|
|
10853
11111
|
case OP_GUARD: {
|
|
10854
11112
|
const pred = fns[code[ip + 1]];
|
|
@@ -13065,6 +13323,7 @@ function assemble(t, prog, cfg) {
|
|
|
13065
13323
|
triviaFieldCapture,
|
|
13066
13324
|
skipDeferredTrivia,
|
|
13067
13325
|
collapseEmpty,
|
|
13326
|
+
popCstChild,
|
|
13068
13327
|
PlainSpan9,
|
|
13069
13328
|
PlainLeaf8,
|
|
13070
13329
|
PlainNode2,
|
|
@@ -13154,6 +13413,7 @@ function assemble(t, prog, cfg) {
|
|
|
13154
13413
|
triviaFieldCapture,
|
|
13155
13414
|
skipDeferredTrivia,
|
|
13156
13415
|
collapseEmpty,
|
|
13416
|
+
popCstChild,
|
|
13157
13417
|
PlainSpan9,
|
|
13158
13418
|
PlainLeaf8,
|
|
13159
13419
|
PlainNode2,
|
|
@@ -14634,6 +14894,34 @@ function isGap(p) {
|
|
|
14634
14894
|
return true;
|
|
14635
14895
|
});
|
|
14636
14896
|
}
|
|
14897
|
+
function publishesOneNode(p, rr, seen = /* @__PURE__ */ new Set()) {
|
|
14898
|
+
if (seen.has(p)) return true;
|
|
14899
|
+
seen.add(p);
|
|
14900
|
+
const d = p._def;
|
|
14901
|
+
switch (d.tag) {
|
|
14902
|
+
case "node":
|
|
14903
|
+
return true;
|
|
14904
|
+
case "lazy": {
|
|
14905
|
+
let target = winnerForRef(p, rr);
|
|
14906
|
+
if (target === void 0) {
|
|
14907
|
+
try {
|
|
14908
|
+
target = d.thunk();
|
|
14909
|
+
} catch {
|
|
14910
|
+
return false;
|
|
14911
|
+
}
|
|
14912
|
+
}
|
|
14913
|
+
return publishesOneNode(target, rr, seen);
|
|
14914
|
+
}
|
|
14915
|
+
case "choice":
|
|
14916
|
+
return d.parsers.every((a) => publishesOneNode(a, rr, seen));
|
|
14917
|
+
case "grammar":
|
|
14918
|
+
case "withCtx":
|
|
14919
|
+
case "label":
|
|
14920
|
+
return publishesOneNode(d.parser, rr, seen);
|
|
14921
|
+
default:
|
|
14922
|
+
return false;
|
|
14923
|
+
}
|
|
14924
|
+
}
|
|
14637
14925
|
var Encoder = class {
|
|
14638
14926
|
code = [];
|
|
14639
14927
|
k = [];
|
|
@@ -15987,7 +16275,8 @@ var Encoder = class {
|
|
|
15987
16275
|
}
|
|
15988
16276
|
case "node": {
|
|
15989
16277
|
if (d.type === void 0) missingInferredType();
|
|
15990
|
-
const
|
|
16278
|
+
const late = this.opensLate(d);
|
|
16279
|
+
const child = late ? this.lateBody(d.parser._def) : this.node(d.parser).ip;
|
|
15991
16280
|
const cstOut = this.settings.hostMode === "cst";
|
|
15992
16281
|
const noBuildCaptures = d.project === void 0;
|
|
15993
16282
|
const derivedTrivia = d.build !== void 0 ? buildReadsTrivia(d) : noBuildCaptures;
|
|
@@ -16008,13 +16297,19 @@ var Encoder = class {
|
|
|
16008
16297
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
16009
16298
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
16010
16299
|
);
|
|
16011
|
-
|
|
16300
|
+
let run = body;
|
|
16301
|
+
if (late) {
|
|
16302
|
+
const corner = this.code[this.code[child + 2] + 1];
|
|
16303
|
+
if (continuationGate(this.code, this.code[child + 3]) === void 0) this.code[child + 2] = corner;
|
|
16304
|
+
else run = this.emit(OP_CONT, corner, body, this.code[child + 3]);
|
|
16305
|
+
}
|
|
16306
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return run;
|
|
16012
16307
|
const fs = this.gateFirstSet(d.parser, d.guarded === true, false);
|
|
16013
|
-
if (fs.kind === "any") return
|
|
16308
|
+
if (fs.kind === "any") return run;
|
|
16014
16309
|
const cls = this.charClass(fs);
|
|
16015
|
-
if (cls < 0) return
|
|
16310
|
+
if (cls < 0) return run;
|
|
16016
16311
|
const e = deriveExpected(d.parser);
|
|
16017
|
-
return this.emit(OP_GATE, cls,
|
|
16312
|
+
return this.emit(OP_GATE, cls, run, this.expected(e.length > 0 ? e : [d.parser._tag]));
|
|
16018
16313
|
}
|
|
16019
16314
|
case "token": {
|
|
16020
16315
|
const saved = this.activeTrivia;
|
|
@@ -16196,6 +16491,29 @@ var Encoder = class {
|
|
|
16196
16491
|
throw new UnsupportedConstruct(d.tag);
|
|
16197
16492
|
}
|
|
16198
16493
|
}
|
|
16494
|
+
/**
|
|
16495
|
+
* `node(sequence(corner, tail), build, { collapse: true })` with a tail that can take
|
|
16496
|
+
* nothing and a corner that is one node: the frame can open after the corner, only if
|
|
16497
|
+
* the tail can start. Any other node keeps its frame from the start, and so does one
|
|
16498
|
+
* with no reducer, whose host can scope the corner's trivia to its type.
|
|
16499
|
+
*/
|
|
16500
|
+
opensLate(d) {
|
|
16501
|
+
if (this.plan !== void 0 || d.collapse !== true || d.build === void 0 || d.trailingTrivia === true) return false;
|
|
16502
|
+
const seq = d.parser._def;
|
|
16503
|
+
return seq.tag === "sequence" && seq.parsers.length === 2 && matchesEmpty(seq.parsers[1], /* @__PURE__ */ new Set(), this.refResolver()) && publishesOneNode(seq.parsers[0], this.refResolver());
|
|
16504
|
+
}
|
|
16505
|
+
/** The body of a late frame: the sequence as written, its corner behind `OP_SEED`. */
|
|
16506
|
+
lateBody(seq) {
|
|
16507
|
+
const seed = this.emit(OP_SEED, this.node(seq.parsers[0]).ip);
|
|
16508
|
+
const tailIp = this.node(seq.parsers[1]).ip;
|
|
16509
|
+
const head = this.emitHead(seq.valueUnused ? OP_SEQV : OP_SEQ, 5);
|
|
16510
|
+
this.code[head + 1] = 2;
|
|
16511
|
+
this.code[head + 2] = seed;
|
|
16512
|
+
this.code[head + 3] = tailIp;
|
|
16513
|
+
this.code[head + 4] = this.followClass(seq.parsers, 0);
|
|
16514
|
+
this.code[head + 5] = this.followClass(seq.parsers, 1);
|
|
16515
|
+
return head;
|
|
16516
|
+
}
|
|
16199
16517
|
/**
|
|
16200
16518
|
* Peephole: an `OP_RULE` row is pure indirection — a switch dispatch and a
|
|
16201
16519
|
* call frame to do nothing but jump. Rewrite every child slot that points at
|
|
@@ -16261,6 +16579,10 @@ var Encoder = class {
|
|
|
16261
16579
|
return this.code[ip + 4] >= 0 ? [ip + 1, ip + 4] : [ip + 1];
|
|
16262
16580
|
case OP_STRICT:
|
|
16263
16581
|
return [ip + 1, ip + 2];
|
|
16582
|
+
case OP_CONT:
|
|
16583
|
+
return [ip + 1, ip + 2, ip + 3];
|
|
16584
|
+
case OP_SEED:
|
|
16585
|
+
return [ip + 1];
|
|
16264
16586
|
default:
|
|
16265
16587
|
return [];
|
|
16266
16588
|
}
|
|
@@ -18157,21 +18479,70 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
18157
18479
|
var LOOP = 8;
|
|
18158
18480
|
var ROUNDS = 60;
|
|
18159
18481
|
var CAP = 1e12;
|
|
18482
|
+
var CROSSING_WEIGHT = 4;
|
|
18483
|
+
var TAKEN = -1;
|
|
18160
18484
|
function selectHotSites(code, entries, siteBytes, budget, profile) {
|
|
18161
18485
|
const selected = /* @__PURE__ */ new Set();
|
|
18162
18486
|
if (budget <= 0) return selected;
|
|
18163
|
-
const weight = profile === void 0 ? staticWeights(code, entries) : void 0;
|
|
18164
|
-
const w = (ip) => (weight !== void 0 ? weight.get(ip) : profile[ip]) ?? 0;
|
|
18165
|
-
const ranked = [...siteBytes.keys()].sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
|
|
18166
18487
|
let spent = 0;
|
|
18167
|
-
for (const ip of
|
|
18168
|
-
if (w(ip) === 0) break;
|
|
18488
|
+
for (const ip of profile === void 0 ? staticRanking(code, entries, siteBytes) : connectedRanking(code, siteBytes, profile)) {
|
|
18169
18489
|
spent += siteBytes.get(ip);
|
|
18170
18490
|
if (spent > budget) break;
|
|
18171
18491
|
selected.add(ip);
|
|
18172
18492
|
}
|
|
18173
18493
|
return selected;
|
|
18174
18494
|
}
|
|
18495
|
+
function edgesAsLowered(code, siteBytes, ip, out) {
|
|
18496
|
+
out.length = 0;
|
|
18497
|
+
if (code[ip] !== OP_CONT) childSlots(code, ip, out);
|
|
18498
|
+
else if (siteBytes.has(ip)) out.push(code[ip + 1], code[ip + 3]);
|
|
18499
|
+
else out.push(code[ip + 2]);
|
|
18500
|
+
for (let i = 0; i < out.length; i++) {
|
|
18501
|
+
let row = out[i];
|
|
18502
|
+
for (; ; ) {
|
|
18503
|
+
const op = code[row];
|
|
18504
|
+
if (op === OP_GAPGATE || op === OP_SEED) row = code[row + 1];
|
|
18505
|
+
else if (op === OP_CONT && !siteBytes.has(row)) row = code[row + 2];
|
|
18506
|
+
else break;
|
|
18507
|
+
}
|
|
18508
|
+
out[i] = row;
|
|
18509
|
+
}
|
|
18510
|
+
}
|
|
18511
|
+
function staticRanking(code, entries, siteBytes) {
|
|
18512
|
+
const weight = staticWeights(code, entries, siteBytes);
|
|
18513
|
+
const w = (ip) => weight.get(ip) ?? 0;
|
|
18514
|
+
return [...siteBytes.keys()].filter((ip) => w(ip) > 0).sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
|
|
18515
|
+
}
|
|
18516
|
+
function* connectedRanking(code, siteBytes, calls) {
|
|
18517
|
+
const ran = [...siteBytes.keys()].filter((ip) => calls[ip] > 0).sort((a, b) => a - b);
|
|
18518
|
+
const slot = new Map(ran.map((ip, i) => [ip, i]));
|
|
18519
|
+
const bytes = ran.map((ip) => siteBytes.get(ip));
|
|
18520
|
+
const worth = ran.map((ip) => calls[ip]);
|
|
18521
|
+
const score = worth.map((value, i) => value / bytes[i]);
|
|
18522
|
+
const crossings = ran.map(() => []);
|
|
18523
|
+
const kids = [];
|
|
18524
|
+
ran.forEach((ip, from) => {
|
|
18525
|
+
edgesAsLowered(code, siteBytes, ip, kids);
|
|
18526
|
+
for (const callee of kids) {
|
|
18527
|
+
const to = slot.get(callee);
|
|
18528
|
+
if (to === void 0) continue;
|
|
18529
|
+
const gain = CROSSING_WEIGHT * calls[callee];
|
|
18530
|
+
crossings[from].push([to, gain]);
|
|
18531
|
+
crossings[to].push([from, gain]);
|
|
18532
|
+
}
|
|
18533
|
+
});
|
|
18534
|
+
for (let left = ran.length; left > 0; left--) {
|
|
18535
|
+
let best = 0;
|
|
18536
|
+
for (let i = 1; i < score.length; i++) if (score[i] > score[best]) best = i;
|
|
18537
|
+
score[best] = TAKEN;
|
|
18538
|
+
yield ran[best];
|
|
18539
|
+
for (const [neighbour, gain] of crossings[best]) {
|
|
18540
|
+
if (score[neighbour] === TAKEN) continue;
|
|
18541
|
+
worth[neighbour] = worth[neighbour] + gain;
|
|
18542
|
+
score[neighbour] = worth[neighbour] / bytes[neighbour];
|
|
18543
|
+
}
|
|
18544
|
+
}
|
|
18545
|
+
}
|
|
18175
18546
|
function fitHotSites(code, entries, siteBytes, fixed, ceiling, sourceBytes, profile) {
|
|
18176
18547
|
const ranked = [...selectHotSites(code, entries, siteBytes, ceiling - fixed, profile)];
|
|
18177
18548
|
for (; ranked.length > 0; ranked.pop()) {
|
|
@@ -18181,21 +18552,17 @@ function fitHotSites(code, entries, siteBytes, fixed, ceiling, sourceBytes, prof
|
|
|
18181
18552
|
}
|
|
18182
18553
|
return void 0;
|
|
18183
18554
|
}
|
|
18184
|
-
function staticWeights(code, entries) {
|
|
18555
|
+
function staticWeights(code, entries, siteBytes) {
|
|
18185
18556
|
let weight = /* @__PURE__ */ new Map();
|
|
18186
18557
|
const kids = [];
|
|
18187
18558
|
for (let round = 0; round < ROUNDS; round++) {
|
|
18188
18559
|
const next = /* @__PURE__ */ new Map();
|
|
18189
18560
|
for (const ip of entries) next.set(ip, 1);
|
|
18190
18561
|
for (const [ip, w] of weight) {
|
|
18191
|
-
|
|
18192
|
-
childSlots(code, ip, kids);
|
|
18562
|
+
edgesAsLowered(code, siteBytes, ip, kids);
|
|
18193
18563
|
const op = code[ip];
|
|
18194
18564
|
const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
|
|
18195
|
-
for (const
|
|
18196
|
-
const kid = code[k] === OP_GAPGATE ? code[k + 1] : k;
|
|
18197
|
-
next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
18198
|
-
}
|
|
18565
|
+
for (const kid of kids) next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
18199
18566
|
}
|
|
18200
18567
|
weight = next;
|
|
18201
18568
|
}
|