@nudojs/core 1.0.1 → 2.0.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.
- package/dist/{chunk-P3G2TODS.js → chunk-VVSVQKWF.js} +3309 -438
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +55 -1
- package/dist/{index-FITqyJ8v.d.ts → index-DxjxtxOJ.d.ts} +112 -18
- package/dist/index.d.ts +239 -14
- package/dist/index.js +785 -251
- package/package.json +1 -1
|
@@ -9,6 +9,8 @@ var runtime_exports = {};
|
|
|
9
9
|
__export(runtime_exports, {
|
|
10
10
|
$add: () => $add,
|
|
11
11
|
$arr: () => $arr,
|
|
12
|
+
$arrMutContainer: () => $arrMutContainer,
|
|
13
|
+
$arrRest: () => $arrRest,
|
|
12
14
|
$async: () => $async,
|
|
13
15
|
$asyncReturn: () => $asyncReturn,
|
|
14
16
|
$await: () => $await,
|
|
@@ -17,6 +19,7 @@ __export(runtime_exports, {
|
|
|
17
19
|
$div: () => $div,
|
|
18
20
|
$elems: () => $elems,
|
|
19
21
|
$eq: () => $eq,
|
|
22
|
+
$eqLoose: () => $eqLoose,
|
|
20
23
|
$fnVal: () => $fnVal,
|
|
21
24
|
$for: () => $for,
|
|
22
25
|
$forIter: () => $forIter,
|
|
@@ -28,38 +31,59 @@ __export(runtime_exports, {
|
|
|
28
31
|
$gt: () => $gt,
|
|
29
32
|
$idx: () => $idx,
|
|
30
33
|
$idxSet: () => $idxSet,
|
|
34
|
+
$isForkExit: () => $isForkExit,
|
|
31
35
|
$join: () => $join,
|
|
32
36
|
$le: () => $le,
|
|
33
37
|
$len: () => $len,
|
|
34
38
|
$lit: () => $lit,
|
|
39
|
+
$loopReturn: () => $loopReturn,
|
|
35
40
|
$lt: () => $lt,
|
|
36
41
|
$mod: () => $mod,
|
|
37
42
|
$mul: () => $mul,
|
|
38
43
|
$ne: () => $ne,
|
|
44
|
+
$neLoose: () => $neLoose,
|
|
39
45
|
$neg: () => $neg,
|
|
40
46
|
$not: () => $not,
|
|
47
|
+
$nullishTest: () => $nullishTest,
|
|
41
48
|
$obj: () => $obj,
|
|
49
|
+
$objRest: () => $objRest,
|
|
50
|
+
$pushLoopExit: () => $pushLoopExit,
|
|
42
51
|
$regex: () => $regex,
|
|
52
|
+
$rethrowIfNudoReturn: () => $rethrowIfNudoReturn,
|
|
43
53
|
$set: () => $set,
|
|
44
54
|
$spread: () => $spread,
|
|
45
55
|
$sub: () => $sub,
|
|
46
56
|
$switch: () => $switch,
|
|
47
57
|
$throw: () => $throw,
|
|
58
|
+
$tryCurrentMark: () => $tryCurrentMark,
|
|
59
|
+
$tryMark: () => $tryMark,
|
|
60
|
+
$tryPopMark: () => $tryPopMark,
|
|
61
|
+
$tryTakeSince: () => $tryTakeSince,
|
|
48
62
|
$typeof: () => $typeof,
|
|
49
63
|
$while: () => $while,
|
|
50
64
|
$whileSeq: () => $whileSeq,
|
|
51
65
|
$yield: () => $yield,
|
|
52
66
|
DEFAULT_MAX_LOOP_ITERS: () => DEFAULT_MAX_LOOP_ITERS,
|
|
67
|
+
NudoReturn: () => NudoReturn,
|
|
53
68
|
NudoThrow: () => NudoThrow,
|
|
54
69
|
asAbsVal: () => asAbsVal,
|
|
70
|
+
callAtFunctionBoundary: () => callAtFunctionBoundary,
|
|
55
71
|
currentExecPhi: () => currentExecPhi,
|
|
72
|
+
isArrMutator: () => isArrMutator,
|
|
56
73
|
isDefinitelyFalse: () => isDefinitelyFalse,
|
|
57
74
|
isDefinitelyTrue: () => isDefinitelyTrue,
|
|
75
|
+
isNudoReturn: () => isNudoReturn,
|
|
58
76
|
isNudoThrow: () => isNudoThrow,
|
|
59
77
|
litTruth: () => litTruth,
|
|
60
78
|
namespaceNameOf: () => namespaceNameOf,
|
|
79
|
+
pushLoopExit: () => pushLoopExit,
|
|
80
|
+
pushThrowExit: () => pushThrowExit,
|
|
81
|
+
runWithLoopExits: () => runWithLoopExits,
|
|
82
|
+
takeLoopExits: () => takeLoopExits,
|
|
83
|
+
takeThrowExits: () => takeThrowExits,
|
|
61
84
|
withExecPhi: () => withExecPhi
|
|
62
85
|
});
|
|
86
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
63
87
|
|
|
64
88
|
// src/algebra/term.ts
|
|
65
89
|
var lit = (value) => ({
|
|
@@ -170,11 +194,16 @@ var ptypeof = (t, type) => ({
|
|
|
170
194
|
});
|
|
171
195
|
function and(...preds) {
|
|
172
196
|
const flat = [];
|
|
197
|
+
const pushUnique = (p) => {
|
|
198
|
+
if (flat.some((q) => predEquals(q, p))) return;
|
|
199
|
+
flat.push(p);
|
|
200
|
+
};
|
|
173
201
|
for (const p of preds) {
|
|
174
202
|
if (p.op === "true") continue;
|
|
175
203
|
if (p.op === "false") return pFalse;
|
|
176
|
-
if (p.op === "and")
|
|
177
|
-
|
|
204
|
+
if (p.op === "and") {
|
|
205
|
+
for (const q of p.args) pushUnique(q);
|
|
206
|
+
} else pushUnique(p);
|
|
178
207
|
}
|
|
179
208
|
if (flat.length === 0) return pTrue;
|
|
180
209
|
if (flat.length === 1) return flat[0];
|
|
@@ -182,11 +211,16 @@ function and(...preds) {
|
|
|
182
211
|
}
|
|
183
212
|
function or(...preds) {
|
|
184
213
|
const flat = [];
|
|
214
|
+
const pushUnique = (p) => {
|
|
215
|
+
if (flat.some((q) => predEquals(q, p))) return;
|
|
216
|
+
flat.push(p);
|
|
217
|
+
};
|
|
185
218
|
for (const p of preds) {
|
|
186
219
|
if (p.op === "false") continue;
|
|
187
220
|
if (p.op === "true") return pTrue;
|
|
188
|
-
if (p.op === "or")
|
|
189
|
-
|
|
221
|
+
if (p.op === "or") {
|
|
222
|
+
for (const q of p.args) pushUnique(q);
|
|
223
|
+
} else pushUnique(p);
|
|
190
224
|
}
|
|
191
225
|
if (flat.length === 0) return pFalse;
|
|
192
226
|
if (flat.length === 1) return flat[0];
|
|
@@ -380,6 +414,25 @@ function extractBounds(phi2) {
|
|
|
380
414
|
return { lo, hi };
|
|
381
415
|
}
|
|
382
416
|
function impliesViaBounds(pred, bounds) {
|
|
417
|
+
if (pred.op === "eq") {
|
|
418
|
+
const left2 = pred.a;
|
|
419
|
+
const right2 = pred.b;
|
|
420
|
+
if (right2.op !== "lit" || typeof right2.value !== "number") return void 0;
|
|
421
|
+
const n2 = right2.value;
|
|
422
|
+
if (left2.op === "var") {
|
|
423
|
+
return eqFromBounds(left2.id, n2, bounds);
|
|
424
|
+
}
|
|
425
|
+
if (left2.op === "app" && left2.fn === "+" && left2.args.length === 2) {
|
|
426
|
+
const [a, b] = left2.args;
|
|
427
|
+
if (a.op === "var" && b.op === "lit" && typeof b.value === "number") {
|
|
428
|
+
return eqFromBounds(a.id, n2 - b.value, bounds);
|
|
429
|
+
}
|
|
430
|
+
if (b.op === "var" && a.op === "lit" && typeof a.value === "number") {
|
|
431
|
+
return eqFromBounds(b.id, n2 - a.value, bounds);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return void 0;
|
|
435
|
+
}
|
|
383
436
|
if (pred.op !== "gt" && pred.op !== "ge" && pred.op !== "lt" && pred.op !== "le") {
|
|
384
437
|
return void 0;
|
|
385
438
|
}
|
|
@@ -401,6 +454,20 @@ function impliesViaBounds(pred, bounds) {
|
|
|
401
454
|
}
|
|
402
455
|
return void 0;
|
|
403
456
|
}
|
|
457
|
+
function eqFromBounds(id, n, bounds) {
|
|
458
|
+
const lo = bounds.lo.get(id);
|
|
459
|
+
const hi = bounds.hi.get(id);
|
|
460
|
+
if (!lo || !hi) return void 0;
|
|
461
|
+
const loCovers = lo.strict ? lo.bound <= n : lo.bound <= n;
|
|
462
|
+
const hiCovers = hi.strict ? hi.bound >= n : hi.bound >= n;
|
|
463
|
+
if (lo.strict && lo.bound >= n) return false;
|
|
464
|
+
if (hi.strict && hi.bound <= n) return false;
|
|
465
|
+
if (!lo.strict && lo.bound > n) return false;
|
|
466
|
+
if (!hi.strict && hi.bound < n) return false;
|
|
467
|
+
if (!loCovers || !hiCovers) return void 0;
|
|
468
|
+
if (!lo.strict && !hi.strict && lo.bound === n && hi.bound === n) return true;
|
|
469
|
+
return void 0;
|
|
470
|
+
}
|
|
404
471
|
function cmpVar(id, op, n, bounds) {
|
|
405
472
|
const lo = bounds.lo.get(id);
|
|
406
473
|
const hi = bounds.hi.get(id);
|
|
@@ -709,173 +776,6 @@ function shapeOnlyFn(paramTypes, returnType, opts) {
|
|
|
709
776
|
);
|
|
710
777
|
}
|
|
711
778
|
|
|
712
|
-
// src/algebra/template.ts
|
|
713
|
-
function viewTemplateParts(parts, describe) {
|
|
714
|
-
return parts.map((p) => {
|
|
715
|
-
const d = describe(p);
|
|
716
|
-
return "fixed" in d ? { fixed: d.fixed, render: d.fixed, part: p } : { fixed: void 0, render: d.render, part: p };
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
function knownPrefixOfViews(views) {
|
|
720
|
-
let s = "";
|
|
721
|
-
for (const v2 of views) {
|
|
722
|
-
if (v2.fixed !== void 0) s += v2.fixed;
|
|
723
|
-
else break;
|
|
724
|
-
}
|
|
725
|
-
return s;
|
|
726
|
-
}
|
|
727
|
-
function knownSuffixOfViews(views) {
|
|
728
|
-
let s = "";
|
|
729
|
-
for (let i = views.length - 1; i >= 0; i--) {
|
|
730
|
-
const v2 = views[i];
|
|
731
|
-
if (v2.fixed !== void 0) s = v2.fixed + s;
|
|
732
|
-
else break;
|
|
733
|
-
}
|
|
734
|
-
return s;
|
|
735
|
-
}
|
|
736
|
-
function allFixedTextOfViews(views) {
|
|
737
|
-
return views.filter((v2) => v2.fixed !== void 0).map((v2) => v2.fixed).join("");
|
|
738
|
-
}
|
|
739
|
-
function fixedLengthOfViews(views) {
|
|
740
|
-
if (views.some((v2) => v2.fixed === void 0)) return void 0;
|
|
741
|
-
return allFixedTextOfViews(views).length;
|
|
742
|
-
}
|
|
743
|
-
function formatTemplateNameViews(views) {
|
|
744
|
-
const inner = views.map((v2) => v2.fixed !== void 0 ? v2.fixed : `\${${v2.render}}`).join("");
|
|
745
|
-
return `\`${inner}\``;
|
|
746
|
-
}
|
|
747
|
-
function mergeAdjacentFixedViews(views, rebuildFixed) {
|
|
748
|
-
const out = [];
|
|
749
|
-
for (const v2 of views) {
|
|
750
|
-
const last = out[out.length - 1];
|
|
751
|
-
if (last && last.fixed !== void 0 && v2.fixed !== void 0) {
|
|
752
|
-
out[out.length - 1] = rebuildFixed(last.fixed + v2.fixed);
|
|
753
|
-
} else {
|
|
754
|
-
out.push(v2);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
return out;
|
|
758
|
-
}
|
|
759
|
-
function templateMatchesValue(value, views) {
|
|
760
|
-
let pos = 0;
|
|
761
|
-
for (let i = 0; i < views.length; i++) {
|
|
762
|
-
const v2 = views[i];
|
|
763
|
-
if (v2.fixed !== void 0) {
|
|
764
|
-
if (!value.startsWith(v2.fixed, pos)) return false;
|
|
765
|
-
pos += v2.fixed.length;
|
|
766
|
-
} else {
|
|
767
|
-
if (i === views.length - 1) return true;
|
|
768
|
-
const next = views[i + 1];
|
|
769
|
-
if (next?.fixed !== void 0) {
|
|
770
|
-
const idx = value.indexOf(next.fixed, pos);
|
|
771
|
-
if (idx === -1) return false;
|
|
772
|
-
pos = idx;
|
|
773
|
-
} else {
|
|
774
|
-
return true;
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return pos === value.length;
|
|
779
|
-
}
|
|
780
|
-
function decideStartsWith(prefix, search) {
|
|
781
|
-
if (prefix.length >= search.length) return prefix.startsWith(search);
|
|
782
|
-
if (search.startsWith(prefix)) return "unknown";
|
|
783
|
-
return false;
|
|
784
|
-
}
|
|
785
|
-
function decideEndsWith(suffix, search) {
|
|
786
|
-
if (suffix.length >= search.length) return suffix.endsWith(search);
|
|
787
|
-
if (search.endsWith(suffix)) return "unknown";
|
|
788
|
-
return false;
|
|
789
|
-
}
|
|
790
|
-
function decideIncludes(fixedText, search) {
|
|
791
|
-
return fixedText.includes(search) ? true : "unknown";
|
|
792
|
-
}
|
|
793
|
-
function isStrLit(a) {
|
|
794
|
-
return a.shape.k === "prim" && a.shape.type === "string" && a.term?.op === "lit" && typeof a.term.value === "string";
|
|
795
|
-
}
|
|
796
|
-
function isStrPrim2(a) {
|
|
797
|
-
return a.shape.k === "prim" && a.shape.type === "string";
|
|
798
|
-
}
|
|
799
|
-
function isTemplateAbs(a) {
|
|
800
|
-
return a.shape.k === "prim" && a.shape.type === "string" && !!a.pred && a.pred.name?.startsWith("`") === true && Array.isArray(a.pred.meta?.templateParts);
|
|
801
|
-
}
|
|
802
|
-
function describeAbsPart(p) {
|
|
803
|
-
if (isStrLit(p)) return { fixed: String(litValue(p)) };
|
|
804
|
-
return { render: p.term ? termToString(p.term) : "string" };
|
|
805
|
-
}
|
|
806
|
-
function absTemplateViews(parts) {
|
|
807
|
-
return viewTemplateParts(parts, describeAbsPart);
|
|
808
|
-
}
|
|
809
|
-
function templatePartsOf(a) {
|
|
810
|
-
if (isTemplateAbs(a)) {
|
|
811
|
-
const meta = a.pred.meta;
|
|
812
|
-
return meta.templateParts;
|
|
813
|
-
}
|
|
814
|
-
return [a];
|
|
815
|
-
}
|
|
816
|
-
function rebuildAbsFixedView(text) {
|
|
817
|
-
return {
|
|
818
|
-
fixed: text,
|
|
819
|
-
render: text,
|
|
820
|
-
part: abs({ k: "prim", type: "string" }, lit(text), void 0, "exact")
|
|
821
|
-
};
|
|
822
|
-
}
|
|
823
|
-
function normalizeParts(parts) {
|
|
824
|
-
return mergeAdjacentFixedViews(absTemplateViews(parts), rebuildAbsFixedView).map((v2) => v2.part);
|
|
825
|
-
}
|
|
826
|
-
function formatTemplateName(parts) {
|
|
827
|
-
return formatTemplateNameViews(absTemplateViews(parts));
|
|
828
|
-
}
|
|
829
|
-
function createTemplateAbs(parts) {
|
|
830
|
-
const normalized = normalizeParts(parts);
|
|
831
|
-
if (normalized.length === 1) {
|
|
832
|
-
const only = normalized[0];
|
|
833
|
-
if (isStrLit(only)) return only;
|
|
834
|
-
if (isStrPrim2(only) && !isTemplateAbs(only)) return only;
|
|
835
|
-
}
|
|
836
|
-
const name = formatTemplateName(normalized);
|
|
837
|
-
const predObj = {
|
|
838
|
-
op: "true",
|
|
839
|
-
name,
|
|
840
|
-
meta: { templateParts: normalized }
|
|
841
|
-
};
|
|
842
|
-
return {
|
|
843
|
-
shape: { k: "prim", type: "string" },
|
|
844
|
-
term: void 0,
|
|
845
|
-
pred: predObj,
|
|
846
|
-
conf: "path"
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
function isTemplateLike(a) {
|
|
850
|
-
return isTemplateAbs(a);
|
|
851
|
-
}
|
|
852
|
-
function concatString(a, b) {
|
|
853
|
-
if (isStrLit(a) && isStrLit(b)) {
|
|
854
|
-
return abs(
|
|
855
|
-
{ k: "prim", type: "string" },
|
|
856
|
-
lit(String(litValue(a)) + String(litValue(b))),
|
|
857
|
-
void 0,
|
|
858
|
-
"exact"
|
|
859
|
-
);
|
|
860
|
-
}
|
|
861
|
-
const aParts = coerceToStringParts(a);
|
|
862
|
-
const bParts = coerceToStringParts(b);
|
|
863
|
-
if (!aParts || !bParts) return abs({ k: "unknown" }, void 0, void 0, "partial");
|
|
864
|
-
return createTemplateAbs([...aParts, ...bParts]);
|
|
865
|
-
}
|
|
866
|
-
function coerceToStringParts(a) {
|
|
867
|
-
if (isTemplateAbs(a) || isStrPrim2(a)) return templatePartsOf(a);
|
|
868
|
-
if (isStrLit(a)) return [a];
|
|
869
|
-
const lv = litValue(a);
|
|
870
|
-
if (typeof lv === "number" || typeof lv === "boolean") {
|
|
871
|
-
return [abs({ k: "prim", type: "string" }, lit(String(lv)), void 0, "exact")];
|
|
872
|
-
}
|
|
873
|
-
if (a.shape.k === "prim" && a.shape.type === "number") {
|
|
874
|
-
return [a];
|
|
875
|
-
}
|
|
876
|
-
return void 0;
|
|
877
|
-
}
|
|
878
|
-
|
|
879
779
|
// src/algebra/derivation.ts
|
|
880
780
|
var collector = null;
|
|
881
781
|
var nextId = 1;
|
|
@@ -1084,114 +984,903 @@ function joinValues(a, b) {
|
|
|
1084
984
|
if (va !== void 0 && Object.is(va, vb)) return a;
|
|
1085
985
|
if (a.shape.k === "prim" && b.shape.k === "prim" && a.shape.type === b.shape.type) {
|
|
1086
986
|
if (va !== void 0 && vb !== void 0) {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
void 0,
|
|
1091
|
-
|
|
1092
|
-
);
|
|
987
|
+
const nanA = typeof va === "number" && Number.isNaN(va);
|
|
988
|
+
const nanB = typeof vb === "number" && Number.isNaN(vb);
|
|
989
|
+
if (nanA || nanB) {
|
|
990
|
+
return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
|
|
991
|
+
}
|
|
992
|
+
return makeSum(a, b);
|
|
1093
993
|
}
|
|
1094
994
|
return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
|
|
1095
995
|
}
|
|
1096
|
-
return makeSum(a, b);
|
|
996
|
+
return makeSum(a, b);
|
|
997
|
+
}
|
|
998
|
+
function makeSum(a, b) {
|
|
999
|
+
const members = flattenSum([a, b]);
|
|
1000
|
+
if (members.length === 1) return members[0];
|
|
1001
|
+
if (members.length > 16) {
|
|
1002
|
+
const first = members[0];
|
|
1003
|
+
const samePrimLit = first.shape.k === "prim" && members.every(
|
|
1004
|
+
(m) => m.shape.k === "prim" && m.shape.type === first.shape.type && litValue(m) !== void 0
|
|
1005
|
+
);
|
|
1006
|
+
if (samePrimLit) {
|
|
1007
|
+
return abs(first.shape, void 0, void 0, "path");
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return {
|
|
1011
|
+
shape: { k: "sum", members },
|
|
1012
|
+
conf: confJoin(a.conf, b.conf)
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
function flattenSum(xs) {
|
|
1016
|
+
const out = [];
|
|
1017
|
+
for (const x of xs) {
|
|
1018
|
+
if (x.shape.k === "sum") out.push(...x.shape.members);
|
|
1019
|
+
else out.push(x);
|
|
1020
|
+
}
|
|
1021
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1022
|
+
const deduped = [];
|
|
1023
|
+
for (const x of out) {
|
|
1024
|
+
const key = absShapeKey(x);
|
|
1025
|
+
if (seen.has(key)) continue;
|
|
1026
|
+
seen.add(key);
|
|
1027
|
+
deduped.push(x);
|
|
1028
|
+
}
|
|
1029
|
+
return deduped;
|
|
1030
|
+
}
|
|
1031
|
+
function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
1032
|
+
if (seen.has(a)) return "cycle";
|
|
1033
|
+
seen.add(a);
|
|
1034
|
+
try {
|
|
1035
|
+
const s = a.shape;
|
|
1036
|
+
if (s.k === "prim") {
|
|
1037
|
+
const lv = litValue(a);
|
|
1038
|
+
if (lv !== void 0) return `prim:${s.type}:${String(lv)}`;
|
|
1039
|
+
const t = a.term ? termToString(a.term) : "";
|
|
1040
|
+
const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
|
|
1041
|
+
return `prim:${s.type}:${t}:${p}`;
|
|
1042
|
+
}
|
|
1043
|
+
if (s.k === "never") return "never";
|
|
1044
|
+
if (s.k === "any") return "any";
|
|
1045
|
+
if (s.k === "unknown") {
|
|
1046
|
+
if (a.term?.op === "lit" && a.term.value === void 0) return "unknown:undefined";
|
|
1047
|
+
return "unknown";
|
|
1048
|
+
}
|
|
1049
|
+
if (s.k === "arr") return `arr(${absShapeKey(s.element, seen)})`;
|
|
1050
|
+
if (s.k === "tuple") {
|
|
1051
|
+
const els = s.elements.map((e) => absShapeKey(e, seen)).join(",");
|
|
1052
|
+
const rest = s.rest ? `...${absShapeKey(s.rest, seen)}` : "";
|
|
1053
|
+
return `tuple[${els}${rest}]`;
|
|
1054
|
+
}
|
|
1055
|
+
if (s.k === "brand") return `brand:${s.name}(${absShapeKey(s.shape, seen)})`;
|
|
1056
|
+
if (s.k === "eff") return `eff:${s.eff}<${absShapeKey(s.inner, seen)}>`;
|
|
1057
|
+
if (s.k === "obj") {
|
|
1058
|
+
const slots = Object.keys(s.slots).sort().map((k) => {
|
|
1059
|
+
const slot = s.slots[k];
|
|
1060
|
+
const flags = (slot.optional ? "?" : "") + (slot.readonly ? "r" : "");
|
|
1061
|
+
return `${k}${flags}:${absShapeKey(slot.value, seen)}`;
|
|
1062
|
+
}).join(",");
|
|
1063
|
+
const idx = s.index ? `idx(${absShapeKey(s.index.key, seen)}\u2192${absShapeKey(s.index.value, seen)})` : "";
|
|
1064
|
+
const open = s.open ? "open" : "";
|
|
1065
|
+
return `obj{${slots}}${idx}${open}`;
|
|
1066
|
+
}
|
|
1067
|
+
if (s.k === "fn") {
|
|
1068
|
+
const pts = (s.paramTypes ?? []).map((t) => absShapeKey(t, seen)).join(",");
|
|
1069
|
+
const ret = s.returnType ? absShapeKey(s.returnType, seen) : "?";
|
|
1070
|
+
const name = s.name ? `#${s.name}` : "";
|
|
1071
|
+
return `fn${name}(${s.params.join(",")}|${pts})=>${ret}`;
|
|
1072
|
+
}
|
|
1073
|
+
if (s.k === "sum") {
|
|
1074
|
+
return `sum(${s.members.map((m) => absShapeKey(m, seen)).join("|")})`;
|
|
1075
|
+
}
|
|
1076
|
+
return "other";
|
|
1077
|
+
} finally {
|
|
1078
|
+
seen.delete(a);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
function fnOf(params, name) {
|
|
1082
|
+
const shape = { k: "fn", params };
|
|
1083
|
+
if (name) shape.name = name;
|
|
1084
|
+
return { shape, conf: "exact" };
|
|
1085
|
+
}
|
|
1086
|
+
function joinFunctions(a, b) {
|
|
1087
|
+
const sa = a.shape;
|
|
1088
|
+
const sb = b.shape;
|
|
1089
|
+
if (sa.k !== "fn" || sb.k !== "fn") return makeSum(a, b);
|
|
1090
|
+
const an = sa.name;
|
|
1091
|
+
const bn = sb.name;
|
|
1092
|
+
if (an && an === bn) {
|
|
1093
|
+
if (sa.params.length === sb.params.length && sa.params.every((p, i) => p === sb.params[i])) {
|
|
1094
|
+
return a;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return makeSum(a, b);
|
|
1098
|
+
}
|
|
1099
|
+
function shapeBrief(a) {
|
|
1100
|
+
const s = a.shape;
|
|
1101
|
+
switch (s.k) {
|
|
1102
|
+
case "never":
|
|
1103
|
+
return "never";
|
|
1104
|
+
case "unknown":
|
|
1105
|
+
case "any":
|
|
1106
|
+
return s.k;
|
|
1107
|
+
case "prim":
|
|
1108
|
+
return s.type;
|
|
1109
|
+
case "arr":
|
|
1110
|
+
return `${shapeBrief(s.element)}[]`;
|
|
1111
|
+
case "obj":
|
|
1112
|
+
return "{\u2026}";
|
|
1113
|
+
case "tuple":
|
|
1114
|
+
return `[${s.elements.length}]`;
|
|
1115
|
+
case "fn":
|
|
1116
|
+
return "fn";
|
|
1117
|
+
case "brand":
|
|
1118
|
+
return s.name;
|
|
1119
|
+
case "eff":
|
|
1120
|
+
return s.eff;
|
|
1121
|
+
case "sum":
|
|
1122
|
+
return s.members.map(shapeBrief).join("|");
|
|
1123
|
+
default:
|
|
1124
|
+
return "\xB7";
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
function annotateJoinPath(a, b, result) {
|
|
1128
|
+
if (result === a || result === b) return result;
|
|
1129
|
+
const sa = shapeBrief(a);
|
|
1130
|
+
const sb = shapeBrief(b);
|
|
1131
|
+
if (sa === sb) {
|
|
1132
|
+
const extra = sameShapeJoinNote(a, b);
|
|
1133
|
+
if (!extra) return result;
|
|
1134
|
+
const note3 = `join(${sa}: ${extra})`;
|
|
1135
|
+
if (result.pathNote === note3) return result;
|
|
1136
|
+
return { ...result, pathNote: note3 };
|
|
1137
|
+
}
|
|
1138
|
+
const note2 = `join(${sa} | ${sb})`;
|
|
1139
|
+
if (result.pathNote === note2) return result;
|
|
1140
|
+
return { ...result, pathNote: note2 };
|
|
1141
|
+
}
|
|
1142
|
+
function sameShapeJoinNote(a, b) {
|
|
1143
|
+
if (a.shape.k === "obj" && b.shape.k === "obj") {
|
|
1144
|
+
const ak = Object.keys(a.shape.slots ?? {});
|
|
1145
|
+
const bk = Object.keys(b.shape.slots ?? {});
|
|
1146
|
+
const onlyA = ak.filter((k) => !bk.includes(k));
|
|
1147
|
+
const onlyB = bk.filter((k) => !ak.includes(k));
|
|
1148
|
+
if (onlyA.length === 0 && onlyB.length === 0) return void 0;
|
|
1149
|
+
const parts = [];
|
|
1150
|
+
if (onlyA.length > 0) parts.push(`+${onlyA.join(",")}`);
|
|
1151
|
+
if (onlyB.length > 0) parts.push(`+${onlyB.join(",")}`);
|
|
1152
|
+
return parts.join(" ");
|
|
1153
|
+
}
|
|
1154
|
+
if (a.shape.k === "tuple" && b.shape.k === "tuple") {
|
|
1155
|
+
const la = a.shape.elements.length;
|
|
1156
|
+
const lb = b.shape.elements.length;
|
|
1157
|
+
if (la === lb) return void 0;
|
|
1158
|
+
return `len ${la}|${lb}`;
|
|
1159
|
+
}
|
|
1160
|
+
if (a.shape.k === "brand" && b.shape.k === "brand") {
|
|
1161
|
+
const an = a.shape.name;
|
|
1162
|
+
const bn = b.shape.name;
|
|
1163
|
+
if (an !== bn) return `brand ${an}|${bn}`;
|
|
1164
|
+
const ai = a.shape.shape;
|
|
1165
|
+
const bi = b.shape.shape;
|
|
1166
|
+
return sameShapeJoinNote(ai, bi);
|
|
1167
|
+
}
|
|
1168
|
+
if (a.shape.k === "sum" && b.shape.k === "sum") {
|
|
1169
|
+
const am = a.shape.members.map((m) => shapeBrief(m)).sort().join(",");
|
|
1170
|
+
const bm = b.shape.members.map((m) => shapeBrief(m)).sort().join(",");
|
|
1171
|
+
if (am === bm) return void 0;
|
|
1172
|
+
return `sum ${am}|${bm}`;
|
|
1173
|
+
}
|
|
1174
|
+
return void 0;
|
|
1175
|
+
}
|
|
1176
|
+
function joinAbs(a, b) {
|
|
1177
|
+
if (a.shape.k === "never") return b;
|
|
1178
|
+
if (b.shape.k === "never") return a;
|
|
1179
|
+
if (isObj(a) && isObj(b)) {
|
|
1180
|
+
return annotateJoinPath(a, b, joinObjects(a, b));
|
|
1181
|
+
}
|
|
1182
|
+
if (a.shape.k === "fn" && b.shape.k === "fn") {
|
|
1183
|
+
return annotateJoinPath(a, b, joinFunctions(a, b));
|
|
1184
|
+
}
|
|
1185
|
+
const result = joinValues(a, b);
|
|
1186
|
+
noteDerivationJoin([a, b], result);
|
|
1187
|
+
return annotateJoinPath(a, b, result);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// src/algebra/collections.ts
|
|
1191
|
+
var mapTables = /* @__PURE__ */ new WeakMap();
|
|
1192
|
+
var setTables = /* @__PURE__ */ new WeakMap();
|
|
1193
|
+
var armOverlays = [];
|
|
1194
|
+
function pushCollectionArm() {
|
|
1195
|
+
armOverlays.push(/* @__PURE__ */ new WeakMap());
|
|
1196
|
+
}
|
|
1197
|
+
function popCollectionArm() {
|
|
1198
|
+
return armOverlays.pop();
|
|
1199
|
+
}
|
|
1200
|
+
function cloneMapTable(t) {
|
|
1201
|
+
return {
|
|
1202
|
+
byLit: new Map(t.byLit),
|
|
1203
|
+
shadowValues: [...t.shadowValues],
|
|
1204
|
+
maybeAbsent: t.maybeAbsent ? new Set(t.maybeAbsent) : void 0
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
function cloneSetTable(t) {
|
|
1208
|
+
return {
|
|
1209
|
+
elements: [...t.elements],
|
|
1210
|
+
maybeAbsent: t.maybeAbsent instanceof Set ? new Set(t.maybeAbsent) : t.maybeAbsent
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
function setAbsentKey(t, k) {
|
|
1214
|
+
if (!t) return false;
|
|
1215
|
+
if (t.maybeAbsent === true) return true;
|
|
1216
|
+
return t.maybeAbsent instanceof Set && t.maybeAbsent.has(k);
|
|
1217
|
+
}
|
|
1218
|
+
function setAnyAbsent(t) {
|
|
1219
|
+
if (!t) return false;
|
|
1220
|
+
return t.maybeAbsent === true || t.maybeAbsent instanceof Set && t.maybeAbsent.size > 0;
|
|
1221
|
+
}
|
|
1222
|
+
function mergeCollectionArms(arms) {
|
|
1223
|
+
endCollectionFork(arms);
|
|
1224
|
+
}
|
|
1225
|
+
var forkTouchedStack = [];
|
|
1226
|
+
function beginCollectionFork() {
|
|
1227
|
+
forkTouchedStack.push(/* @__PURE__ */ new Set());
|
|
1228
|
+
}
|
|
1229
|
+
function noteCollectionWrite(id) {
|
|
1230
|
+
const top = forkTouchedStack[forkTouchedStack.length - 1];
|
|
1231
|
+
if (top) top.add(id);
|
|
1232
|
+
}
|
|
1233
|
+
function endCollectionFork(arms) {
|
|
1234
|
+
const touched = forkTouchedStack.pop() ?? /* @__PURE__ */ new Set();
|
|
1235
|
+
const live = arms.filter(Boolean);
|
|
1236
|
+
if (live.length === 0) return;
|
|
1237
|
+
const nested = armOverlays.length > 0;
|
|
1238
|
+
const outerArm = nested ? armOverlays[armOverlays.length - 1] : void 0;
|
|
1239
|
+
const commitMap = (id, merged) => {
|
|
1240
|
+
if (outerArm) {
|
|
1241
|
+
const e = outerArm.get(id) ?? {};
|
|
1242
|
+
outerArm.set(id, { ...e, map: merged });
|
|
1243
|
+
} else {
|
|
1244
|
+
mapTables.set(id, merged);
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
const commitSet = (id, merged) => {
|
|
1248
|
+
if (outerArm) {
|
|
1249
|
+
const e = outerArm.get(id) ?? {};
|
|
1250
|
+
outerArm.set(id, { ...e, set: merged });
|
|
1251
|
+
} else {
|
|
1252
|
+
setTables.set(id, merged);
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
for (const id of touched) {
|
|
1256
|
+
const armTables = [];
|
|
1257
|
+
const armSetTables = [];
|
|
1258
|
+
let anyMap = false;
|
|
1259
|
+
let anySet = false;
|
|
1260
|
+
for (const arm of live) {
|
|
1261
|
+
const e = arm.get(id);
|
|
1262
|
+
if (e?.map) {
|
|
1263
|
+
anyMap = true;
|
|
1264
|
+
armTables.push(e.map);
|
|
1265
|
+
} else if (anyMap || armTables.length > 0) {
|
|
1266
|
+
armTables.push(void 0);
|
|
1267
|
+
}
|
|
1268
|
+
if (e?.set) {
|
|
1269
|
+
anySet = true;
|
|
1270
|
+
armSetTables.push(e.set);
|
|
1271
|
+
} else if (anySet || armSetTables.length > 0) {
|
|
1272
|
+
armSetTables.push(void 0);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
if (anyMap || armTables.some(Boolean)) {
|
|
1276
|
+
const base = (nested ? mapTableForReadBase(outerArm, id) : mapTables.get(id)) ?? emptyMapTable();
|
|
1277
|
+
const perArm = live.map((arm) => {
|
|
1278
|
+
const e = arm.get(id);
|
|
1279
|
+
return e?.map ?? cloneMapTable(base);
|
|
1280
|
+
});
|
|
1281
|
+
const merged = { byLit: /* @__PURE__ */ new Map(), shadowValues: [], maybeAbsent: /* @__PURE__ */ new Set() };
|
|
1282
|
+
const keyArms = /* @__PURE__ */ new Map();
|
|
1283
|
+
const forcedAbsent = /* @__PURE__ */ new Set();
|
|
1284
|
+
for (const t of perArm) {
|
|
1285
|
+
for (const [k, v2] of t.byLit) {
|
|
1286
|
+
const prev = merged.byLit.get(k);
|
|
1287
|
+
merged.byLit.set(k, prev ? joinAbs(prev, v2) : v2);
|
|
1288
|
+
keyArms.set(k, (keyArms.get(k) ?? 0) + 1);
|
|
1289
|
+
}
|
|
1290
|
+
for (const sv of t.shadowValues) merged.shadowValues.push(sv);
|
|
1291
|
+
if (t.maybeAbsent) {
|
|
1292
|
+
for (const k of t.maybeAbsent) forcedAbsent.add(k);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
for (const [k, count] of keyArms) {
|
|
1296
|
+
if (count < perArm.length) merged.maybeAbsent.add(k);
|
|
1297
|
+
}
|
|
1298
|
+
for (const k of forcedAbsent) merged.maybeAbsent.add(k);
|
|
1299
|
+
if (merged.maybeAbsent.size === 0) delete merged.maybeAbsent;
|
|
1300
|
+
commitMap(id, merged);
|
|
1301
|
+
}
|
|
1302
|
+
if (anySet || armSetTables.some(Boolean)) {
|
|
1303
|
+
const base = (nested ? setTableForReadBase(outerArm, id) : setTables.get(id)) ?? emptySetTable();
|
|
1304
|
+
const perArm = live.map((arm) => {
|
|
1305
|
+
const e = arm.get(id);
|
|
1306
|
+
return e?.set ?? cloneSetTable(base);
|
|
1307
|
+
});
|
|
1308
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1309
|
+
const mergedEls = [];
|
|
1310
|
+
const litArmCount = /* @__PURE__ */ new Map();
|
|
1311
|
+
const forcedAbsent = /* @__PURE__ */ new Set();
|
|
1312
|
+
let wholeUncertain = false;
|
|
1313
|
+
let hasNonLit = false;
|
|
1314
|
+
for (const t of perArm) {
|
|
1315
|
+
if (t.maybeAbsent === true) wholeUncertain = true;
|
|
1316
|
+
if (t.maybeAbsent instanceof Set) {
|
|
1317
|
+
for (const k of t.maybeAbsent) forcedAbsent.add(k);
|
|
1318
|
+
}
|
|
1319
|
+
const armLits = /* @__PURE__ */ new Set();
|
|
1320
|
+
for (const el of t.elements) {
|
|
1321
|
+
const lk = litKeyOf(el);
|
|
1322
|
+
if (lk !== void 0) {
|
|
1323
|
+
if (!seen.has(lk)) {
|
|
1324
|
+
seen.add(lk);
|
|
1325
|
+
mergedEls.push(el);
|
|
1326
|
+
}
|
|
1327
|
+
armLits.add(lk);
|
|
1328
|
+
} else {
|
|
1329
|
+
hasNonLit = true;
|
|
1330
|
+
mergedEls.push(el);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
for (const k of armLits) {
|
|
1334
|
+
litArmCount.set(k, (litArmCount.get(k) ?? 0) + 1);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
const maybeKeys = /* @__PURE__ */ new Set();
|
|
1338
|
+
if (wholeUncertain || hasNonLit) {
|
|
1339
|
+
wholeUncertain = true;
|
|
1340
|
+
} else {
|
|
1341
|
+
for (const [k, count] of litArmCount) {
|
|
1342
|
+
if (count < perArm.length) maybeKeys.add(k);
|
|
1343
|
+
}
|
|
1344
|
+
for (const k of forcedAbsent) maybeKeys.add(k);
|
|
1345
|
+
}
|
|
1346
|
+
commitSet(id, {
|
|
1347
|
+
elements: mergedEls,
|
|
1348
|
+
maybeAbsent: wholeUncertain ? true : maybeKeys.size > 0 ? maybeKeys : void 0
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
function mapTableForReadBase(arm, id) {
|
|
1354
|
+
return arm.get(id)?.map ?? mapTables.get(id);
|
|
1355
|
+
}
|
|
1356
|
+
function setTableForReadBase(arm, id) {
|
|
1357
|
+
return arm.get(id)?.set ?? setTables.get(id);
|
|
1358
|
+
}
|
|
1359
|
+
function emptyMapTable() {
|
|
1360
|
+
return { byLit: /* @__PURE__ */ new Map(), shadowValues: [] };
|
|
1361
|
+
}
|
|
1362
|
+
function emptySetTable() {
|
|
1363
|
+
return { elements: [] };
|
|
1364
|
+
}
|
|
1365
|
+
function brandOf(name) {
|
|
1366
|
+
return abs(
|
|
1367
|
+
{ k: "brand", name, shape: objOf({}) },
|
|
1368
|
+
void 0,
|
|
1369
|
+
void 0,
|
|
1370
|
+
"path"
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
function litKeyOf(a) {
|
|
1374
|
+
if (!a) return void 0;
|
|
1375
|
+
if (a.term?.op === "lit") return a.term.value;
|
|
1376
|
+
const v2 = litValue(a);
|
|
1377
|
+
if (v2 === void 0 && a.term === void 0) return void 0;
|
|
1378
|
+
return v2;
|
|
1379
|
+
}
|
|
1380
|
+
function isMapAbs(a) {
|
|
1381
|
+
return !!a && a.shape.k === "brand" && a.shape.name === "Map";
|
|
1382
|
+
}
|
|
1383
|
+
function isSetAbs(a) {
|
|
1384
|
+
return !!a && a.shape.k === "brand" && a.shape.name === "Set";
|
|
1385
|
+
}
|
|
1386
|
+
function elementsFrom(iterable) {
|
|
1387
|
+
if (!iterable) return [];
|
|
1388
|
+
if (iterable.shape.k === "tuple") return [...iterable.shape.elements];
|
|
1389
|
+
if (iterable.shape.k === "arr") {
|
|
1390
|
+
return [iterable.shape.element];
|
|
1391
|
+
}
|
|
1392
|
+
if (iterable.shape.k === "sum") {
|
|
1393
|
+
return iterable.shape.members.flatMap(elementsFrom);
|
|
1394
|
+
}
|
|
1395
|
+
return [];
|
|
1396
|
+
}
|
|
1397
|
+
function makeMapAbs(iterable) {
|
|
1398
|
+
const m = brandOf("Map");
|
|
1399
|
+
const table = emptyMapTable();
|
|
1400
|
+
for (const el of elementsFrom(iterable)) {
|
|
1401
|
+
if (el.shape.k === "tuple" && el.shape.elements.length >= 2) {
|
|
1402
|
+
const k = litKeyOf(el.shape.elements[0]);
|
|
1403
|
+
const v2 = el.shape.elements[1];
|
|
1404
|
+
if (k !== void 0) table.byLit.set(k, v2);
|
|
1405
|
+
else table.shadowValues.push(v2);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
mapTables.set(m, table);
|
|
1409
|
+
return m;
|
|
1410
|
+
}
|
|
1411
|
+
function makeSetAbs(iterable) {
|
|
1412
|
+
const s = brandOf("Set");
|
|
1413
|
+
const table = emptySetTable();
|
|
1414
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1415
|
+
for (const el of elementsFrom(iterable)) {
|
|
1416
|
+
const lk = litKeyOf(el);
|
|
1417
|
+
if (lk !== void 0) {
|
|
1418
|
+
if (seen.has(lk)) continue;
|
|
1419
|
+
seen.add(lk);
|
|
1420
|
+
}
|
|
1421
|
+
table.elements.push(el);
|
|
1422
|
+
}
|
|
1423
|
+
setTables.set(s, table);
|
|
1424
|
+
return s;
|
|
1425
|
+
}
|
|
1426
|
+
function mapTableOf(a) {
|
|
1427
|
+
const existing = mapTables.get(a);
|
|
1428
|
+
if (existing) return existing;
|
|
1429
|
+
const t = emptyMapTable();
|
|
1430
|
+
mapTables.set(a, t);
|
|
1431
|
+
return t;
|
|
1432
|
+
}
|
|
1433
|
+
function setTableOf(a) {
|
|
1434
|
+
const existing = setTables.get(a);
|
|
1435
|
+
if (existing) return existing;
|
|
1436
|
+
const t = emptySetTable();
|
|
1437
|
+
setTables.set(a, t);
|
|
1438
|
+
return t;
|
|
1439
|
+
}
|
|
1440
|
+
function mapTableForWrite(a) {
|
|
1441
|
+
noteCollectionWrite(a);
|
|
1442
|
+
if (armOverlays.length > 0) {
|
|
1443
|
+
let base;
|
|
1444
|
+
for (let i = 0; i < armOverlays.length; i++) {
|
|
1445
|
+
const e = armOverlays[i].get(a);
|
|
1446
|
+
if (e?.map) base = e.map;
|
|
1447
|
+
}
|
|
1448
|
+
if (!base) base = mapTables.get(a);
|
|
1449
|
+
const top = armOverlays[armOverlays.length - 1];
|
|
1450
|
+
let entry = top.get(a);
|
|
1451
|
+
if (!entry?.map) {
|
|
1452
|
+
const cloned = cloneMapTable(base ?? emptyMapTable());
|
|
1453
|
+
entry = { ...entry ?? {}, map: cloned };
|
|
1454
|
+
top.set(a, entry);
|
|
1455
|
+
return cloned;
|
|
1456
|
+
}
|
|
1457
|
+
return entry.map;
|
|
1458
|
+
}
|
|
1459
|
+
return mapTableOf(a);
|
|
1460
|
+
}
|
|
1461
|
+
function mapTableForRead(a) {
|
|
1462
|
+
for (let i = armOverlays.length - 1; i >= 0; i--) {
|
|
1463
|
+
const entry = armOverlays[i].get(a);
|
|
1464
|
+
if (entry?.map) return entry.map;
|
|
1465
|
+
}
|
|
1466
|
+
return mapTables.get(a);
|
|
1467
|
+
}
|
|
1468
|
+
function setTableForWrite(a) {
|
|
1469
|
+
noteCollectionWrite(a);
|
|
1470
|
+
if (armOverlays.length > 0) {
|
|
1471
|
+
let base;
|
|
1472
|
+
for (let i = 0; i < armOverlays.length; i++) {
|
|
1473
|
+
const e = armOverlays[i].get(a);
|
|
1474
|
+
if (e?.set) base = e.set;
|
|
1475
|
+
}
|
|
1476
|
+
if (!base) base = setTables.get(a);
|
|
1477
|
+
const top = armOverlays[armOverlays.length - 1];
|
|
1478
|
+
let entry = top.get(a);
|
|
1479
|
+
if (!entry?.set) {
|
|
1480
|
+
const cloned = cloneSetTable(base ?? emptySetTable());
|
|
1481
|
+
entry = { ...entry ?? {}, set: cloned };
|
|
1482
|
+
top.set(a, entry);
|
|
1483
|
+
return cloned;
|
|
1484
|
+
}
|
|
1485
|
+
return entry.set;
|
|
1486
|
+
}
|
|
1487
|
+
return setTableOf(a);
|
|
1488
|
+
}
|
|
1489
|
+
function setTableForRead(a) {
|
|
1490
|
+
for (let i = armOverlays.length - 1; i >= 0; i--) {
|
|
1491
|
+
const entry = armOverlays[i].get(a);
|
|
1492
|
+
if (entry?.set) return entry.set;
|
|
1493
|
+
}
|
|
1494
|
+
return setTables.get(a);
|
|
1495
|
+
}
|
|
1496
|
+
function mapSetEntry(mapAbs, key, value) {
|
|
1497
|
+
const t = mapTableForWrite(mapAbs);
|
|
1498
|
+
const k = litKeyOf(key);
|
|
1499
|
+
if (k !== void 0) t.byLit.set(k, value);
|
|
1500
|
+
else if (value) t.shadowValues.push(value);
|
|
1501
|
+
return mapAbs;
|
|
1502
|
+
}
|
|
1503
|
+
function mapDeleteEntry(mapAbs, key) {
|
|
1504
|
+
const t = mapTableForWrite(mapAbs);
|
|
1505
|
+
const k = litKeyOf(key);
|
|
1506
|
+
if (k !== void 0) {
|
|
1507
|
+
t.byLit.delete(k);
|
|
1508
|
+
t.maybeAbsent?.delete(k);
|
|
1509
|
+
} else if (t.shadowValues.length === 0 && t.byLit.size > 0) {
|
|
1510
|
+
t.maybeAbsent = new Set(t.byLit.keys());
|
|
1511
|
+
}
|
|
1512
|
+
return abs(
|
|
1513
|
+
{ k: "prim", type: "boolean" },
|
|
1514
|
+
void 0,
|
|
1515
|
+
void 0,
|
|
1516
|
+
"path"
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
function mapClearEntries(mapAbs) {
|
|
1520
|
+
const t = mapTableForWrite(mapAbs);
|
|
1521
|
+
t.byLit.clear();
|
|
1522
|
+
t.shadowValues.length = 0;
|
|
1523
|
+
delete t.maybeAbsent;
|
|
1524
|
+
return undefAbs();
|
|
1525
|
+
}
|
|
1526
|
+
function undefAbs() {
|
|
1527
|
+
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, void 0, "exact");
|
|
1528
|
+
}
|
|
1529
|
+
function joinAll(els) {
|
|
1530
|
+
if (els.length === 0) return void 0;
|
|
1531
|
+
return els.reduce((a, b) => joinAbs(a, b));
|
|
1532
|
+
}
|
|
1533
|
+
function mapGetEntry(mapAbs, key) {
|
|
1534
|
+
const t = mapTableForRead(mapAbs);
|
|
1535
|
+
if (!t) return unknown;
|
|
1536
|
+
const k = litKeyOf(key);
|
|
1537
|
+
if (k !== void 0) {
|
|
1538
|
+
const v2 = t.byLit.get(k);
|
|
1539
|
+
const absent = t.maybeAbsent?.has(k) === true;
|
|
1540
|
+
if (v2 !== void 0 && !absent && t.shadowValues.length === 0) return v2;
|
|
1541
|
+
if (v2 !== void 0) {
|
|
1542
|
+
return joinAll([v2, ...t.shadowValues, undefAbs()]) ?? undefAbs();
|
|
1543
|
+
}
|
|
1544
|
+
if (t.shadowValues.length === 0) return undefAbs();
|
|
1545
|
+
}
|
|
1546
|
+
const known = [...t.byLit.values(), ...t.shadowValues];
|
|
1547
|
+
const joined = joinAll(known);
|
|
1548
|
+
if (k !== void 0 && t.shadowValues.length === 0) {
|
|
1549
|
+
return undefAbs();
|
|
1550
|
+
}
|
|
1551
|
+
if (joined === void 0) {
|
|
1552
|
+
return k !== void 0 ? undefAbs() : unknown;
|
|
1553
|
+
}
|
|
1554
|
+
return joinAbs(joined, undefAbs());
|
|
1555
|
+
}
|
|
1556
|
+
function mapHasEntry(mapAbs, key) {
|
|
1557
|
+
const t = mapTableForRead(mapAbs);
|
|
1558
|
+
if (!t) return unknown;
|
|
1559
|
+
const k = litKeyOf(key);
|
|
1560
|
+
if (k === void 0) {
|
|
1561
|
+
return t.byLit.size > 0 || t.shadowValues.length > 0 ? abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial") : unknown;
|
|
1562
|
+
}
|
|
1563
|
+
const hit = t.byLit.has(k);
|
|
1564
|
+
const maybeAbsent = t.maybeAbsent?.has(k) === true;
|
|
1565
|
+
if (t.shadowValues.length > 0 || maybeAbsent) {
|
|
1566
|
+
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
1567
|
+
}
|
|
1568
|
+
return abs(
|
|
1569
|
+
{ k: "prim", type: "boolean" },
|
|
1570
|
+
{ op: "lit", value: hit },
|
|
1571
|
+
void 0,
|
|
1572
|
+
"exact"
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1575
|
+
function mapSizeAbs(mapAbs) {
|
|
1576
|
+
const t = mapTableForRead(mapAbs);
|
|
1577
|
+
if (!t || t.shadowValues.length > 0 || t.maybeAbsent && t.maybeAbsent.size > 0) {
|
|
1578
|
+
return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
|
|
1579
|
+
}
|
|
1580
|
+
return abs(
|
|
1581
|
+
{ k: "prim", type: "number" },
|
|
1582
|
+
{ op: "lit", value: t.byLit.size },
|
|
1583
|
+
void 0,
|
|
1584
|
+
"exact"
|
|
1585
|
+
);
|
|
1586
|
+
}
|
|
1587
|
+
function mapValuesAbs(mapAbs) {
|
|
1588
|
+
const t = mapTableForRead(mapAbs);
|
|
1589
|
+
if (!t) return [];
|
|
1590
|
+
return [...t.byLit.values(), ...t.shadowValues];
|
|
1591
|
+
}
|
|
1592
|
+
function keyAbsFromLitKey(k) {
|
|
1593
|
+
if (k === null) {
|
|
1594
|
+
return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
1595
|
+
}
|
|
1596
|
+
if (k === void 0) {
|
|
1597
|
+
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, void 0, "exact");
|
|
1598
|
+
}
|
|
1599
|
+
if (typeof k === "string") return abs({ k: "prim", type: "string" }, { op: "lit", value: k }, void 0, "exact");
|
|
1600
|
+
if (typeof k === "number") return abs({ k: "prim", type: "number" }, { op: "lit", value: k }, void 0, "exact");
|
|
1601
|
+
return abs({ k: "prim", type: "boolean" }, { op: "lit", value: k }, void 0, "exact");
|
|
1602
|
+
}
|
|
1603
|
+
function mapEntriesAbs(mapAbs) {
|
|
1604
|
+
const t = mapTableForRead(mapAbs);
|
|
1605
|
+
if (!t) return [];
|
|
1606
|
+
const entries = [];
|
|
1607
|
+
for (const [k, v2] of t.byLit) {
|
|
1608
|
+
entries.push(
|
|
1609
|
+
abs(
|
|
1610
|
+
{ k: "tuple", elements: [keyAbsFromLitKey(k), v2] },
|
|
1611
|
+
void 0,
|
|
1612
|
+
void 0,
|
|
1613
|
+
confJoin(v2.conf, "exact")
|
|
1614
|
+
)
|
|
1615
|
+
);
|
|
1616
|
+
}
|
|
1617
|
+
const unkKey = abs({ k: "unknown" }, void 0, void 0, "partial");
|
|
1618
|
+
for (const v2 of t.shadowValues) {
|
|
1619
|
+
entries.push(
|
|
1620
|
+
abs(
|
|
1621
|
+
{ k: "tuple", elements: [unkKey, v2] },
|
|
1622
|
+
void 0,
|
|
1623
|
+
void 0,
|
|
1624
|
+
"partial"
|
|
1625
|
+
)
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
return entries;
|
|
1629
|
+
}
|
|
1630
|
+
function setAddEntry(setAbs, value) {
|
|
1631
|
+
const t = setTableForWrite(setAbs);
|
|
1632
|
+
const lk = litKeyOf(value);
|
|
1633
|
+
if (lk !== void 0 && t.elements.some((el) => litKeyOf(el) === lk)) {
|
|
1634
|
+
return setAbs;
|
|
1635
|
+
}
|
|
1636
|
+
t.elements.push(value);
|
|
1637
|
+
return setAbs;
|
|
1638
|
+
}
|
|
1639
|
+
function setDeleteEntry(setAbs, value) {
|
|
1640
|
+
const t = setTableForWrite(setAbs);
|
|
1641
|
+
const lk = litKeyOf(value);
|
|
1642
|
+
if (lk !== void 0) {
|
|
1643
|
+
t.elements = t.elements.filter((el) => litKeyOf(el) !== lk);
|
|
1644
|
+
const hasUnknown = t.elements.some((el) => litKeyOf(el) === void 0);
|
|
1645
|
+
if (hasUnknown) t.maybeAbsent = true;
|
|
1646
|
+
else delete t.maybeAbsent;
|
|
1647
|
+
} else {
|
|
1648
|
+
t.maybeAbsent = true;
|
|
1649
|
+
}
|
|
1650
|
+
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "path");
|
|
1651
|
+
}
|
|
1652
|
+
function setClearEntries(setAbs) {
|
|
1653
|
+
const t = setTableForWrite(setAbs);
|
|
1654
|
+
t.elements = [];
|
|
1655
|
+
delete t.maybeAbsent;
|
|
1656
|
+
return undefAbs();
|
|
1657
|
+
}
|
|
1658
|
+
function setHasEntry(setAbs, value) {
|
|
1659
|
+
const t = setTableForRead(setAbs);
|
|
1660
|
+
if (!t) return unknown;
|
|
1661
|
+
const k = litKeyOf(value);
|
|
1662
|
+
if (k !== void 0) {
|
|
1663
|
+
const hit = t.elements.some((el) => litKeyOf(el) === k);
|
|
1664
|
+
if (setAbsentKey(t, k)) {
|
|
1665
|
+
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
1666
|
+
}
|
|
1667
|
+
return abs(
|
|
1668
|
+
{ k: "prim", type: "boolean" },
|
|
1669
|
+
{ op: "lit", value: hit },
|
|
1670
|
+
void 0,
|
|
1671
|
+
"exact"
|
|
1672
|
+
);
|
|
1673
|
+
}
|
|
1674
|
+
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
1675
|
+
}
|
|
1676
|
+
function setSizeAbs(setAbs) {
|
|
1677
|
+
const t = setTableForRead(setAbs);
|
|
1678
|
+
if (!t || setAnyAbsent(t)) {
|
|
1679
|
+
return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
|
|
1680
|
+
}
|
|
1681
|
+
return abs(
|
|
1682
|
+
{ k: "prim", type: "number" },
|
|
1683
|
+
{ op: "lit", value: t.elements.length },
|
|
1684
|
+
void 0,
|
|
1685
|
+
"exact"
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
function setElementsAbs(setAbs) {
|
|
1689
|
+
const t = setTableForRead(setAbs);
|
|
1690
|
+
return t ? [...t.elements] : [];
|
|
1691
|
+
}
|
|
1692
|
+
function collectionExactLen(c) {
|
|
1693
|
+
if (isSetAbs(c)) {
|
|
1694
|
+
const t = setTableForRead(c);
|
|
1695
|
+
if (!t) return void 0;
|
|
1696
|
+
if (t.maybeAbsent === true || t.maybeAbsent instanceof Set && t.maybeAbsent.size > 0) {
|
|
1697
|
+
return void 0;
|
|
1698
|
+
}
|
|
1699
|
+
return t.elements.length;
|
|
1700
|
+
}
|
|
1701
|
+
if (isMapAbs(c)) {
|
|
1702
|
+
const t = mapTableForRead(c);
|
|
1703
|
+
if (!t) return void 0;
|
|
1704
|
+
if (t.shadowValues.length > 0 || t.maybeAbsent && t.maybeAbsent.size > 0) {
|
|
1705
|
+
return void 0;
|
|
1706
|
+
}
|
|
1707
|
+
return t.byLit.size;
|
|
1708
|
+
}
|
|
1709
|
+
return void 0;
|
|
1710
|
+
}
|
|
1711
|
+
function collectionElementJoin(c) {
|
|
1712
|
+
const els = isSetAbs(c) ? setElementsAbs(c) : isMapAbs(c) ? mapEntriesAbs(c) : [];
|
|
1713
|
+
if (els.length === 0) return unknown;
|
|
1714
|
+
return els.reduce((a, b) => joinAbs(a, b));
|
|
1715
|
+
}
|
|
1716
|
+
function clearCollectionTables() {
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
// src/algebra/template.ts
|
|
1720
|
+
function viewTemplateParts(parts, describe) {
|
|
1721
|
+
return parts.map((p) => {
|
|
1722
|
+
const d = describe(p);
|
|
1723
|
+
return "fixed" in d ? { fixed: d.fixed, render: d.fixed, part: p } : { fixed: void 0, render: d.render, part: p };
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
function knownPrefixOfViews(views) {
|
|
1727
|
+
let s = "";
|
|
1728
|
+
for (const v2 of views) {
|
|
1729
|
+
if (v2.fixed !== void 0) s += v2.fixed;
|
|
1730
|
+
else break;
|
|
1731
|
+
}
|
|
1732
|
+
return s;
|
|
1733
|
+
}
|
|
1734
|
+
function knownSuffixOfViews(views) {
|
|
1735
|
+
let s = "";
|
|
1736
|
+
for (let i = views.length - 1; i >= 0; i--) {
|
|
1737
|
+
const v2 = views[i];
|
|
1738
|
+
if (v2.fixed !== void 0) s = v2.fixed + s;
|
|
1739
|
+
else break;
|
|
1740
|
+
}
|
|
1741
|
+
return s;
|
|
1742
|
+
}
|
|
1743
|
+
function allFixedTextOfViews(views) {
|
|
1744
|
+
return views.filter((v2) => v2.fixed !== void 0).map((v2) => v2.fixed).join("");
|
|
1745
|
+
}
|
|
1746
|
+
function fixedLengthOfViews(views) {
|
|
1747
|
+
if (views.some((v2) => v2.fixed === void 0)) return void 0;
|
|
1748
|
+
return allFixedTextOfViews(views).length;
|
|
1749
|
+
}
|
|
1750
|
+
function formatTemplateNameViews(views) {
|
|
1751
|
+
const inner = views.map((v2) => v2.fixed !== void 0 ? v2.fixed : `\${${v2.render}}`).join("");
|
|
1752
|
+
return `\`${inner}\``;
|
|
1753
|
+
}
|
|
1754
|
+
function mergeAdjacentFixedViews(views, rebuildFixed) {
|
|
1755
|
+
const out = [];
|
|
1756
|
+
for (const v2 of views) {
|
|
1757
|
+
const last = out[out.length - 1];
|
|
1758
|
+
if (last && last.fixed !== void 0 && v2.fixed !== void 0) {
|
|
1759
|
+
out[out.length - 1] = rebuildFixed(last.fixed + v2.fixed);
|
|
1760
|
+
} else {
|
|
1761
|
+
out.push(v2);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
return out;
|
|
1765
|
+
}
|
|
1766
|
+
function templateMatchesValue(value, views) {
|
|
1767
|
+
let pos = 0;
|
|
1768
|
+
for (let i = 0; i < views.length; i++) {
|
|
1769
|
+
const v2 = views[i];
|
|
1770
|
+
if (v2.fixed !== void 0) {
|
|
1771
|
+
if (!value.startsWith(v2.fixed, pos)) return false;
|
|
1772
|
+
pos += v2.fixed.length;
|
|
1773
|
+
} else {
|
|
1774
|
+
if (i === views.length - 1) return true;
|
|
1775
|
+
const next = views[i + 1];
|
|
1776
|
+
if (next?.fixed !== void 0) {
|
|
1777
|
+
const idx = value.indexOf(next.fixed, pos);
|
|
1778
|
+
if (idx === -1) return false;
|
|
1779
|
+
pos = idx;
|
|
1780
|
+
} else {
|
|
1781
|
+
return true;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return pos === value.length;
|
|
1786
|
+
}
|
|
1787
|
+
function decideStartsWith(prefix, search) {
|
|
1788
|
+
if (prefix.length >= search.length) return prefix.startsWith(search);
|
|
1789
|
+
if (search.startsWith(prefix)) return "unknown";
|
|
1790
|
+
return false;
|
|
1791
|
+
}
|
|
1792
|
+
function decideEndsWith(suffix, search) {
|
|
1793
|
+
if (suffix.length >= search.length) return suffix.endsWith(search);
|
|
1794
|
+
if (search.endsWith(suffix)) return "unknown";
|
|
1795
|
+
return false;
|
|
1796
|
+
}
|
|
1797
|
+
function decideIncludes(fixedText, search) {
|
|
1798
|
+
return fixedText.includes(search) ? true : "unknown";
|
|
1799
|
+
}
|
|
1800
|
+
function isStrLit(a) {
|
|
1801
|
+
return a.shape.k === "prim" && a.shape.type === "string" && a.term?.op === "lit" && typeof a.term.value === "string";
|
|
1802
|
+
}
|
|
1803
|
+
function isStrPrim2(a) {
|
|
1804
|
+
return a.shape.k === "prim" && a.shape.type === "string";
|
|
1805
|
+
}
|
|
1806
|
+
function isTemplateAbs(a) {
|
|
1807
|
+
return a.shape.k === "prim" && a.shape.type === "string" && !!a.pred && a.pred.name?.startsWith("`") === true && Array.isArray(a.pred.meta?.templateParts);
|
|
1808
|
+
}
|
|
1809
|
+
function describeAbsPart(p) {
|
|
1810
|
+
if (isStrLit(p)) return { fixed: String(litValue(p)) };
|
|
1811
|
+
return { render: p.term ? termToString(p.term) : "string" };
|
|
1812
|
+
}
|
|
1813
|
+
function absTemplateViews(parts) {
|
|
1814
|
+
return viewTemplateParts(parts, describeAbsPart);
|
|
1815
|
+
}
|
|
1816
|
+
function templatePartsOf(a) {
|
|
1817
|
+
if (isTemplateAbs(a)) {
|
|
1818
|
+
const meta = a.pred.meta;
|
|
1819
|
+
return meta.templateParts;
|
|
1820
|
+
}
|
|
1821
|
+
return [a];
|
|
1097
1822
|
}
|
|
1098
|
-
function
|
|
1099
|
-
const members = flattenSum([a, b]);
|
|
1100
|
-
if (members.length === 1) return members[0];
|
|
1823
|
+
function rebuildAbsFixedView(text) {
|
|
1101
1824
|
return {
|
|
1102
|
-
|
|
1103
|
-
|
|
1825
|
+
fixed: text,
|
|
1826
|
+
render: text,
|
|
1827
|
+
part: abs({ k: "prim", type: "string" }, lit(text), void 0, "exact")
|
|
1104
1828
|
};
|
|
1105
1829
|
}
|
|
1106
|
-
function
|
|
1107
|
-
|
|
1108
|
-
for (const x of xs) {
|
|
1109
|
-
if (x.shape.k === "sum") out.push(...x.shape.members);
|
|
1110
|
-
else out.push(x);
|
|
1111
|
-
}
|
|
1112
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1113
|
-
const deduped = [];
|
|
1114
|
-
for (const x of out) {
|
|
1115
|
-
const key = absShapeKey(x);
|
|
1116
|
-
if (seen.has(key)) continue;
|
|
1117
|
-
seen.add(key);
|
|
1118
|
-
deduped.push(x);
|
|
1119
|
-
}
|
|
1120
|
-
return deduped;
|
|
1830
|
+
function normalizeParts(parts) {
|
|
1831
|
+
return mergeAdjacentFixedViews(absTemplateViews(parts), rebuildAbsFixedView).map((v2) => v2.part);
|
|
1121
1832
|
}
|
|
1122
|
-
function
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
|
|
1132
|
-
return `prim:${s.type}:${t}:${p}`;
|
|
1133
|
-
}
|
|
1134
|
-
if (s.k === "never") return "never";
|
|
1135
|
-
if (s.k === "any") return "any";
|
|
1136
|
-
if (s.k === "unknown") return "unknown";
|
|
1137
|
-
if (s.k === "arr") return `arr(${absShapeKey(s.element, seen)})`;
|
|
1138
|
-
if (s.k === "tuple") {
|
|
1139
|
-
const els = s.elements.map((e) => absShapeKey(e, seen)).join(",");
|
|
1140
|
-
const rest = s.rest ? `...${absShapeKey(s.rest, seen)}` : "";
|
|
1141
|
-
return `tuple[${els}${rest}]`;
|
|
1142
|
-
}
|
|
1143
|
-
if (s.k === "brand") return `brand:${s.name}(${absShapeKey(s.shape, seen)})`;
|
|
1144
|
-
if (s.k === "eff") return `eff:${s.eff}<${absShapeKey(s.inner, seen)}>`;
|
|
1145
|
-
if (s.k === "obj") {
|
|
1146
|
-
const slots = Object.keys(s.slots).sort().map((k) => {
|
|
1147
|
-
const slot = s.slots[k];
|
|
1148
|
-
const flags = (slot.optional ? "?" : "") + (slot.readonly ? "r" : "");
|
|
1149
|
-
return `${k}${flags}:${absShapeKey(slot.value, seen)}`;
|
|
1150
|
-
}).join(",");
|
|
1151
|
-
const idx = s.index ? `idx(${absShapeKey(s.index.key, seen)}\u2192${absShapeKey(s.index.value, seen)})` : "";
|
|
1152
|
-
const open = s.open ? "open" : "";
|
|
1153
|
-
return `obj{${slots}}${idx}${open}`;
|
|
1154
|
-
}
|
|
1155
|
-
if (s.k === "fn") {
|
|
1156
|
-
const pts = (s.paramTypes ?? []).map((t) => absShapeKey(t, seen)).join(",");
|
|
1157
|
-
const ret = s.returnType ? absShapeKey(s.returnType, seen) : "?";
|
|
1158
|
-
const name = s.name ? `#${s.name}` : "";
|
|
1159
|
-
return `fn${name}(${s.params.join(",")}|${pts})=>${ret}`;
|
|
1160
|
-
}
|
|
1161
|
-
if (s.k === "sum") {
|
|
1162
|
-
return `sum(${s.members.map((m) => absShapeKey(m, seen)).join("|")})`;
|
|
1163
|
-
}
|
|
1164
|
-
return "other";
|
|
1165
|
-
} finally {
|
|
1166
|
-
seen.delete(a);
|
|
1833
|
+
function formatTemplateName(parts) {
|
|
1834
|
+
return formatTemplateNameViews(absTemplateViews(parts));
|
|
1835
|
+
}
|
|
1836
|
+
function createTemplateAbs(parts) {
|
|
1837
|
+
const normalized = normalizeParts(parts);
|
|
1838
|
+
if (normalized.length === 1) {
|
|
1839
|
+
const only = normalized[0];
|
|
1840
|
+
if (isStrLit(only)) return only;
|
|
1841
|
+
if (isStrPrim2(only) && !isTemplateAbs(only)) return only;
|
|
1167
1842
|
}
|
|
1843
|
+
const name = formatTemplateName(normalized);
|
|
1844
|
+
const predObj = {
|
|
1845
|
+
op: "true",
|
|
1846
|
+
name,
|
|
1847
|
+
meta: { templateParts: normalized }
|
|
1848
|
+
};
|
|
1849
|
+
return {
|
|
1850
|
+
shape: { k: "prim", type: "string" },
|
|
1851
|
+
term: void 0,
|
|
1852
|
+
pred: predObj,
|
|
1853
|
+
conf: "path"
|
|
1854
|
+
};
|
|
1168
1855
|
}
|
|
1169
|
-
function
|
|
1170
|
-
|
|
1171
|
-
if (name) shape.name = name;
|
|
1172
|
-
return { shape, conf: "exact" };
|
|
1856
|
+
function isTemplateLike(a) {
|
|
1857
|
+
return isTemplateAbs(a);
|
|
1173
1858
|
}
|
|
1174
|
-
function
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
return a;
|
|
1183
|
-
}
|
|
1859
|
+
function concatString(a, b) {
|
|
1860
|
+
if (isStrLit(a) && isStrLit(b)) {
|
|
1861
|
+
return abs(
|
|
1862
|
+
{ k: "prim", type: "string" },
|
|
1863
|
+
lit(String(litValue(a)) + String(litValue(b))),
|
|
1864
|
+
void 0,
|
|
1865
|
+
"exact"
|
|
1866
|
+
);
|
|
1184
1867
|
}
|
|
1185
|
-
|
|
1868
|
+
const aParts = coerceToStringParts(a);
|
|
1869
|
+
const bParts = coerceToStringParts(b);
|
|
1870
|
+
if (!aParts || !bParts) return abs({ k: "unknown" }, void 0, void 0, "partial");
|
|
1871
|
+
return createTemplateAbs([...aParts, ...bParts]);
|
|
1186
1872
|
}
|
|
1187
|
-
function
|
|
1188
|
-
if (a
|
|
1189
|
-
if (
|
|
1190
|
-
|
|
1191
|
-
if (
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1873
|
+
function coerceToStringParts(a) {
|
|
1874
|
+
if (isTemplateAbs(a) || isStrPrim2(a)) return templatePartsOf(a);
|
|
1875
|
+
if (isStrLit(a)) return [a];
|
|
1876
|
+
const lv = litValue(a);
|
|
1877
|
+
if (typeof lv === "number" || typeof lv === "boolean") {
|
|
1878
|
+
return [abs({ k: "prim", type: "string" }, lit(String(lv)), void 0, "exact")];
|
|
1879
|
+
}
|
|
1880
|
+
if (a.shape.k === "prim" && a.shape.type === "number") {
|
|
1881
|
+
return [a];
|
|
1882
|
+
}
|
|
1883
|
+
return void 0;
|
|
1195
1884
|
}
|
|
1196
1885
|
|
|
1197
1886
|
// src/algebra/arithmetic.ts
|
|
@@ -1877,9 +2566,9 @@ function definitelyNotNullishShape(s) {
|
|
|
1877
2566
|
}
|
|
1878
2567
|
}
|
|
1879
2568
|
function isNullishLitAbs(a) {
|
|
1880
|
-
const
|
|
1881
|
-
if (
|
|
1882
|
-
return
|
|
2569
|
+
const t = a.term;
|
|
2570
|
+
if (!t || t.op !== "lit") return false;
|
|
2571
|
+
return t.value === null || t.value === void 0;
|
|
1883
2572
|
}
|
|
1884
2573
|
function strictEqAbs(a, b) {
|
|
1885
2574
|
const va = litValue(a);
|
|
@@ -1894,6 +2583,26 @@ function strictEqAbs(a, b) {
|
|
|
1894
2583
|
}
|
|
1895
2584
|
return void 0;
|
|
1896
2585
|
}
|
|
2586
|
+
function abstractEq(x, y) {
|
|
2587
|
+
if (x === y) return true;
|
|
2588
|
+
if (x === null && y === void 0) return true;
|
|
2589
|
+
if (x === void 0 && y === null) return true;
|
|
2590
|
+
if (typeof x === "number" && Number.isNaN(x)) return false;
|
|
2591
|
+
if (typeof y === "number" && Number.isNaN(y)) return false;
|
|
2592
|
+
if (typeof x === "boolean") return abstractEq(x ? 1 : 0, y);
|
|
2593
|
+
if (typeof y === "boolean") return abstractEq(x, y ? 1 : 0);
|
|
2594
|
+
if (typeof x === "number" && typeof y === "string") return x === Number(y);
|
|
2595
|
+
if (typeof x === "string" && typeof y === "number") return Number(x) === y;
|
|
2596
|
+
return false;
|
|
2597
|
+
}
|
|
2598
|
+
function looseEqAbs(a, b) {
|
|
2599
|
+
const ta = a.term;
|
|
2600
|
+
const tb = b.term;
|
|
2601
|
+
if (ta?.op === "lit" && tb?.op === "lit") {
|
|
2602
|
+
return abstractEq(ta.value, tb.value);
|
|
2603
|
+
}
|
|
2604
|
+
return strictEqAbs(a, b);
|
|
2605
|
+
}
|
|
1897
2606
|
|
|
1898
2607
|
// src/algebra/containers.ts
|
|
1899
2608
|
var TUPLE_LITERAL_CAP = 8;
|
|
@@ -2115,6 +2824,13 @@ function leqWithPred(src, tgt, phi2, env, depth) {
|
|
|
2115
2824
|
const tv = litValue(tgt);
|
|
2116
2825
|
if (sv !== void 0 && tv !== void 0) {
|
|
2117
2826
|
if (sv === tv) return ok();
|
|
2827
|
+
if (tgt.shape.k === "prim") {
|
|
2828
|
+
return fail(`lit ${String(sv)} \u22AD lit ${String(tv)}`);
|
|
2829
|
+
}
|
|
2830
|
+
} else if (tv !== void 0 && sv === void 0) {
|
|
2831
|
+
if (tgt.shape.k === "prim") {
|
|
2832
|
+
return fail(`non-lit prim \u22AD lit ${String(tv)}`);
|
|
2833
|
+
}
|
|
2118
2834
|
}
|
|
2119
2835
|
const shapeR = leqShape(src, tgt, phi2, env, depth);
|
|
2120
2836
|
if (!shapeR.ok) return shapeR;
|
|
@@ -2215,6 +2931,11 @@ function leqShape(src, tgt, phi2, env, depth) {
|
|
|
2215
2931
|
if (srcSlot.optional && !slot.optional) {
|
|
2216
2932
|
return fail(`slot ${key}: optional \u22AD required`);
|
|
2217
2933
|
}
|
|
2934
|
+
const ssv = litValue(srcSlot.value);
|
|
2935
|
+
const stv = litValue(slot.value);
|
|
2936
|
+
if (ssv !== void 0 && stv !== void 0 && primOf(srcSlot.value) !== void 0 && primOf(srcSlot.value) === primOf(slot.value)) {
|
|
2937
|
+
continue;
|
|
2938
|
+
}
|
|
2218
2939
|
const r = leqWithPred(srcSlot.value, slot.value, phi2, env, depth + 1);
|
|
2219
2940
|
if (!r.ok) return fail(`slot ${key}: ${r.reason}`);
|
|
2220
2941
|
}
|
|
@@ -2481,6 +3202,10 @@ function evalArrayStatic(name, args) {
|
|
|
2481
3202
|
return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
|
|
2482
3203
|
case "from": {
|
|
2483
3204
|
if (!a0) return unknown;
|
|
3205
|
+
if (isSetAbs(a0) || isMapAbs(a0)) {
|
|
3206
|
+
const el = collectionElementJoin(a0);
|
|
3207
|
+
return abs({ k: "arr", element: el }, void 0, void 0, "path");
|
|
3208
|
+
}
|
|
2484
3209
|
const k = a0.shape.k;
|
|
2485
3210
|
if (k === "arr") return a0;
|
|
2486
3211
|
if (k === "tuple") {
|
|
@@ -2599,6 +3324,35 @@ function evalNamespaceCall(ns, method, args) {
|
|
|
2599
3324
|
return void 0;
|
|
2600
3325
|
}
|
|
2601
3326
|
}
|
|
3327
|
+
var ERROR_CTOR_NAMES = /* @__PURE__ */ new Set([
|
|
3328
|
+
"Error",
|
|
3329
|
+
"TypeError",
|
|
3330
|
+
"RangeError",
|
|
3331
|
+
"SyntaxError",
|
|
3332
|
+
"ReferenceError",
|
|
3333
|
+
"URIError",
|
|
3334
|
+
"EvalError",
|
|
3335
|
+
"AggregateError"
|
|
3336
|
+
]);
|
|
3337
|
+
function isErrorCtorName(name) {
|
|
3338
|
+
return !!name && ERROR_CTOR_NAMES.has(name);
|
|
3339
|
+
}
|
|
3340
|
+
function errorBrandAbs(name, messageArg) {
|
|
3341
|
+
const message = messageArg ?? strPrim();
|
|
3342
|
+
return abs(
|
|
3343
|
+
{
|
|
3344
|
+
k: "brand",
|
|
3345
|
+
name,
|
|
3346
|
+
shape: objOf({
|
|
3347
|
+
name: { value: strLit(name) },
|
|
3348
|
+
message: { value: message }
|
|
3349
|
+
})
|
|
3350
|
+
},
|
|
3351
|
+
void 0,
|
|
3352
|
+
void 0,
|
|
3353
|
+
"path"
|
|
3354
|
+
);
|
|
3355
|
+
}
|
|
2602
3356
|
function evalBuiltinNew(className, args) {
|
|
2603
3357
|
switch (className) {
|
|
2604
3358
|
case "Date":
|
|
@@ -2608,20 +3362,13 @@ function evalBuiltinNew(className, args) {
|
|
|
2608
3362
|
case "Promise":
|
|
2609
3363
|
return evalPromiseCtor(args);
|
|
2610
3364
|
case "Map":
|
|
2611
|
-
return
|
|
2612
|
-
{ k: "brand", name: "Map", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
|
|
2613
|
-
void 0,
|
|
2614
|
-
void 0,
|
|
2615
|
-
"path"
|
|
2616
|
-
);
|
|
3365
|
+
return makeMapAbs(args[0]);
|
|
2617
3366
|
case "Set":
|
|
2618
|
-
return
|
|
2619
|
-
{ k: "brand", name: "Set", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
|
|
2620
|
-
void 0,
|
|
2621
|
-
void 0,
|
|
2622
|
-
"path"
|
|
2623
|
-
);
|
|
3367
|
+
return makeSetAbs(args[0]);
|
|
2624
3368
|
default:
|
|
3369
|
+
if (isErrorCtorName(className)) {
|
|
3370
|
+
return errorBrandAbs(className, args[0]);
|
|
3371
|
+
}
|
|
2625
3372
|
return void 0;
|
|
2626
3373
|
}
|
|
2627
3374
|
}
|
|
@@ -2631,13 +3378,17 @@ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
|
|
|
2631
3378
|
if (brandName === "Map") {
|
|
2632
3379
|
switch (method) {
|
|
2633
3380
|
case "get":
|
|
2634
|
-
return
|
|
3381
|
+
return mapGetEntry(recv, args[0]);
|
|
2635
3382
|
case "has":
|
|
2636
|
-
return
|
|
3383
|
+
return mapHasEntry(recv, args[0]);
|
|
2637
3384
|
case "set":
|
|
2638
|
-
return recv;
|
|
3385
|
+
return mapSetEntry(recv, args[0], args[1] ?? unknown);
|
|
3386
|
+
case "delete":
|
|
3387
|
+
return mapDeleteEntry(recv, args[0]);
|
|
3388
|
+
case "clear":
|
|
3389
|
+
return mapClearEntries(recv);
|
|
2639
3390
|
case "size":
|
|
2640
|
-
return
|
|
3391
|
+
return mapSizeAbs(recv);
|
|
2641
3392
|
default:
|
|
2642
3393
|
return void 0;
|
|
2643
3394
|
}
|
|
@@ -2645,11 +3396,15 @@ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
|
|
|
2645
3396
|
if (brandName === "Set") {
|
|
2646
3397
|
switch (method) {
|
|
2647
3398
|
case "has":
|
|
2648
|
-
return
|
|
3399
|
+
return setHasEntry(recv, args[0]);
|
|
2649
3400
|
case "add":
|
|
2650
|
-
return recv;
|
|
3401
|
+
return setAddEntry(recv, args[0] ?? unknown);
|
|
3402
|
+
case "delete":
|
|
3403
|
+
return setDeleteEntry(recv, args[0]);
|
|
3404
|
+
case "clear":
|
|
3405
|
+
return setClearEntries(recv);
|
|
2651
3406
|
case "size":
|
|
2652
|
-
return
|
|
3407
|
+
return setSizeAbs(recv);
|
|
2653
3408
|
default:
|
|
2654
3409
|
return void 0;
|
|
2655
3410
|
}
|
|
@@ -2663,11 +3418,15 @@ __export(calls_exports, {
|
|
|
2663
3418
|
$callNamed: () => $callNamed,
|
|
2664
3419
|
getAbsOrigin: () => getAbsOrigin,
|
|
2665
3420
|
getBCallCollector: () => getBCallCollector,
|
|
3421
|
+
isEvalMissingSlotEnabled: () => isEvalMissingSlotEnabled,
|
|
2666
3422
|
noteMemberDispatchMiss: () => noteMemberDispatchMiss,
|
|
3423
|
+
noteObjSlotMissing: () => noteObjSlotMissing,
|
|
2667
3424
|
notePrimMemberMissing: () => notePrimMemberMissing,
|
|
2668
3425
|
noteUnknownMemberMissing: () => noteUnknownMemberMissing,
|
|
2669
3426
|
recordMemberDiag: () => recordMemberDiag,
|
|
3427
|
+
runWithEvalMissingSlot: () => runWithEvalMissingSlot,
|
|
2670
3428
|
setBCallCollector: () => setBCallCollector,
|
|
3429
|
+
setEvalMissingSlotEnabled: () => setEvalMissingSlotEnabled,
|
|
2671
3430
|
setMemberDiagCollector: () => setMemberDiagCollector,
|
|
2672
3431
|
tagAbsOrigin: () => tagAbsOrigin
|
|
2673
3432
|
});
|
|
@@ -3394,6 +4153,19 @@ function setApplyCallbackHost(fn) {
|
|
|
3394
4153
|
applyCallbackHost = fn;
|
|
3395
4154
|
}
|
|
3396
4155
|
function applyCallbackAbs(cb, args, env, phi2, budget) {
|
|
4156
|
+
const sumIdx = args.findIndex(
|
|
4157
|
+
(a) => a && typeof a === "object" && "shape" in a && a.shape.k === "sum"
|
|
4158
|
+
);
|
|
4159
|
+
if (sumIdx >= 0) {
|
|
4160
|
+
const members = args[sumIdx].shape.members;
|
|
4161
|
+
let acc;
|
|
4162
|
+
for (const m of members) {
|
|
4163
|
+
const nextArgs = args.map((a, i) => i === sumIdx ? m : a);
|
|
4164
|
+
const r = applyCallbackAbs(cb, nextArgs, env, phi2, budget);
|
|
4165
|
+
acc = acc === void 0 ? r : joinAbs(acc, r);
|
|
4166
|
+
}
|
|
4167
|
+
return acc ?? unknown;
|
|
4168
|
+
}
|
|
3397
4169
|
if (!applyCallbackHost) {
|
|
3398
4170
|
if (cb && typeof cb === "object" && "shape" in cb) {
|
|
3399
4171
|
const a = cb;
|
|
@@ -3405,7 +4177,7 @@ function applyCallbackAbs(cb, args, env, phi2, budget) {
|
|
|
3405
4177
|
}
|
|
3406
4178
|
return applyCallbackHost(cb, args, env, phi2, budget);
|
|
3407
4179
|
}
|
|
3408
|
-
function
|
|
4180
|
+
function undefAbs2() {
|
|
3409
4181
|
return abs(
|
|
3410
4182
|
{ k: "unknown" },
|
|
3411
4183
|
{ op: "lit", value: void 0 },
|
|
@@ -3585,6 +4357,7 @@ function getAbsProperty(recv, name) {
|
|
|
3585
4357
|
}
|
|
3586
4358
|
|
|
3587
4359
|
// src/algebra/exec/member-diag.ts
|
|
4360
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
3588
4361
|
var memberDiagCollector = null;
|
|
3589
4362
|
var callLocStack = [];
|
|
3590
4363
|
var absOrigins = /* @__PURE__ */ new WeakMap();
|
|
@@ -3684,7 +4457,41 @@ function noteUnknownMemberMissing(recv, name, kind, loc) {
|
|
|
3684
4457
|
}
|
|
3685
4458
|
function noteMemberDispatchMiss(recv, name, kind, loc) {
|
|
3686
4459
|
if (notePrimMemberMissing(recv, name, kind, loc)) return;
|
|
3687
|
-
noteUnknownMemberMissing(recv, name, kind, loc);
|
|
4460
|
+
if (noteUnknownMemberMissing(recv, name, kind, loc)) return;
|
|
4461
|
+
noteObjSlotMissing(recv, name, loc);
|
|
4462
|
+
}
|
|
4463
|
+
var evalMissingSlotAls = new AsyncLocalStorage();
|
|
4464
|
+
var evalMissingSlotFallback = false;
|
|
4465
|
+
function setEvalMissingSlotEnabled(enabled) {
|
|
4466
|
+
evalMissingSlotFallback = enabled;
|
|
4467
|
+
evalMissingSlotAls.enterWith(enabled);
|
|
4468
|
+
}
|
|
4469
|
+
function isEvalMissingSlotEnabled() {
|
|
4470
|
+
return evalMissingSlotAls.getStore() ?? evalMissingSlotFallback;
|
|
4471
|
+
}
|
|
4472
|
+
function runWithEvalMissingSlot(enabled, body) {
|
|
4473
|
+
return evalMissingSlotAls.run(enabled, body);
|
|
4474
|
+
}
|
|
4475
|
+
function noteObjSlotMissing(recv, name, loc) {
|
|
4476
|
+
if (!isEvalMissingSlotEnabled()) return false;
|
|
4477
|
+
const shape = recv?.shape;
|
|
4478
|
+
if (!shape || shape.k !== "obj") return false;
|
|
4479
|
+
const obj2 = shape;
|
|
4480
|
+
if (obj2.open) return false;
|
|
4481
|
+
if (obj2.slots && name in obj2.slots) return false;
|
|
4482
|
+
const conf = recv?.conf;
|
|
4483
|
+
if (conf === "opaque" || conf === "widened") return false;
|
|
4484
|
+
const origin = getAbsOrigin(recv);
|
|
4485
|
+
recordMemberDiag({
|
|
4486
|
+
kind: "property",
|
|
4487
|
+
name,
|
|
4488
|
+
receiver: "object",
|
|
4489
|
+
code: "nudo:missing-slot",
|
|
4490
|
+
line: loc?.[0],
|
|
4491
|
+
column: loc?.[1],
|
|
4492
|
+
...origin ? { origin } : {}
|
|
4493
|
+
});
|
|
4494
|
+
return true;
|
|
3688
4495
|
}
|
|
3689
4496
|
|
|
3690
4497
|
// src/algebra/exec/class-registry.ts
|
|
@@ -3809,6 +4616,28 @@ function withVar(env, name, value) {
|
|
|
3809
4616
|
vars.set(name, value);
|
|
3810
4617
|
return { vars, fns: env.fns, classes: env.classes, hofCollect: env.hofCollect };
|
|
3811
4618
|
}
|
|
4619
|
+
function joinEnvs(a, b, base) {
|
|
4620
|
+
const vars = new Map(base.vars);
|
|
4621
|
+
const keys = /* @__PURE__ */ new Set([...a.vars.keys(), ...b.vars.keys()]);
|
|
4622
|
+
for (const k of keys) {
|
|
4623
|
+
const va = a.vars.get(k);
|
|
4624
|
+
const vb = b.vars.get(k);
|
|
4625
|
+
const baseV = base.vars.get(k);
|
|
4626
|
+
if (va !== void 0 && vb !== void 0) {
|
|
4627
|
+
vars.set(k, va === vb ? va : joinAbs(va, vb));
|
|
4628
|
+
} else if (va !== void 0) {
|
|
4629
|
+
vars.set(k, baseV !== void 0 ? joinAbs(baseV, va) : va);
|
|
4630
|
+
} else if (vb !== void 0) {
|
|
4631
|
+
vars.set(k, baseV !== void 0 ? joinAbs(baseV, vb) : vb);
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
return {
|
|
4635
|
+
vars,
|
|
4636
|
+
fns: a.fns ?? b.fns,
|
|
4637
|
+
classes: a.classes ?? b.classes,
|
|
4638
|
+
hofCollect: a.hofCollect ?? b.hofCollect
|
|
4639
|
+
};
|
|
4640
|
+
}
|
|
3812
4641
|
var MAX_CALL_DEPTH = 64;
|
|
3813
4642
|
var MAX_TOTAL_CALLS = 2e5;
|
|
3814
4643
|
var _absCallDepth = 0;
|
|
@@ -4169,8 +4998,66 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4169
4998
|
}
|
|
4170
4999
|
case "AssignmentExpression": {
|
|
4171
5000
|
const ae = node;
|
|
4172
|
-
|
|
4173
|
-
const
|
|
5001
|
+
const op = ae.operator;
|
|
5002
|
+
const applyBin = (binOp, lhs, rhsAbs) => {
|
|
5003
|
+
switch (binOp) {
|
|
5004
|
+
case "+":
|
|
5005
|
+
return leakIfNeeded(add(lhs, rhsAbs, phi2), budget, "add");
|
|
5006
|
+
case "-":
|
|
5007
|
+
return leakIfNeeded(sub(lhs, rhsAbs, phi2), budget, "sub");
|
|
5008
|
+
case "*":
|
|
5009
|
+
return leakIfNeeded(mul(lhs, rhsAbs, phi2), budget, "mul");
|
|
5010
|
+
case "/":
|
|
5011
|
+
return leakIfNeeded(div(lhs, rhsAbs, phi2), budget, "div");
|
|
5012
|
+
case "%":
|
|
5013
|
+
return leakIfNeeded(mod(lhs, rhsAbs, phi2), budget, "mod");
|
|
5014
|
+
default:
|
|
5015
|
+
return unknown;
|
|
5016
|
+
}
|
|
5017
|
+
};
|
|
5018
|
+
let rhs;
|
|
5019
|
+
if (op === "=") {
|
|
5020
|
+
rhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5021
|
+
} else if (op === "||=" || op === "&&=" || op === "??=") {
|
|
5022
|
+
const lhs = evalNode(ae.left, env, phi2, budget).value;
|
|
5023
|
+
const lv = litValue(lhs);
|
|
5024
|
+
const nullishLit = isNullishLitAbs(lhs);
|
|
5025
|
+
const definitelyNotNullish = definitelyNotNullishShape(lhs.shape) && !nullishLit;
|
|
5026
|
+
const falsy = lv === false || nullishLit || lv === null || lv === void 0 && lhs.term?.op === "lit" && lhs.term.value === void 0;
|
|
5027
|
+
const truthy = lv !== void 0 && !falsy && !nullishLit;
|
|
5028
|
+
let assignRhs = null;
|
|
5029
|
+
if (op === "||=") {
|
|
5030
|
+
if (truthy) return ok2(lhs, phi2, env);
|
|
5031
|
+
if (falsy || nullishLit) {
|
|
5032
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5033
|
+
}
|
|
5034
|
+
} else if (op === "&&=") {
|
|
5035
|
+
if (falsy) return ok2(lhs, phi2, env);
|
|
5036
|
+
if (truthy) {
|
|
5037
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5038
|
+
}
|
|
5039
|
+
} else {
|
|
5040
|
+
if (definitelyNotNullish || lv !== void 0 && lv !== null && !nullishLit) {
|
|
5041
|
+
return ok2(lhs, phi2, env);
|
|
5042
|
+
}
|
|
5043
|
+
if (nullishLit || lv === null || lv === void 0 && lhs.term?.op === "lit") {
|
|
5044
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5045
|
+
}
|
|
5046
|
+
}
|
|
5047
|
+
if (assignRhs === null) {
|
|
5048
|
+
const r = evalNode(ae.right, env, phi2, budget).value;
|
|
5049
|
+
rhs = joinAbs(lhs, r);
|
|
5050
|
+
} else {
|
|
5051
|
+
rhs = assignRhs;
|
|
5052
|
+
}
|
|
5053
|
+
} else if (op.endsWith("=")) {
|
|
5054
|
+
const binOp = op.slice(0, -1);
|
|
5055
|
+
const lhs = evalNode(ae.left, env, phi2, budget).value;
|
|
5056
|
+
const rhsVal = evalNode(ae.right, env, phi2, budget).value;
|
|
5057
|
+
rhs = applyBin(binOp, lhs, rhsVal);
|
|
5058
|
+
} else {
|
|
5059
|
+
return ok2(unknown, phi2, env);
|
|
5060
|
+
}
|
|
4174
5061
|
if (ae.left.type === "MemberExpression" && ae.left.object.type === "ThisExpression") {
|
|
4175
5062
|
const prop = ae.left.property;
|
|
4176
5063
|
const key = !ae.left.computed && prop.type === "Identifier" ? prop.name : prop.type === "StringLiteral" ? prop.value : void 0;
|
|
@@ -4204,6 +5091,25 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4204
5091
|
recordAbsAssign(name, prev, rhs, loc);
|
|
4205
5092
|
return { value: rhs, phi: phi2, env: withVar(env, name, rhs) };
|
|
4206
5093
|
}
|
|
5094
|
+
if (ae.left.type === "MemberExpression") {
|
|
5095
|
+
const m = ae.left;
|
|
5096
|
+
if (m.object.type === "Identifier") {
|
|
5097
|
+
const root = m.object.name;
|
|
5098
|
+
const prev = env.vars.get(root);
|
|
5099
|
+
const key = !m.computed ? m.property.type === "Identifier" ? m.property.name : m.property.type === "StringLiteral" ? m.property.value : void 0 : void 0;
|
|
5100
|
+
if (prev && key && prev.shape.k === "obj") {
|
|
5101
|
+
const slots = { ...prev.shape.slots };
|
|
5102
|
+
slots[key] = { value: rhs };
|
|
5103
|
+
const updated = abs(
|
|
5104
|
+
{ k: "obj", slots },
|
|
5105
|
+
void 0,
|
|
5106
|
+
void 0,
|
|
5107
|
+
prev.conf === "exact" ? "path" : prev.conf
|
|
5108
|
+
);
|
|
5109
|
+
return { value: rhs, phi: phi2, env: withVar(env, root, updated) };
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
}
|
|
4207
5113
|
return ok2(rhs, phi2, env);
|
|
4208
5114
|
}
|
|
4209
5115
|
case "AwaitExpression": {
|
|
@@ -4233,7 +5139,7 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4233
5139
|
if (tv === false) return evalNode(cond.alternate, env, phi2, budget);
|
|
4234
5140
|
const a = evalNode(cond.consequent, env, phi2, budget);
|
|
4235
5141
|
const b = evalNode(cond.alternate, env, phi2, budget);
|
|
4236
|
-
return { value: joinAbs(a.value, b.value), phi: phi2, env };
|
|
5142
|
+
return { value: joinAbs(a.value, b.value), phi: phi2, env: joinEnvs(a.env, b.env, env) };
|
|
4237
5143
|
}
|
|
4238
5144
|
case "ForStatement":
|
|
4239
5145
|
return evalFor(node, env, phi2, budget);
|
|
@@ -4264,6 +5170,8 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4264
5170
|
}
|
|
4265
5171
|
case "IfStatement":
|
|
4266
5172
|
return evalIf(node, env, phi2, budget);
|
|
5173
|
+
case "SwitchStatement":
|
|
5174
|
+
return evalSwitch(node, env, phi2, budget);
|
|
4267
5175
|
case "ExpressionStatement":
|
|
4268
5176
|
return evalNode(node.expression, env, phi2, budget);
|
|
4269
5177
|
case "VariableDeclaration":
|
|
@@ -4285,8 +5193,10 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4285
5193
|
const le3 = node;
|
|
4286
5194
|
const l = evalNode(le3.left, env, phi2, budget);
|
|
4287
5195
|
const lv = litValue(l.value);
|
|
4288
|
-
const
|
|
4289
|
-
const
|
|
5196
|
+
const nullishLit = isNullishLitAbs(l.value);
|
|
5197
|
+
const definitelyNotNullish = definitelyNotNullishShape(l.value.shape) && !nullishLit;
|
|
5198
|
+
const falsy = lv === false || nullishLit || lv === void 0 && l.value.term?.op === "lit" && l.value.term.value === void 0 || lv === null;
|
|
5199
|
+
const truthy = lv !== void 0 && !falsy && !nullishLit;
|
|
4290
5200
|
if (le3.operator === "&&") {
|
|
4291
5201
|
if (falsy) return ok2(l.value, phi2, env);
|
|
4292
5202
|
if (truthy) return evalNode(le3.right, env, phi2, budget);
|
|
@@ -4299,6 +5209,14 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4299
5209
|
const r = evalNode(le3.right, env, phi2, budget);
|
|
4300
5210
|
return ok2(joinAbs(l.value, r.value), phi2, env);
|
|
4301
5211
|
}
|
|
5212
|
+
if (le3.operator === "??") {
|
|
5213
|
+
if (nullishLit || lv === null) return evalNode(le3.right, env, phi2, budget);
|
|
5214
|
+
if (definitelyNotNullish || lv !== void 0 && lv !== null) {
|
|
5215
|
+
return ok2(l.value, phi2, env);
|
|
5216
|
+
}
|
|
5217
|
+
const r = evalNode(le3.right, env, phi2, budget);
|
|
5218
|
+
return ok2(joinAbs(l.value, r.value), phi2, env);
|
|
5219
|
+
}
|
|
4302
5220
|
return ok2(unknown, phi2, env);
|
|
4303
5221
|
}
|
|
4304
5222
|
case "TemplateLiteral": {
|
|
@@ -4388,12 +5306,39 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4388
5306
|
acc = spread(acc, sp);
|
|
4389
5307
|
continue;
|
|
4390
5308
|
}
|
|
4391
|
-
|
|
5309
|
+
if (p.type === "ObjectMethod") {
|
|
5310
|
+
const om = p;
|
|
5311
|
+
const keyNode2 = om.key;
|
|
5312
|
+
let key2;
|
|
5313
|
+
if (keyNode2 && keyNode2.type === "Identifier") key2 = keyNode2.name;
|
|
5314
|
+
if (keyNode2 && keyNode2.type === "StringLiteral") key2 = keyNode2.value;
|
|
5315
|
+
if (!key2 || !om.body) continue;
|
|
5316
|
+
const paramNames = (om.params ?? []).map(
|
|
5317
|
+
(pp, i) => pp.type === "Identifier" ? pp.name : `_a${i}`
|
|
5318
|
+
);
|
|
5319
|
+
const methodBody = om.body;
|
|
5320
|
+
const fnAbs = absFunction(paramNames, {
|
|
5321
|
+
body: methodBody,
|
|
5322
|
+
apply: (args) => {
|
|
5323
|
+
let e2 = env;
|
|
5324
|
+
for (let i = 0; i < paramNames.length; i++) {
|
|
5325
|
+
e2 = withVar(e2, paramNames[i], args[i] ?? unknown);
|
|
5326
|
+
}
|
|
5327
|
+
const r = evalNode(methodBody, e2, phi2, budget);
|
|
5328
|
+
return r.value;
|
|
5329
|
+
}
|
|
5330
|
+
});
|
|
5331
|
+
pending[key2] = { value: fnAbs };
|
|
5332
|
+
continue;
|
|
5333
|
+
}
|
|
5334
|
+
if (p.type !== "ObjectProperty") continue;
|
|
5335
|
+
const op = p;
|
|
5336
|
+
const keyNode = op.key;
|
|
4392
5337
|
let key;
|
|
4393
5338
|
if (keyNode && keyNode.type === "Identifier") key = keyNode.name;
|
|
4394
5339
|
if (keyNode && keyNode.type === "StringLiteral") key = keyNode.value;
|
|
4395
|
-
if (!key || !
|
|
4396
|
-
pending[key] = { value: evalNode(
|
|
5340
|
+
if (!key || !op.value) continue;
|
|
5341
|
+
pending[key] = { value: evalNode(op.value, env, phi2, budget).value };
|
|
4397
5342
|
}
|
|
4398
5343
|
acc = flushPending(acc);
|
|
4399
5344
|
return ok2(acc, phi2, env);
|
|
@@ -4446,6 +5391,16 @@ function evalBinary(node, env, phi2, budget) {
|
|
|
4446
5391
|
if (eq2 !== void 0) return ok2(boolLit(!eq2), phi2, env);
|
|
4447
5392
|
return ok2(cmp("ne", l, r, phi2), phi2, env);
|
|
4448
5393
|
}
|
|
5394
|
+
case "==": {
|
|
5395
|
+
const eq2 = looseEqAbs(l, r);
|
|
5396
|
+
if (eq2 !== void 0) return ok2(boolLit(eq2), phi2, env);
|
|
5397
|
+
return ok2(unknown, phi2, env);
|
|
5398
|
+
}
|
|
5399
|
+
case "!=": {
|
|
5400
|
+
const eq2 = looseEqAbs(l, r);
|
|
5401
|
+
if (eq2 !== void 0) return ok2(boolLit(!eq2), phi2, env);
|
|
5402
|
+
return ok2(unknown, phi2, env);
|
|
5403
|
+
}
|
|
4449
5404
|
case "/":
|
|
4450
5405
|
return ok2(leakIfNeeded(div(l, r, phi2), budget, "div"), phi2, env);
|
|
4451
5406
|
case "%":
|
|
@@ -4737,7 +5692,7 @@ function evalCall(node, env, phi2, budget) {
|
|
|
4737
5692
|
} else if (obj2.shape.k === "arr") {
|
|
4738
5693
|
applyUnaryCallback(fnNode, obj2.shape.element, env, phi2, budget);
|
|
4739
5694
|
}
|
|
4740
|
-
return ok2(
|
|
5695
|
+
return ok2(undefAbs2(), phi2, env);
|
|
4741
5696
|
}
|
|
4742
5697
|
if ((method === "some" || method === "every") && rawArgs.length >= 1) {
|
|
4743
5698
|
const fnNode = rawArgs[0];
|
|
@@ -4754,7 +5709,7 @@ function evalCall(node, env, phi2, budget) {
|
|
|
4754
5709
|
const fnNode = rawArgs[0];
|
|
4755
5710
|
const elem = obj2.shape.k === "arr" ? obj2.shape.element : obj2.shape.k === "tuple" ? obj2.shape.elements[0] ?? unknown : unknown;
|
|
4756
5711
|
applyUnaryCallback(fnNode, elem, env, phi2, budget);
|
|
4757
|
-
return ok2(joinAbs(elem,
|
|
5712
|
+
return ok2(joinAbs(elem, undefAbs2()), phi2, env);
|
|
4758
5713
|
}
|
|
4759
5714
|
{
|
|
4760
5715
|
const loc = node.loc ? [node.loc.start.line, node.loc.start.column] : void 0;
|
|
@@ -4819,7 +5774,16 @@ function applyAbsFn(fnVal, args, env, phi2, budget) {
|
|
|
4819
5774
|
const label = fnVal.shape.name ?? "anonymous";
|
|
4820
5775
|
if (!enterCall(key, label)) return truncatedAbs();
|
|
4821
5776
|
try {
|
|
4822
|
-
if (impl.apply)
|
|
5777
|
+
if (impl.apply) {
|
|
5778
|
+
try {
|
|
5779
|
+
return impl.apply(args);
|
|
5780
|
+
} catch (e) {
|
|
5781
|
+
if (e && typeof e === "object" && e.name === "NudoReturn") {
|
|
5782
|
+
return e.absValue;
|
|
5783
|
+
}
|
|
5784
|
+
throw e;
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
4823
5787
|
const base = impl.env ?? env;
|
|
4824
5788
|
let local = { vars: new Map(base.vars), fns: base.fns, hofCollect: env.hofCollect };
|
|
4825
5789
|
if (base.classes) {
|
|
@@ -4939,18 +5903,29 @@ function evalFor(node, env, phi2, budget) {
|
|
|
4939
5903
|
const r = evalNode(node.init, local, phi2, budget);
|
|
4940
5904
|
local = r.env;
|
|
4941
5905
|
}
|
|
5906
|
+
const entry = local;
|
|
4942
5907
|
let acc = unknown;
|
|
5908
|
+
let exitEnv;
|
|
5909
|
+
let sawAbstractTest = false;
|
|
4943
5910
|
for (let i = 0; i < MAX_LOOP_ITERS; i++) {
|
|
4944
5911
|
if (node.test) {
|
|
4945
5912
|
const t = evalNode(node.test, local, phi2, budget);
|
|
4946
5913
|
const lv = litValue(t.value);
|
|
4947
|
-
if (lv === false || lv === null || lv === void 0)
|
|
5914
|
+
if (lv === false || lv === null || lv === void 0) {
|
|
5915
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5916
|
+
break;
|
|
5917
|
+
}
|
|
5918
|
+
if (lv !== true) {
|
|
5919
|
+
sawAbstractTest = true;
|
|
5920
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5921
|
+
}
|
|
4948
5922
|
}
|
|
4949
5923
|
const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
|
|
4950
5924
|
if (bodyR.returned) return bodyR;
|
|
4951
5925
|
if (bodyR.threw) return bodyR;
|
|
4952
5926
|
if (bodyR.brk) {
|
|
4953
5927
|
local = bodyR.env;
|
|
5928
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
4954
5929
|
break;
|
|
4955
5930
|
}
|
|
4956
5931
|
local = bodyR.env;
|
|
@@ -4960,25 +5935,42 @@ function evalFor(node, env, phi2, budget) {
|
|
|
4960
5935
|
local = u.env;
|
|
4961
5936
|
}
|
|
4962
5937
|
}
|
|
4963
|
-
|
|
5938
|
+
if (sawAbstractTest) {
|
|
5939
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5940
|
+
}
|
|
5941
|
+
return ok2(acc, phi2, exitEnv ?? local);
|
|
4964
5942
|
}
|
|
4965
5943
|
function evalWhile(node, env, phi2, budget) {
|
|
4966
5944
|
let local = env;
|
|
5945
|
+
const entry = local;
|
|
4967
5946
|
let acc = unknown;
|
|
5947
|
+
let exitEnv;
|
|
5948
|
+
let sawAbstractTest = false;
|
|
4968
5949
|
for (let i = 0; i < MAX_LOOP_ITERS; i++) {
|
|
4969
5950
|
const t = evalNode(node.test, local, phi2, budget);
|
|
4970
5951
|
const lv = litValue(t.value);
|
|
4971
|
-
if (lv === false || lv === null || lv === void 0)
|
|
5952
|
+
if (lv === false || lv === null || lv === void 0) {
|
|
5953
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5954
|
+
break;
|
|
5955
|
+
}
|
|
5956
|
+
if (lv !== true) {
|
|
5957
|
+
sawAbstractTest = true;
|
|
5958
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5959
|
+
}
|
|
4972
5960
|
const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
|
|
4973
5961
|
if (bodyR.returned || bodyR.threw) return bodyR;
|
|
4974
5962
|
if (bodyR.brk) {
|
|
4975
5963
|
local = bodyR.env;
|
|
5964
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
4976
5965
|
break;
|
|
4977
5966
|
}
|
|
4978
5967
|
local = bodyR.env;
|
|
4979
5968
|
acc = joinAbs(acc, bodyR.value);
|
|
4980
5969
|
}
|
|
4981
|
-
|
|
5970
|
+
if (sawAbstractTest) {
|
|
5971
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5972
|
+
}
|
|
5973
|
+
return ok2(acc, phi2, exitEnv ?? local);
|
|
4982
5974
|
}
|
|
4983
5975
|
function evalDoWhile(node, env, phi2, budget) {
|
|
4984
5976
|
let local = env;
|
|
@@ -5009,13 +6001,50 @@ function evalForOf(node, env, phi2, budget) {
|
|
|
5009
6001
|
);
|
|
5010
6002
|
if (promoted) iterVal = promoted;
|
|
5011
6003
|
}
|
|
5012
|
-
const
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
6004
|
+
const shape = iterVal.shape;
|
|
6005
|
+
const isTuple = shape.k === "tuple";
|
|
6006
|
+
const isArr = shape.k === "arr";
|
|
6007
|
+
let elements = [];
|
|
6008
|
+
if (isArr) {
|
|
6009
|
+
elements = [shape.element];
|
|
6010
|
+
} else if (isTuple) {
|
|
6011
|
+
elements = [...shape.elements];
|
|
6012
|
+
} else if (shape.k === "sum") {
|
|
6013
|
+
elements = shape.members.flatMap(
|
|
6014
|
+
(m) => m.shape.k === "arr" ? [m.shape.element] : m.shape.k === "tuple" ? [...m.shape.elements] : []
|
|
6015
|
+
);
|
|
6016
|
+
} else {
|
|
6017
|
+
elements = [unknown];
|
|
6018
|
+
}
|
|
5016
6019
|
const left = node.left;
|
|
5017
6020
|
const bindName = left.type === "Identifier" ? left.name : left.type === "VariableDeclaration" ? left.declarations[0]?.id?.name : void 0;
|
|
5018
6021
|
if (!bindName) return ok2(unknown, phi2, env);
|
|
6022
|
+
if (isTuple && elements.length === 0) {
|
|
6023
|
+
return ok2(unknown, phi2, env);
|
|
6024
|
+
}
|
|
6025
|
+
const unbounded = !isTuple;
|
|
6026
|
+
if (unbounded) {
|
|
6027
|
+
let cur = env;
|
|
6028
|
+
let joinedEnv = env;
|
|
6029
|
+
let joinedVal = unknown;
|
|
6030
|
+
const el = elements.length > 0 ? elements[0] : unknown;
|
|
6031
|
+
const n2 = elements.length > 0 || isArr || shape.k === "sum" ? MAX_LOOP_ITERS : 0;
|
|
6032
|
+
for (let i = 0; i < n2; i++) {
|
|
6033
|
+
cur = withVar(cur, bindName, el);
|
|
6034
|
+
const bodyR = evalInConditionalFlow(() => evalNode(node.body, cur, phi2, budget));
|
|
6035
|
+
if (bodyR.returned || bodyR.threw) return bodyR;
|
|
6036
|
+
if (bodyR.brk) {
|
|
6037
|
+
cur = bodyR.env;
|
|
6038
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6039
|
+
break;
|
|
6040
|
+
}
|
|
6041
|
+
cur = bodyR.env;
|
|
6042
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6043
|
+
joinedVal = joinAbs(joinedVal, bodyR.value);
|
|
6044
|
+
}
|
|
6045
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6046
|
+
return ok2(joinedVal, phi2, joinedEnv);
|
|
6047
|
+
}
|
|
5019
6048
|
let local = env;
|
|
5020
6049
|
let acc = unknown;
|
|
5021
6050
|
const n = Math.min(elements.length, MAX_LOOP_ITERS);
|
|
@@ -5053,6 +6082,20 @@ function evalTry(node, env, phi2, budget) {
|
|
|
5053
6082
|
if (node.finalizer) evalNode(node.finalizer, local, curPhi, budget);
|
|
5054
6083
|
return { value: catchR.value, phi: curPhi, env: local, threw: true };
|
|
5055
6084
|
}
|
|
6085
|
+
} else if (tryR.partialThrow && node.handler) {
|
|
6086
|
+
const param = node.handler.param && node.handler.param.type === "Identifier" ? node.handler.param.name : void 0;
|
|
6087
|
+
let catchEnv = env;
|
|
6088
|
+
if (param) catchEnv = withVar(env, param, tryR.throwValue ?? tryR.value);
|
|
6089
|
+
const catchR = evalNode(node.handler.body, catchEnv, phi2, budget);
|
|
6090
|
+
value = joinAbs(tryR.value, catchR.value);
|
|
6091
|
+
local = joinEnvs(tryR.env, catchR.env, env);
|
|
6092
|
+
curPhi = catchR.phi;
|
|
6093
|
+
if (catchR.returned && tryR.returned) {
|
|
6094
|
+
return { value, phi: curPhi, env: local, returned: true };
|
|
6095
|
+
}
|
|
6096
|
+
if (catchR.threw && tryR.threw) {
|
|
6097
|
+
return { value, phi: curPhi, env: local, threw: true };
|
|
6098
|
+
}
|
|
5056
6099
|
} else if (tryR.returned) {
|
|
5057
6100
|
if (node.finalizer) evalNode(node.finalizer, local, curPhi, budget);
|
|
5058
6101
|
return tryR;
|
|
@@ -5065,7 +6108,13 @@ function evalTry(node, env, phi2, budget) {
|
|
|
5065
6108
|
if (fR.returned || fR.threw) return fR;
|
|
5066
6109
|
local = fR.env;
|
|
5067
6110
|
}
|
|
5068
|
-
return {
|
|
6111
|
+
return {
|
|
6112
|
+
value,
|
|
6113
|
+
phi: curPhi,
|
|
6114
|
+
env: local,
|
|
6115
|
+
returned: tryR.returned,
|
|
6116
|
+
...tryR.partialReturn || tryR.partialThrow ? { partialReturn: tryR.partialReturn } : {}
|
|
6117
|
+
};
|
|
5069
6118
|
}
|
|
5070
6119
|
function evalVarDecl(node, env, phi2, budget) {
|
|
5071
6120
|
let local = env;
|
|
@@ -5105,12 +6154,157 @@ function evalIf(node, env, phi2, budget) {
|
|
|
5105
6154
|
const b = evalInConditionalFlow(
|
|
5106
6155
|
() => evalNode(alt, env, fCons ? and(phi2, fCons) : phi2, budget)
|
|
5107
6156
|
);
|
|
5108
|
-
|
|
6157
|
+
const bothRet = !!a.returned && !!b.returned;
|
|
6158
|
+
const eitherRet = !!a.returned || !!b.returned;
|
|
6159
|
+
const contEnv = a.returned && !b.returned ? b.env : b.returned && !a.returned ? a.env : a.threw && !b.threw ? b.env : b.threw && !a.threw ? a.env : joinEnvs(a.env, b.env, env);
|
|
6160
|
+
return {
|
|
6161
|
+
value: joinAbs(a.value, b.value),
|
|
6162
|
+
phi: phi2,
|
|
6163
|
+
env: contEnv,
|
|
6164
|
+
...bothRet ? { returned: true } : eitherRet ? { partialReturn: true } : {},
|
|
6165
|
+
...a.threw && b.threw ? { threw: true, throwValue: joinAbs(a.value, b.value) } : {},
|
|
6166
|
+
...(a.threw || b.threw) && !(a.threw && b.threw) ? { partialThrow: true, throwValue: a.threw ? a.value : b.value } : {}
|
|
6167
|
+
};
|
|
5109
6168
|
}
|
|
5110
|
-
if (a.returned
|
|
6169
|
+
if (a.returned && a.threw) {
|
|
5111
6170
|
return { value: a.value, phi: phi2, env, partialReturn: true };
|
|
5112
6171
|
}
|
|
5113
|
-
|
|
6172
|
+
if (a.returned || a.threw) {
|
|
6173
|
+
return {
|
|
6174
|
+
value: a.value,
|
|
6175
|
+
phi: phi2,
|
|
6176
|
+
env,
|
|
6177
|
+
...a.returned ? { partialReturn: true } : {},
|
|
6178
|
+
...a.threw ? { partialThrow: true, throwValue: a.value } : {}
|
|
6179
|
+
};
|
|
6180
|
+
}
|
|
6181
|
+
return { value: unknown, phi: phi2, env: joinEnvs(a.env, env, env) };
|
|
6182
|
+
}
|
|
6183
|
+
function evalSwitch(node, env, phi2, budget) {
|
|
6184
|
+
const stmtCompletes = (s) => {
|
|
6185
|
+
if (!s) return false;
|
|
6186
|
+
switch (s.type) {
|
|
6187
|
+
case "BreakStatement":
|
|
6188
|
+
case "ReturnStatement":
|
|
6189
|
+
case "ThrowStatement":
|
|
6190
|
+
case "ContinueStatement":
|
|
6191
|
+
return true;
|
|
6192
|
+
case "BlockStatement":
|
|
6193
|
+
return stmtCompletes(s.body[s.body.length - 1]);
|
|
6194
|
+
case "IfStatement": {
|
|
6195
|
+
const ifs = s;
|
|
6196
|
+
return ifs.alternate != null && stmtCompletes(ifs.consequent) && stmtCompletes(ifs.alternate);
|
|
6197
|
+
}
|
|
6198
|
+
default:
|
|
6199
|
+
return false;
|
|
6200
|
+
}
|
|
6201
|
+
};
|
|
6202
|
+
const pre = [];
|
|
6203
|
+
let pending = [];
|
|
6204
|
+
for (const c of node.cases) {
|
|
6205
|
+
if (c.test == null) {
|
|
6206
|
+
if (pending.length > 0 && c.consequent.length > 0) {
|
|
6207
|
+
pre.push({ tests: pending, body: [...c.consequent], isDefault: false });
|
|
6208
|
+
pending = [];
|
|
6209
|
+
}
|
|
6210
|
+
pre.push({ tests: [], body: [...c.consequent], isDefault: true });
|
|
6211
|
+
continue;
|
|
6212
|
+
}
|
|
6213
|
+
if (c.consequent.length === 0) {
|
|
6214
|
+
pending.push(c.test);
|
|
6215
|
+
continue;
|
|
6216
|
+
}
|
|
6217
|
+
pre.push({ tests: [...pending, c.test], body: [...c.consequent], isDefault: false });
|
|
6218
|
+
pending = [];
|
|
6219
|
+
}
|
|
6220
|
+
if (pending.length > 0) pre.push({ tests: pending, body: [], isDefault: false });
|
|
6221
|
+
const arms = pre.map((a) => ({ ...a, tests: [...a.tests], body: [...a.body] }));
|
|
6222
|
+
for (let i = 0; i < arms.length; i++) {
|
|
6223
|
+
const arm = arms[i];
|
|
6224
|
+
const body = [...arm.body];
|
|
6225
|
+
let j = i + 1;
|
|
6226
|
+
while (j < arms.length && !stmtCompletes(body[body.length - 1])) {
|
|
6227
|
+
body.push(...arms[j].body);
|
|
6228
|
+
if (stmtCompletes(body[body.length - 1])) break;
|
|
6229
|
+
j++;
|
|
6230
|
+
}
|
|
6231
|
+
arm.body = body;
|
|
6232
|
+
}
|
|
6233
|
+
const runBody = (body, e) => {
|
|
6234
|
+
let local = e;
|
|
6235
|
+
let value2 = unknown;
|
|
6236
|
+
for (const s of body) {
|
|
6237
|
+
const r = evalInConditionalFlow(() => evalNode(s, local, phi2, budget));
|
|
6238
|
+
local = r.env;
|
|
6239
|
+
value2 = r.value;
|
|
6240
|
+
if (r.returned || r.threw || r.brk) return { ...r, env: local, value: value2 };
|
|
6241
|
+
}
|
|
6242
|
+
return { value: value2, phi: phi2, env: local };
|
|
6243
|
+
};
|
|
6244
|
+
const disc = evalNode(node.discriminant, env, phi2, budget).value;
|
|
6245
|
+
const dlv = litValue(disc);
|
|
6246
|
+
const hasDefault = arms.some((a) => a.isDefault);
|
|
6247
|
+
const testLit = (t) => {
|
|
6248
|
+
if (t == null) return null;
|
|
6249
|
+
return litValue(evalNode(t, env, phi2, budget).value);
|
|
6250
|
+
};
|
|
6251
|
+
if (dlv !== void 0) {
|
|
6252
|
+
let matched = null;
|
|
6253
|
+
let sawAbstractTest = false;
|
|
6254
|
+
for (const arm of arms) {
|
|
6255
|
+
if (arm.isDefault) continue;
|
|
6256
|
+
let hit = false;
|
|
6257
|
+
for (const t of arm.tests) {
|
|
6258
|
+
const tv = testLit(t);
|
|
6259
|
+
if (tv === null) continue;
|
|
6260
|
+
if (tv === void 0) {
|
|
6261
|
+
sawAbstractTest = true;
|
|
6262
|
+
continue;
|
|
6263
|
+
}
|
|
6264
|
+
if (tv === dlv) {
|
|
6265
|
+
hit = true;
|
|
6266
|
+
break;
|
|
6267
|
+
}
|
|
6268
|
+
}
|
|
6269
|
+
if (hit) {
|
|
6270
|
+
matched = arm;
|
|
6271
|
+
break;
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6274
|
+
if (!sawAbstractTest) {
|
|
6275
|
+
if (matched) return runBody(matched.body, env);
|
|
6276
|
+
const dflt = arms.find((a) => a.isDefault);
|
|
6277
|
+
if (dflt) return runBody(dflt.body, env);
|
|
6278
|
+
return ok2(unknown, phi2, env);
|
|
6279
|
+
}
|
|
6280
|
+
}
|
|
6281
|
+
const results = [];
|
|
6282
|
+
if (!hasDefault) results.push(ok2(unknown, phi2, env));
|
|
6283
|
+
for (const arm of arms) {
|
|
6284
|
+
if (arm.body.length === 0 && !arm.isDefault) continue;
|
|
6285
|
+
results.push(runBody(arm.body, env));
|
|
6286
|
+
}
|
|
6287
|
+
if (results.length === 0) return ok2(unknown, phi2, env);
|
|
6288
|
+
let value = results[0].value;
|
|
6289
|
+
let envOut = results[0].env;
|
|
6290
|
+
let allRet = !!results[0].returned;
|
|
6291
|
+
let anyRet = !!results[0].returned;
|
|
6292
|
+
let anyThrew = !!results[0].threw;
|
|
6293
|
+
for (let i = 1; i < results.length; i++) {
|
|
6294
|
+
const r = results[i];
|
|
6295
|
+
value = joinAbs(value, r.value);
|
|
6296
|
+
envOut = joinEnvs(envOut, r.env, env);
|
|
6297
|
+
allRet = allRet && !!r.returned;
|
|
6298
|
+
anyRet = anyRet || !!r.returned;
|
|
6299
|
+
anyThrew = anyThrew || !!r.threw;
|
|
6300
|
+
}
|
|
6301
|
+
return {
|
|
6302
|
+
value,
|
|
6303
|
+
phi: phi2,
|
|
6304
|
+
env: envOut,
|
|
6305
|
+
...allRet ? { returned: true } : anyRet ? { partialReturn: true } : {},
|
|
6306
|
+
...anyThrew ? { partialThrow: true } : {}
|
|
6307
|
+
};
|
|
5114
6308
|
}
|
|
5115
6309
|
function analyzeFn(source, fnName, args, phi2 = pTrue, budget, file, modules) {
|
|
5116
6310
|
return evalSource(source, { fn: fnName, args }, { phi: phi2, budget, file, modules }).value;
|
|
@@ -5281,7 +6475,7 @@ function $callNamed(name, fn, args, loc, argLocs) {
|
|
|
5281
6475
|
try {
|
|
5282
6476
|
if (typeof fn === "function") {
|
|
5283
6477
|
const g = GLOBAL_FNS.has(name) && fn === globalThis[name] ? evalGlobalFn(name, args) : void 0;
|
|
5284
|
-
result = g ?? fn(...args);
|
|
6478
|
+
result = g ?? callAtFunctionBoundary(() => fn(...args));
|
|
5285
6479
|
} else if (fn && typeof fn === "object" && "shape" in fn) {
|
|
5286
6480
|
result = $call(fn, args);
|
|
5287
6481
|
}
|
|
@@ -5352,6 +6546,14 @@ function $ne(a, b) {
|
|
|
5352
6546
|
const r = strictEqAbs(a, b);
|
|
5353
6547
|
return r === void 0 ? bool() : boolLit(!r);
|
|
5354
6548
|
}
|
|
6549
|
+
function $eqLoose(a, b) {
|
|
6550
|
+
const r = looseEqAbs(a, b);
|
|
6551
|
+
return r === void 0 ? bool() : boolLit(r);
|
|
6552
|
+
}
|
|
6553
|
+
function $neLoose(a, b) {
|
|
6554
|
+
const r = looseEqAbs(a, b);
|
|
6555
|
+
return r === void 0 ? bool() : boolLit(!r);
|
|
6556
|
+
}
|
|
5355
6557
|
function $lt(a, b) {
|
|
5356
6558
|
return cmp("lt", a, b, phi);
|
|
5357
6559
|
}
|
|
@@ -5375,13 +6577,28 @@ function asAbsVal(v2) {
|
|
|
5375
6577
|
const params = Array.from({ length: n }, (_, i) => `arg${i}`);
|
|
5376
6578
|
return absFunction(params, {
|
|
5377
6579
|
body: noBody,
|
|
5378
|
-
|
|
6580
|
+
// 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
|
|
6581
|
+
apply: (args) => callAtFunctionBoundary(() => v2(...args))
|
|
5379
6582
|
});
|
|
5380
6583
|
}
|
|
5381
6584
|
return $lit(v2);
|
|
5382
6585
|
}
|
|
5383
|
-
function
|
|
5384
|
-
return
|
|
6586
|
+
function callAtFunctionBoundary(body) {
|
|
6587
|
+
return runWithLoopExits(() => {
|
|
6588
|
+
try {
|
|
6589
|
+
return body();
|
|
6590
|
+
} catch (e) {
|
|
6591
|
+
if (isNudoReturn(e)) return e.absValue;
|
|
6592
|
+
throw e;
|
|
6593
|
+
}
|
|
6594
|
+
});
|
|
6595
|
+
}
|
|
6596
|
+
function $fnVal(params, impl, opts) {
|
|
6597
|
+
return absFunction(params, {
|
|
6598
|
+
body: noBody,
|
|
6599
|
+
apply: (args) => callAtFunctionBoundary(() => impl(...args)),
|
|
6600
|
+
...opts?.bindThis ? { bindThis: true } : {}
|
|
6601
|
+
});
|
|
5385
6602
|
}
|
|
5386
6603
|
function $lit(v2) {
|
|
5387
6604
|
if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
|
|
@@ -5436,12 +6653,163 @@ function isDefinitelyFalse(a) {
|
|
|
5436
6653
|
function undef() {
|
|
5437
6654
|
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
|
|
5438
6655
|
}
|
|
6656
|
+
var loopExitsAls = new AsyncLocalStorage2();
|
|
6657
|
+
var throwExitsAls = new AsyncLocalStorage2();
|
|
6658
|
+
var tryMarksAls = new AsyncLocalStorage2();
|
|
6659
|
+
function runWithLoopExits(body) {
|
|
6660
|
+
return loopExitsAls.run(
|
|
6661
|
+
[],
|
|
6662
|
+
() => throwExitsAls.run([], () => tryMarksAls.run([], body))
|
|
6663
|
+
);
|
|
6664
|
+
}
|
|
6665
|
+
function takeLoopExits() {
|
|
6666
|
+
return loopExitsAls.getStore() ?? [];
|
|
6667
|
+
}
|
|
6668
|
+
function takeThrowExits() {
|
|
6669
|
+
return throwExitsAls.getStore() ?? [];
|
|
6670
|
+
}
|
|
6671
|
+
function pushLoopExit(v2) {
|
|
6672
|
+
loopExitsAls.getStore()?.push(v2);
|
|
6673
|
+
}
|
|
6674
|
+
function pushThrowExit(v2) {
|
|
6675
|
+
throwExitsAls.getStore()?.push(v2);
|
|
6676
|
+
}
|
|
6677
|
+
function $pushLoopExit(v2) {
|
|
6678
|
+
pushLoopExit(v2);
|
|
6679
|
+
}
|
|
6680
|
+
function $tryMark() {
|
|
6681
|
+
const store = throwExitsAls.getStore();
|
|
6682
|
+
const m = store?.length ?? 0;
|
|
6683
|
+
tryMarksAls.getStore()?.push(m);
|
|
6684
|
+
return m;
|
|
6685
|
+
}
|
|
6686
|
+
function $tryCurrentMark() {
|
|
6687
|
+
const stack = tryMarksAls.getStore();
|
|
6688
|
+
return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
|
|
6689
|
+
}
|
|
6690
|
+
function $tryPopMark() {
|
|
6691
|
+
tryMarksAls.getStore()?.pop();
|
|
6692
|
+
}
|
|
6693
|
+
function $tryTakeSince(mark) {
|
|
6694
|
+
const store = throwExitsAls.getStore();
|
|
6695
|
+
if (!store) return [];
|
|
6696
|
+
return store.splice(Math.min(mark, store.length));
|
|
6697
|
+
}
|
|
6698
|
+
var yieldStack = [];
|
|
6699
|
+
var genPathSensitive = 0;
|
|
6700
|
+
var genJoinOverride = null;
|
|
6701
|
+
function withIsolatedYields(fn) {
|
|
6702
|
+
const top = yieldStack[yieldStack.length - 1];
|
|
6703
|
+
if (!top) return { v: fn(), ys: null };
|
|
6704
|
+
const armYs = [];
|
|
6705
|
+
yieldStack[yieldStack.length - 1] = armYs;
|
|
6706
|
+
try {
|
|
6707
|
+
return { v: fn(), ys: armYs };
|
|
6708
|
+
} finally {
|
|
6709
|
+
yieldStack[yieldStack.length - 1] = top;
|
|
6710
|
+
}
|
|
6711
|
+
}
|
|
6712
|
+
function mergeArmYields(armYsList) {
|
|
6713
|
+
const top = yieldStack[yieldStack.length - 1];
|
|
6714
|
+
if (!top || armYsList.length === 0) return;
|
|
6715
|
+
const concrete = armYsList.filter((x) => x !== null);
|
|
6716
|
+
if (concrete.length === 0) return;
|
|
6717
|
+
if (concrete.length === 1) {
|
|
6718
|
+
top.push(...concrete[0]);
|
|
6719
|
+
return;
|
|
6720
|
+
}
|
|
6721
|
+
let joined = null;
|
|
6722
|
+
for (const ys of concrete) {
|
|
6723
|
+
joined = joined ? joinAbs(joined, $arr(ys)) : $arr(ys);
|
|
6724
|
+
}
|
|
6725
|
+
genPathSensitive++;
|
|
6726
|
+
if (joined) genJoinOverride = joined;
|
|
6727
|
+
for (const ys of concrete) top.push(...ys);
|
|
6728
|
+
}
|
|
6729
|
+
function runForkArm(arm, exits) {
|
|
6730
|
+
try {
|
|
6731
|
+
return { kind: "val", v: asAbsVal(arm()) };
|
|
6732
|
+
} catch (e) {
|
|
6733
|
+
if (isNudoReturn(e)) {
|
|
6734
|
+
exits?.push(e.absValue);
|
|
6735
|
+
return { kind: "ret", v: e.absValue };
|
|
6736
|
+
}
|
|
6737
|
+
if (isNudoThrow(e)) {
|
|
6738
|
+
pushThrowExit(e.absValue);
|
|
6739
|
+
return { kind: "throw", v: e.absValue };
|
|
6740
|
+
}
|
|
6741
|
+
throw e;
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
function settleForkArms(a, b, exits) {
|
|
6745
|
+
const throws = [a, b].filter((r) => r.kind === "throw");
|
|
6746
|
+
const nonThrow = [a, b].filter((r) => r.kind !== "throw");
|
|
6747
|
+
if (nonThrow.length === 0) {
|
|
6748
|
+
throw new NudoThrow(throws.map((t) => t.v).reduce((x, y) => joinAbs(x, y)));
|
|
6749
|
+
}
|
|
6750
|
+
const first = nonThrow[0];
|
|
6751
|
+
const second = nonThrow[1] ?? first;
|
|
6752
|
+
if (first.kind === "ret" && second.kind === "ret") {
|
|
6753
|
+
throw new NudoReturn(joinAbs(first.v, second.v));
|
|
6754
|
+
}
|
|
6755
|
+
if (nonThrow.length === 1) {
|
|
6756
|
+
if (first.kind === "ret") {
|
|
6757
|
+
if (!exits) throw new NudoReturn(first.v);
|
|
6758
|
+
return undef();
|
|
6759
|
+
}
|
|
6760
|
+
return first.v;
|
|
6761
|
+
}
|
|
6762
|
+
if (first.kind === "ret") {
|
|
6763
|
+
if (!exits) throw new NudoReturn(first.v);
|
|
6764
|
+
return second.kind === "val" ? second.v : undef();
|
|
6765
|
+
}
|
|
6766
|
+
if (second.kind === "ret") {
|
|
6767
|
+
if (!exits) throw new NudoReturn(second.v);
|
|
6768
|
+
return first.v;
|
|
6769
|
+
}
|
|
6770
|
+
return joinAbs(first.v, second.v);
|
|
6771
|
+
}
|
|
5439
6772
|
function $fork(test, consequent, alternate) {
|
|
5440
6773
|
if (isDefinitelyTrue(test)) return asAbsVal(consequent());
|
|
5441
6774
|
if (isDefinitelyFalse(test)) return alternate ? asAbsVal(alternate()) : undef();
|
|
5442
|
-
const
|
|
5443
|
-
|
|
5444
|
-
|
|
6775
|
+
const exits = loopExitsAls.getStore();
|
|
6776
|
+
beginCollectionFork();
|
|
6777
|
+
const arms = [];
|
|
6778
|
+
const armYsList = [];
|
|
6779
|
+
let a;
|
|
6780
|
+
let b;
|
|
6781
|
+
try {
|
|
6782
|
+
pushCollectionArm();
|
|
6783
|
+
try {
|
|
6784
|
+
const r = withIsolatedYields(() => runForkArm(consequent, exits));
|
|
6785
|
+
a = r.v;
|
|
6786
|
+
armYsList.push(r.ys);
|
|
6787
|
+
} finally {
|
|
6788
|
+
arms.push(popCollectionArm());
|
|
6789
|
+
}
|
|
6790
|
+
if (alternate) {
|
|
6791
|
+
pushCollectionArm();
|
|
6792
|
+
try {
|
|
6793
|
+
const r = withIsolatedYields(() => runForkArm(alternate, exits));
|
|
6794
|
+
b = r.v;
|
|
6795
|
+
armYsList.push(r.ys);
|
|
6796
|
+
} finally {
|
|
6797
|
+
arms.push(popCollectionArm());
|
|
6798
|
+
}
|
|
6799
|
+
} else {
|
|
6800
|
+
pushCollectionArm();
|
|
6801
|
+
try {
|
|
6802
|
+
b = { kind: "val", v: undef() };
|
|
6803
|
+
armYsList.push(null);
|
|
6804
|
+
} finally {
|
|
6805
|
+
arms.push(popCollectionArm());
|
|
6806
|
+
}
|
|
6807
|
+
}
|
|
6808
|
+
} finally {
|
|
6809
|
+
endCollectionFork(arms);
|
|
6810
|
+
if (yieldStack.length > 0) mergeArmYields(armYsList);
|
|
6811
|
+
}
|
|
6812
|
+
return settleForkArms(a, b, exits);
|
|
5445
6813
|
}
|
|
5446
6814
|
var DEFAULT_MAX_LOOP_ITERS = 8;
|
|
5447
6815
|
function* $forIter(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
@@ -5457,30 +6825,67 @@ function* $forIter(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
|
5457
6825
|
s = step(afterBody);
|
|
5458
6826
|
}
|
|
5459
6827
|
}
|
|
5460
|
-
function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
6828
|
+
function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
5461
6829
|
let state = init;
|
|
5462
6830
|
let exitJoin;
|
|
6831
|
+
let extJoin;
|
|
6832
|
+
const pack = opts?.pack;
|
|
6833
|
+
const unpack = opts?.unpack;
|
|
6834
|
+
const snapCounter = () => {
|
|
6835
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, state) : state;
|
|
6836
|
+
};
|
|
6837
|
+
const snapExt = () => {
|
|
6838
|
+
if (!pack) return;
|
|
6839
|
+
const p = pack();
|
|
6840
|
+
extJoin = extJoin ? joinAbs(extJoin, p) : p;
|
|
6841
|
+
};
|
|
6842
|
+
const applyExtJoin = () => {
|
|
6843
|
+
if (!extJoin || !pack || !unpack) return;
|
|
6844
|
+
unpack(joinAbs(extJoin, pack()));
|
|
6845
|
+
};
|
|
5463
6846
|
for (let i = 0; i < maxIters; i++) {
|
|
5464
6847
|
const t = test(state);
|
|
5465
6848
|
if (isDefinitelyFalse(t)) {
|
|
5466
|
-
|
|
6849
|
+
snapCounter();
|
|
6850
|
+
snapExt();
|
|
6851
|
+
applyExtJoin();
|
|
6852
|
+
return exitJoin ?? state;
|
|
5467
6853
|
}
|
|
5468
|
-
|
|
5469
|
-
|
|
6854
|
+
const abstractTest = !isDefinitelyTrue(t);
|
|
6855
|
+
if (abstractTest) {
|
|
6856
|
+
snapCounter();
|
|
6857
|
+
snapExt();
|
|
6858
|
+
}
|
|
6859
|
+
let afterBody;
|
|
6860
|
+
try {
|
|
6861
|
+
afterBody = body(state);
|
|
6862
|
+
} catch (e) {
|
|
6863
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
6864
|
+
throw e;
|
|
5470
6865
|
}
|
|
5471
|
-
const afterBody = body(state);
|
|
5472
6866
|
const next = step(afterBody);
|
|
6867
|
+
if (abstractTest) {
|
|
6868
|
+
state = afterBody;
|
|
6869
|
+
snapExt();
|
|
6870
|
+
}
|
|
5473
6871
|
if (i > 0) {
|
|
5474
6872
|
const nv = litValue(next);
|
|
5475
6873
|
const sv = litValue(state);
|
|
5476
6874
|
const stuck = nv !== void 0 && sv !== void 0 && nv === sv || nv === void 0 && sv === void 0 && leqAbs(next, state).ok;
|
|
5477
6875
|
if (stuck) {
|
|
5478
|
-
|
|
6876
|
+
state = next;
|
|
6877
|
+
snapCounter();
|
|
6878
|
+
snapExt();
|
|
6879
|
+
applyExtJoin();
|
|
6880
|
+
return exitJoin ?? next;
|
|
5479
6881
|
}
|
|
5480
6882
|
}
|
|
5481
6883
|
state = next;
|
|
5482
6884
|
}
|
|
5483
|
-
|
|
6885
|
+
snapCounter();
|
|
6886
|
+
snapExt();
|
|
6887
|
+
applyExtJoin();
|
|
6888
|
+
return exitJoin ?? state;
|
|
5484
6889
|
}
|
|
5485
6890
|
function tupleOrWiden(els, conf) {
|
|
5486
6891
|
if (shouldWidenArrayLiteral(els.length)) {
|
|
@@ -5496,6 +6901,99 @@ function tupleOrWiden(els, conf) {
|
|
|
5496
6901
|
function $arr(items) {
|
|
5497
6902
|
return tupleOrWiden(items.map(asAbsVal), "exact");
|
|
5498
6903
|
}
|
|
6904
|
+
var ARR_MUTATORS = /* @__PURE__ */ new Set([
|
|
6905
|
+
"push",
|
|
6906
|
+
"unshift",
|
|
6907
|
+
"pop",
|
|
6908
|
+
"shift",
|
|
6909
|
+
"splice",
|
|
6910
|
+
"reverse",
|
|
6911
|
+
"sort"
|
|
6912
|
+
]);
|
|
6913
|
+
function isArrMutator(name) {
|
|
6914
|
+
return ARR_MUTATORS.has(name);
|
|
6915
|
+
}
|
|
6916
|
+
function $arrMutContainer(arr, method, args) {
|
|
6917
|
+
const shape = arr.shape;
|
|
6918
|
+
if (shape.k !== "tuple" && shape.k !== "arr") return arr;
|
|
6919
|
+
const vals = args.map((a) => asAbsVal(a));
|
|
6920
|
+
const asArrEl = (els) => els.length > 0 ? els.reduce((x, y) => joinAbs(x, y)) : unknown;
|
|
6921
|
+
if (method === "push" || method === "unshift") {
|
|
6922
|
+
if (shape.k === "tuple") {
|
|
6923
|
+
const els = method === "push" ? [...shape.elements, ...vals] : [...vals, ...shape.elements];
|
|
6924
|
+
const conf = vals.reduce(
|
|
6925
|
+
(acc, v2) => confJoin(acc, v2.conf),
|
|
6926
|
+
arr.conf
|
|
6927
|
+
);
|
|
6928
|
+
return abs(
|
|
6929
|
+
{ k: "tuple", elements: els },
|
|
6930
|
+
void 0,
|
|
6931
|
+
void 0,
|
|
6932
|
+
conf
|
|
6933
|
+
);
|
|
6934
|
+
}
|
|
6935
|
+
const el = vals.reduce((acc, v2) => joinAbs(acc, v2), shape.element);
|
|
6936
|
+
return abs({ k: "arr", element: el }, void 0, void 0, confJoin(arr.conf, "path"));
|
|
6937
|
+
}
|
|
6938
|
+
if (method === "pop") {
|
|
6939
|
+
if (shape.k === "tuple") {
|
|
6940
|
+
if (shape.elements.length === 0) return arr;
|
|
6941
|
+
return abs(
|
|
6942
|
+
{ k: "tuple", elements: shape.elements.slice(0, -1) },
|
|
6943
|
+
void 0,
|
|
6944
|
+
void 0,
|
|
6945
|
+
arr.conf
|
|
6946
|
+
);
|
|
6947
|
+
}
|
|
6948
|
+
return arr;
|
|
6949
|
+
}
|
|
6950
|
+
if (method === "shift") {
|
|
6951
|
+
if (shape.k === "tuple") {
|
|
6952
|
+
if (shape.elements.length === 0) return arr;
|
|
6953
|
+
return abs(
|
|
6954
|
+
{ k: "tuple", elements: shape.elements.slice(1) },
|
|
6955
|
+
void 0,
|
|
6956
|
+
void 0,
|
|
6957
|
+
arr.conf
|
|
6958
|
+
);
|
|
6959
|
+
}
|
|
6960
|
+
return arr;
|
|
6961
|
+
}
|
|
6962
|
+
if (method === "splice") {
|
|
6963
|
+
if (shape.k === "tuple") {
|
|
6964
|
+
return abs(
|
|
6965
|
+
{ k: "arr", element: asArrEl(shape.elements) },
|
|
6966
|
+
void 0,
|
|
6967
|
+
void 0,
|
|
6968
|
+
confJoin(arr.conf, "path")
|
|
6969
|
+
);
|
|
6970
|
+
}
|
|
6971
|
+
return arr;
|
|
6972
|
+
}
|
|
6973
|
+
if (method === "reverse") {
|
|
6974
|
+
if (shape.k === "tuple") {
|
|
6975
|
+
return abs(
|
|
6976
|
+
{ k: "tuple", elements: [...shape.elements].reverse() },
|
|
6977
|
+
void 0,
|
|
6978
|
+
void 0,
|
|
6979
|
+
arr.conf
|
|
6980
|
+
);
|
|
6981
|
+
}
|
|
6982
|
+
return arr;
|
|
6983
|
+
}
|
|
6984
|
+
if (method === "sort") {
|
|
6985
|
+
if (shape.k === "tuple") {
|
|
6986
|
+
return abs(
|
|
6987
|
+
{ k: "arr", element: asArrEl(shape.elements) },
|
|
6988
|
+
void 0,
|
|
6989
|
+
void 0,
|
|
6990
|
+
confJoin(arr.conf, "path")
|
|
6991
|
+
);
|
|
6992
|
+
}
|
|
6993
|
+
return arr;
|
|
6994
|
+
}
|
|
6995
|
+
return arr;
|
|
6996
|
+
}
|
|
5499
6997
|
function $idx(a, i) {
|
|
5500
6998
|
const iv = litValue(i);
|
|
5501
6999
|
if (a.shape.k === "tuple") {
|
|
@@ -5511,6 +7009,22 @@ function $idx(a, i) {
|
|
|
5511
7009
|
if (a.shape.k === "sum") {
|
|
5512
7010
|
return a.shape.members.map((m) => $idx(m, i)).reduce((x, y) => joinAbs(x, y));
|
|
5513
7011
|
}
|
|
7012
|
+
if (a.shape.k === "obj" || a.shape.k === "brand" && a.shape.shape.shape.k === "obj") {
|
|
7013
|
+
const objShape = a.shape.k === "obj" ? a.shape : a.shape.shape.shape;
|
|
7014
|
+
const slots = Object.values(objShape.slots).map((s) => s.value);
|
|
7015
|
+
if (slots.length === 0) return objShape.open ? unknown : undef();
|
|
7016
|
+
const joinSlotsWithUndef = () => joinAbs(slots.reduce((x, y) => joinAbs(x, y)), undef());
|
|
7017
|
+
if (typeof iv === "string" || typeof iv === "number" || typeof iv === "boolean") {
|
|
7018
|
+
const slot = objShape.slots[String(iv)];
|
|
7019
|
+
if (slot) return slot.value;
|
|
7020
|
+
if (objShape.open) return unknown;
|
|
7021
|
+
return undef();
|
|
7022
|
+
}
|
|
7023
|
+
if (objShape.open && slots.length > 0) {
|
|
7024
|
+
return joinAbs(slots.reduce((x, y) => joinAbs(x, y)), unknown);
|
|
7025
|
+
}
|
|
7026
|
+
return joinSlotsWithUndef();
|
|
7027
|
+
}
|
|
5514
7028
|
const sv = litValue(a);
|
|
5515
7029
|
if (typeof sv === "string") {
|
|
5516
7030
|
if (typeof iv === "number" && Number.isInteger(iv)) {
|
|
@@ -5570,6 +7084,35 @@ function $obj(slots) {
|
|
|
5570
7084
|
function $spread(a, b) {
|
|
5571
7085
|
return spread(asAbsVal(a), asAbsVal(b));
|
|
5572
7086
|
}
|
|
7087
|
+
function $objRest(o, keys) {
|
|
7088
|
+
o = asAbsVal(o);
|
|
7089
|
+
if (o.shape.k === "sum") {
|
|
7090
|
+
return o.shape.members.map((m) => $objRest(m, keys)).reduce((a, b) => joinAbs(a, b));
|
|
7091
|
+
}
|
|
7092
|
+
if (!isObj(o)) return unknown;
|
|
7093
|
+
const drop = new Set(keys);
|
|
7094
|
+
const slots = {};
|
|
7095
|
+
let openRest = o.shape.open === true;
|
|
7096
|
+
for (const [k, s] of Object.entries(o.shape.slots)) {
|
|
7097
|
+
if (drop.has(k)) continue;
|
|
7098
|
+
slots[k] = s;
|
|
7099
|
+
}
|
|
7100
|
+
if (o.shape.open) openRest = true;
|
|
7101
|
+
const shape = { k: "obj", slots };
|
|
7102
|
+
if (openRest) shape.open = true;
|
|
7103
|
+
return { shape, conf: o.conf === "exact" ? "exact" : confJoin(o.conf, "partial") };
|
|
7104
|
+
}
|
|
7105
|
+
function $arrRest(a, start) {
|
|
7106
|
+
a = asAbsVal(a);
|
|
7107
|
+
if (a.shape.k === "sum") {
|
|
7108
|
+
return a.shape.members.map((m) => $arrRest(m, start)).reduce((x, y) => joinAbs(x, y));
|
|
7109
|
+
}
|
|
7110
|
+
if (a.shape.k === "tuple") {
|
|
7111
|
+
return tupleOrWiden(a.shape.elements.slice(start), a.conf);
|
|
7112
|
+
}
|
|
7113
|
+
if (a.shape.k === "arr") return a;
|
|
7114
|
+
return unknown;
|
|
7115
|
+
}
|
|
5573
7116
|
function $concat(a, b) {
|
|
5574
7117
|
a = asAbsVal(a);
|
|
5575
7118
|
b = asAbsVal(b);
|
|
@@ -5604,20 +7147,49 @@ function $concat(a, b) {
|
|
|
5604
7147
|
function $elems(a) {
|
|
5605
7148
|
if (a.shape.k === "tuple") return [...a.shape.elements];
|
|
5606
7149
|
if (a.shape.k === "arr") return [a.shape.element];
|
|
7150
|
+
if (isSetAbs(a)) return setElementsAbs(a);
|
|
7151
|
+
if (isMapAbs(a)) return mapEntriesAbs(a);
|
|
5607
7152
|
return [unknown];
|
|
5608
7153
|
}
|
|
5609
|
-
function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
7154
|
+
function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
7155
|
+
const pack = opts?.pack;
|
|
7156
|
+
const unpack = opts?.unpack;
|
|
7157
|
+
let exitJoin;
|
|
7158
|
+
const snapExit = () => {
|
|
7159
|
+
if (!pack) return;
|
|
7160
|
+
const s = pack();
|
|
7161
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, s) : s;
|
|
7162
|
+
};
|
|
7163
|
+
const applyExitJoin = () => {
|
|
7164
|
+
if (!exitJoin || !pack || !unpack) return;
|
|
7165
|
+
unpack(joinAbs(exitJoin, pack()));
|
|
7166
|
+
};
|
|
7167
|
+
const shape = iterable.shape;
|
|
5610
7168
|
const items = $elems(iterable);
|
|
5611
|
-
const
|
|
7169
|
+
const knownLen = shape.k === "tuple" ? shape.elements.length : collectionExactLen(iterable);
|
|
7170
|
+
const unbounded = knownLen === void 0;
|
|
7171
|
+
if (unbounded) snapExit();
|
|
7172
|
+
const n = knownLen !== void 0 ? Math.min(knownLen, maxIters) : items.length > 0 ? maxIters : 0;
|
|
5612
7173
|
for (let i = 0; i < n; i++) {
|
|
5613
7174
|
const item = items.length > 0 ? items[Math.min(i, items.length - 1)] : unknown;
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
7175
|
+
try {
|
|
7176
|
+
body(
|
|
7177
|
+
item,
|
|
7178
|
+
abs(
|
|
7179
|
+
{ k: "prim", type: "number" },
|
|
7180
|
+
{ op: "lit", value: i },
|
|
7181
|
+
pTrue,
|
|
7182
|
+
"exact"
|
|
7183
|
+
)
|
|
7184
|
+
);
|
|
7185
|
+
} catch (e) {
|
|
7186
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
7187
|
+
throw e;
|
|
7188
|
+
}
|
|
7189
|
+
if (unbounded) snapExit();
|
|
5620
7190
|
}
|
|
7191
|
+
if (unbounded && n === 0) snapExit();
|
|
7192
|
+
applyExitJoin();
|
|
5621
7193
|
}
|
|
5622
7194
|
function namespaceNameOf(v2) {
|
|
5623
7195
|
if (typeof v2 !== "object" && typeof v2 !== "function") return void 0;
|
|
@@ -5665,11 +7237,19 @@ function $get(o, key, opts) {
|
|
|
5665
7237
|
}
|
|
5666
7238
|
return unknown;
|
|
5667
7239
|
}
|
|
5668
|
-
if (o.shape.k === "brand")
|
|
7240
|
+
if (o.shape.k === "brand") {
|
|
7241
|
+
if (key === "size" && o.shape.name === "Map") return mapSizeAbs(o);
|
|
7242
|
+
if (key === "size" && o.shape.name === "Set") return setSizeAbs(o);
|
|
7243
|
+
return $get(o.shape.shape, key, opts);
|
|
7244
|
+
}
|
|
5669
7245
|
if (isObj(o)) {
|
|
5670
7246
|
const slot = o.shape.slots[key];
|
|
5671
|
-
if (slot)
|
|
7247
|
+
if (slot) {
|
|
7248
|
+
if (slot.optional) return joinAbs(slot.value, undef());
|
|
7249
|
+
return slot.value;
|
|
7250
|
+
}
|
|
5672
7251
|
if (o.shape.open) return unknown;
|
|
7252
|
+
noteObjSlotMissing(o, key);
|
|
5673
7253
|
return undef();
|
|
5674
7254
|
}
|
|
5675
7255
|
if (o.shape.k === "sum") {
|
|
@@ -5678,6 +7258,7 @@ function $get(o, key, opts) {
|
|
|
5678
7258
|
}
|
|
5679
7259
|
if (!opts?.silent) {
|
|
5680
7260
|
noteUnknownMemberMissing(o, key, "property");
|
|
7261
|
+
noteObjSlotMissing(o, key);
|
|
5681
7262
|
}
|
|
5682
7263
|
return unknown;
|
|
5683
7264
|
}
|
|
@@ -5725,12 +7306,52 @@ function $while(init, test, step, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
|
5725
7306
|
}
|
|
5726
7307
|
return exitJoin ? joinAbs(exitJoin, state) : state;
|
|
5727
7308
|
}
|
|
5728
|
-
function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
7309
|
+
function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
7310
|
+
const pack = opts?.pack;
|
|
7311
|
+
const unpack = opts?.unpack;
|
|
7312
|
+
let exitJoin;
|
|
7313
|
+
const snapExit = () => {
|
|
7314
|
+
if (!pack) return;
|
|
7315
|
+
const s = pack();
|
|
7316
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, s) : s;
|
|
7317
|
+
};
|
|
7318
|
+
const applyExitJoin = () => {
|
|
7319
|
+
if (!exitJoin || !pack || !unpack) return;
|
|
7320
|
+
unpack(joinAbs(exitJoin, pack()));
|
|
7321
|
+
};
|
|
5729
7322
|
for (let i = 0; i < maxIters; i++) {
|
|
5730
7323
|
const t = test();
|
|
5731
|
-
if (isDefinitelyFalse(t))
|
|
5732
|
-
|
|
7324
|
+
if (isDefinitelyFalse(t)) {
|
|
7325
|
+
applyExitJoin();
|
|
7326
|
+
return;
|
|
7327
|
+
}
|
|
7328
|
+
if (!isDefinitelyTrue(t)) snapExit();
|
|
7329
|
+
try {
|
|
7330
|
+
body();
|
|
7331
|
+
} catch (e) {
|
|
7332
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
7333
|
+
throw e;
|
|
7334
|
+
}
|
|
7335
|
+
}
|
|
7336
|
+
snapExit();
|
|
7337
|
+
applyExitJoin();
|
|
7338
|
+
}
|
|
7339
|
+
var NudoReturn = class extends Error {
|
|
7340
|
+
absValue;
|
|
7341
|
+
constructor(absValue) {
|
|
7342
|
+
super("nudo:return");
|
|
7343
|
+
this.name = "NudoReturn";
|
|
7344
|
+
this.absValue = absValue;
|
|
5733
7345
|
}
|
|
7346
|
+
};
|
|
7347
|
+
function $loopReturn(v2) {
|
|
7348
|
+
throw new NudoReturn(v2);
|
|
7349
|
+
}
|
|
7350
|
+
function isNudoReturn(e) {
|
|
7351
|
+
return e instanceof NudoReturn;
|
|
7352
|
+
}
|
|
7353
|
+
function $rethrowIfNudoReturn(e) {
|
|
7354
|
+
if (isNudoReturn(e)) throw e;
|
|
5734
7355
|
}
|
|
5735
7356
|
var NudoThrow = class extends Error {
|
|
5736
7357
|
absValue;
|
|
@@ -5746,11 +7367,35 @@ function $throw(v2) {
|
|
|
5746
7367
|
function isNudoThrow(e) {
|
|
5747
7368
|
return e instanceof NudoThrow;
|
|
5748
7369
|
}
|
|
7370
|
+
function $isForkExit(e) {
|
|
7371
|
+
return isNudoReturn(e) || isNudoThrow(e);
|
|
7372
|
+
}
|
|
5749
7373
|
function $catchVal(e) {
|
|
5750
7374
|
if (isNudoThrow(e)) return e.absValue;
|
|
5751
7375
|
if (e instanceof Error) {
|
|
7376
|
+
const name = e.name || "Error";
|
|
7377
|
+
const msgAbs = typeof e.message === "string" ? abs(
|
|
7378
|
+
{ k: "prim", type: "string" },
|
|
7379
|
+
{ op: "lit", value: e.message },
|
|
7380
|
+
pTrue,
|
|
7381
|
+
"exact"
|
|
7382
|
+
) : abs({ k: "prim", type: "string" }, void 0, void 0, "path");
|
|
5752
7383
|
return abs(
|
|
5753
|
-
{
|
|
7384
|
+
{
|
|
7385
|
+
k: "brand",
|
|
7386
|
+
name,
|
|
7387
|
+
shape: objOf({
|
|
7388
|
+
name: {
|
|
7389
|
+
value: abs(
|
|
7390
|
+
{ k: "prim", type: "string" },
|
|
7391
|
+
{ op: "lit", value: name },
|
|
7392
|
+
pTrue,
|
|
7393
|
+
"exact"
|
|
7394
|
+
)
|
|
7395
|
+
},
|
|
7396
|
+
message: { value: msgAbs }
|
|
7397
|
+
})
|
|
7398
|
+
},
|
|
5754
7399
|
void 0,
|
|
5755
7400
|
void 0,
|
|
5756
7401
|
"path"
|
|
@@ -5781,16 +7426,28 @@ function $asyncReturn(v2) {
|
|
|
5781
7426
|
if (v2.shape.k === "eff") return v2;
|
|
5782
7427
|
return wrapPromiseAbs(v2);
|
|
5783
7428
|
}
|
|
5784
|
-
var yieldStack = [];
|
|
5785
7429
|
function $gen(body) {
|
|
5786
7430
|
const ys = [];
|
|
7431
|
+
const marker = genPathSensitive;
|
|
7432
|
+
const prevOverride = genJoinOverride;
|
|
7433
|
+
genJoinOverride = null;
|
|
5787
7434
|
yieldStack.push(ys);
|
|
5788
7435
|
try {
|
|
5789
7436
|
body();
|
|
5790
7437
|
} finally {
|
|
5791
7438
|
yieldStack.pop();
|
|
5792
7439
|
}
|
|
5793
|
-
|
|
7440
|
+
if (genJoinOverride) {
|
|
7441
|
+
const joined = genJoinOverride;
|
|
7442
|
+
genJoinOverride = prevOverride;
|
|
7443
|
+
return { ...joined, conf: joined.conf === "exact" ? "path" : joined.conf };
|
|
7444
|
+
}
|
|
7445
|
+
genJoinOverride = prevOverride;
|
|
7446
|
+
const arr = $arr(ys);
|
|
7447
|
+
if (genPathSensitive > marker) {
|
|
7448
|
+
return { ...arr, conf: arr.conf === "exact" ? "path" : arr.conf };
|
|
7449
|
+
}
|
|
7450
|
+
return arr;
|
|
5794
7451
|
}
|
|
5795
7452
|
function $yield(v2) {
|
|
5796
7453
|
const top = yieldStack[yieldStack.length - 1];
|
|
@@ -5806,10 +7463,63 @@ function $switch(disc, cases, dflt) {
|
|
|
5806
7463
|
}
|
|
5807
7464
|
return dflt ? asAbsVal(dflt()) : undef();
|
|
5808
7465
|
}
|
|
5809
|
-
const
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
7466
|
+
const exits = loopExitsAls.getStore();
|
|
7467
|
+
beginCollectionFork();
|
|
7468
|
+
const armOverlays2 = [];
|
|
7469
|
+
const armYsList = [];
|
|
7470
|
+
const runArm = (fn) => {
|
|
7471
|
+
pushCollectionArm();
|
|
7472
|
+
try {
|
|
7473
|
+
const r = withIsolatedYields(() => runForkArm(fn, exits));
|
|
7474
|
+
armYsList.push(r.ys);
|
|
7475
|
+
return r.v;
|
|
7476
|
+
} finally {
|
|
7477
|
+
armOverlays2.push(popCollectionArm());
|
|
7478
|
+
}
|
|
7479
|
+
};
|
|
7480
|
+
const results = [];
|
|
7481
|
+
try {
|
|
7482
|
+
const seenRuns = /* @__PURE__ */ new Set();
|
|
7483
|
+
for (const c of cases) {
|
|
7484
|
+
if (seenRuns.has(c.run)) continue;
|
|
7485
|
+
seenRuns.add(c.run);
|
|
7486
|
+
results.push(runArm(c.run));
|
|
7487
|
+
}
|
|
7488
|
+
if (dflt) {
|
|
7489
|
+
if (!seenRuns.has(dflt)) results.push(runArm(dflt));
|
|
7490
|
+
} else {
|
|
7491
|
+
pushCollectionArm();
|
|
7492
|
+
try {
|
|
7493
|
+
results.push({ kind: "val", v: undef() });
|
|
7494
|
+
armYsList.push(null);
|
|
7495
|
+
} finally {
|
|
7496
|
+
armOverlays2.push(popCollectionArm());
|
|
7497
|
+
}
|
|
7498
|
+
}
|
|
7499
|
+
} finally {
|
|
7500
|
+
endCollectionFork(armOverlays2);
|
|
7501
|
+
if (yieldStack.length > 0) mergeArmYields(armYsList);
|
|
7502
|
+
}
|
|
7503
|
+
if (results.length === 0) return undef();
|
|
7504
|
+
const throws = results.filter((r) => r.kind === "throw");
|
|
7505
|
+
const nonThrow = results.filter((r) => r.kind !== "throw");
|
|
7506
|
+
if (nonThrow.length === 0) {
|
|
7507
|
+
throw new NudoThrow(throws.map((t) => t.v).reduce((x, y) => joinAbs(x, y)));
|
|
7508
|
+
}
|
|
7509
|
+
const allRet = nonThrow.every((r) => r.kind === "ret");
|
|
7510
|
+
if (allRet) {
|
|
7511
|
+
throw new NudoReturn(nonThrow.map((r) => r.v).reduce((a, b) => joinAbs(a, b)));
|
|
7512
|
+
}
|
|
7513
|
+
const valParts = nonThrow.filter((r) => r.kind === "val").map((r) => r.v);
|
|
7514
|
+
if (valParts.length === 0) return undef();
|
|
7515
|
+
return valParts.reduce((a, b) => joinAbs(a, b));
|
|
7516
|
+
}
|
|
7517
|
+
function $nullishTest(v2) {
|
|
7518
|
+
if (definitelyNotNullishShape(v2.shape)) return boolLit(false);
|
|
7519
|
+
if (isNullishLitAbs(v2)) return boolLit(true);
|
|
7520
|
+
const t = v2.term;
|
|
7521
|
+
if (t?.op === "lit" && t.value !== null && t.value !== void 0) return boolLit(false);
|
|
7522
|
+
return bool();
|
|
5813
7523
|
}
|
|
5814
7524
|
|
|
5815
7525
|
// src/algebra/exec/transpile.ts
|
|
@@ -5824,6 +7534,7 @@ function matchAsOverride(stmt, opts) {
|
|
|
5824
7534
|
function normWs(s) {
|
|
5825
7535
|
return s.replace(/\s+/g, "");
|
|
5826
7536
|
}
|
|
7537
|
+
var switchBodySeq = 0;
|
|
5827
7538
|
function matchReplacement(node, opts) {
|
|
5828
7539
|
if (!opts.source || !opts.replacements?.length) return null;
|
|
5829
7540
|
if (node.start == null || node.end == null || !node.loc) return null;
|
|
@@ -5848,7 +7559,9 @@ var BIN_OPS = {
|
|
|
5848
7559
|
">": "$gt",
|
|
5849
7560
|
">=": "$ge",
|
|
5850
7561
|
"===": "$eq",
|
|
5851
|
-
"!==": "$ne"
|
|
7562
|
+
"!==": "$ne",
|
|
7563
|
+
"==": "$eqLoose",
|
|
7564
|
+
"!=": "$neLoose"
|
|
5852
7565
|
};
|
|
5853
7566
|
var COMPOUND_OPS = {
|
|
5854
7567
|
"+=": "$add",
|
|
@@ -5921,6 +7634,65 @@ function setPathSrc(p, valSrc) {
|
|
|
5921
7634
|
function readPrefix(p, j) {
|
|
5922
7635
|
return p.layers.slice(0, j + 1).reduce((acc, l) => l.get(acc), p.rootSrc);
|
|
5923
7636
|
}
|
|
7637
|
+
var ARR_MUTATOR_NAMES = /* @__PURE__ */ new Set([
|
|
7638
|
+
"push",
|
|
7639
|
+
"unshift",
|
|
7640
|
+
"splice",
|
|
7641
|
+
"pop",
|
|
7642
|
+
"shift",
|
|
7643
|
+
"reverse",
|
|
7644
|
+
"sort"
|
|
7645
|
+
]);
|
|
7646
|
+
function emitArrMutatorRebinds(expr, opts, pad) {
|
|
7647
|
+
const lines = [];
|
|
7648
|
+
if (!expr || typeof expr !== "object") return lines;
|
|
7649
|
+
const visit = (n) => {
|
|
7650
|
+
if (!n || typeof n !== "object") return;
|
|
7651
|
+
const node = n;
|
|
7652
|
+
if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "ObjectMethod" || node.type === "ClassMethod") {
|
|
7653
|
+
return;
|
|
7654
|
+
}
|
|
7655
|
+
if (node.type === "LogicalExpression" || node.type === "ConditionalExpression") {
|
|
7656
|
+
return;
|
|
7657
|
+
}
|
|
7658
|
+
if (node.type === "AssignmentExpression" && (node.operator === "||=" || node.operator === "&&=" || node.operator === "??=")) {
|
|
7659
|
+
visit(node.left);
|
|
7660
|
+
return;
|
|
7661
|
+
}
|
|
7662
|
+
if (node.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.computed !== true && node.callee.property?.type === "Identifier" && ARR_MUTATOR_NAMES.has(node.callee.property.name)) {
|
|
7663
|
+
const methodName = node.callee.property.name;
|
|
7664
|
+
const argSrcs = (node.arguments ?? []).map(
|
|
7665
|
+
(a) => a.type === "SpreadElement" ? "$lit(undefined)" : isExpression(a) ? transpileExpression(a, opts) : "$lit(undefined)"
|
|
7666
|
+
).join(", ");
|
|
7667
|
+
const objNode = node.callee.object;
|
|
7668
|
+
if (objNode.type === "Identifier") {
|
|
7669
|
+
const name = objNode.name;
|
|
7670
|
+
lines.push(
|
|
7671
|
+
`${pad}${name} = $arrMutContainer(${name}, ${JSON.stringify(methodName)}, [${argSrcs}]);`
|
|
7672
|
+
);
|
|
7673
|
+
} else if (objNode.type === "MemberExpression" || objNode.type === "ThisExpression") {
|
|
7674
|
+
const path = objNode.type === "MemberExpression" ? memberPathOf(
|
|
7675
|
+
objNode,
|
|
7676
|
+
opts
|
|
7677
|
+
) : null;
|
|
7678
|
+
if (path) {
|
|
7679
|
+
const recvSrc = readPathSrc(path);
|
|
7680
|
+
const mutSrc = `$arrMutContainer(${recvSrc}, ${JSON.stringify(methodName)}, [${argSrcs}])`;
|
|
7681
|
+
lines.push(`${pad}${path.rootSrc} = ${setPathSrc(path, mutSrc)};`);
|
|
7682
|
+
}
|
|
7683
|
+
}
|
|
7684
|
+
}
|
|
7685
|
+
for (const key of Object.keys(node)) {
|
|
7686
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7687
|
+
if (key === "callee" || key === "property") continue;
|
|
7688
|
+
const child = node[key];
|
|
7689
|
+
if (Array.isArray(child)) child.forEach(visit);
|
|
7690
|
+
else if (child && typeof child === "object") visit(child);
|
|
7691
|
+
}
|
|
7692
|
+
};
|
|
7693
|
+
visit(expr);
|
|
7694
|
+
return lines;
|
|
7695
|
+
}
|
|
5924
7696
|
function transpileSource(source, opts = {}) {
|
|
5925
7697
|
const file = parseSource(source);
|
|
5926
7698
|
return transpileFile(file, { ...opts, source: opts.source ?? source });
|
|
@@ -5929,7 +7701,7 @@ function transpileFile(file, opts = {}) {
|
|
|
5929
7701
|
const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
|
|
5930
7702
|
const lines = [
|
|
5931
7703
|
`// nudo B-path transpile \u2014 values are Abs; operators are overloaded calls`,
|
|
5932
|
-
`import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $idx, $idxSet, $len, $call, $throw, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex } from ${JSON.stringify(runtime)};`,
|
|
7704
|
+
`import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $rethrowIfNudoReturn, $nullishTest, $tryMark, $tryTakeSince, $tryCurrentMark, $tryPopMark, $pushLoopExit, $objRest, $arrRest, $isForkExit } from ${JSON.stringify(runtime)};`,
|
|
5933
7705
|
``
|
|
5934
7706
|
];
|
|
5935
7707
|
for (const stmt of file.program.body) {
|
|
@@ -5940,12 +7712,226 @@ function transpileFile(file, opts = {}) {
|
|
|
5940
7712
|
function indent(n) {
|
|
5941
7713
|
return " ".repeat(n);
|
|
5942
7714
|
}
|
|
7715
|
+
function collectAssignedIds(node, acc) {
|
|
7716
|
+
if (!node || typeof node !== "object") return;
|
|
7717
|
+
const n = node;
|
|
7718
|
+
if (n.type === "AssignmentExpression" && n.left?.type === "Identifier" && n.left.name) {
|
|
7719
|
+
acc.add(n.left.name);
|
|
7720
|
+
}
|
|
7721
|
+
if (n.type === "AssignmentExpression" && n.left?.type === "MemberExpression") {
|
|
7722
|
+
let cur = n.left;
|
|
7723
|
+
while (cur?.type === "MemberExpression") cur = cur.object;
|
|
7724
|
+
if (cur?.type === "Identifier" && cur.name) acc.add(cur.name);
|
|
7725
|
+
}
|
|
7726
|
+
if (n.type === "UpdateExpression" && n.argument?.type === "Identifier" && n.argument.name) {
|
|
7727
|
+
acc.add(n.argument.name);
|
|
7728
|
+
}
|
|
7729
|
+
for (const key of Object.keys(n)) {
|
|
7730
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7731
|
+
const child = n[key];
|
|
7732
|
+
if (Array.isArray(child)) child.forEach((c) => collectAssignedIds(c, acc));
|
|
7733
|
+
else if (child && typeof child === "object") collectAssignedIds(child, acc);
|
|
7734
|
+
}
|
|
7735
|
+
}
|
|
7736
|
+
var FUNCTION_SCOPE_TYPES = /* @__PURE__ */ new Set([
|
|
7737
|
+
"FunctionDeclaration",
|
|
7738
|
+
"FunctionExpression",
|
|
7739
|
+
"ArrowFunctionExpression",
|
|
7740
|
+
"ObjectMethod",
|
|
7741
|
+
"ClassMethod",
|
|
7742
|
+
"ClassPrivateMethod"
|
|
7743
|
+
]);
|
|
7744
|
+
var BINDING_SCOPE_TYPES = /* @__PURE__ */ new Set([
|
|
7745
|
+
...FUNCTION_SCOPE_TYPES,
|
|
7746
|
+
"CatchClause",
|
|
7747
|
+
"ForOfStatement",
|
|
7748
|
+
"ForInStatement"
|
|
7749
|
+
]);
|
|
7750
|
+
function collectPatternNames(id, acc) {
|
|
7751
|
+
if (!id || typeof id !== "object") return;
|
|
7752
|
+
const n = id;
|
|
7753
|
+
if (n.type === "Identifier" && n.name) acc.add(n.name);
|
|
7754
|
+
else if (n.type === "RestElement") collectPatternNames(n.argument, acc);
|
|
7755
|
+
else if (n.type === "AssignmentPattern") collectPatternNames(n.left, acc);
|
|
7756
|
+
else if (n.type === "ObjectPattern") {
|
|
7757
|
+
for (const p of n.properties ?? []) {
|
|
7758
|
+
const prop = p;
|
|
7759
|
+
if (prop?.type === "RestElement") collectPatternNames(prop.argument, acc);
|
|
7760
|
+
else collectPatternNames(prop?.value, acc);
|
|
7761
|
+
}
|
|
7762
|
+
} else if (n.type === "ArrayPattern") {
|
|
7763
|
+
for (const el of n.elements ?? []) collectPatternNames(el, acc);
|
|
7764
|
+
}
|
|
7765
|
+
}
|
|
7766
|
+
var freeAssignedCache = /* @__PURE__ */ new WeakMap();
|
|
7767
|
+
var mutatorRecvCache = /* @__PURE__ */ new WeakMap();
|
|
7768
|
+
function collectFreeAssignedNames(...nodes) {
|
|
7769
|
+
const cachedParts = [];
|
|
7770
|
+
const pending = [];
|
|
7771
|
+
for (const node of nodes) {
|
|
7772
|
+
if (node && typeof node === "object") {
|
|
7773
|
+
const hit = freeAssignedCache.get(node);
|
|
7774
|
+
if (hit) {
|
|
7775
|
+
cachedParts.push(hit);
|
|
7776
|
+
continue;
|
|
7777
|
+
}
|
|
7778
|
+
pending.push(node);
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7781
|
+
if (pending.length === 0) {
|
|
7782
|
+
const merged2 = /* @__PURE__ */ new Set();
|
|
7783
|
+
for (const p of cachedParts) for (const n of p) merged2.add(n);
|
|
7784
|
+
return [...merged2];
|
|
7785
|
+
}
|
|
7786
|
+
const free = /* @__PURE__ */ new Set();
|
|
7787
|
+
const markFree = (name, shadowed) => {
|
|
7788
|
+
if (name && name !== "undefined" && !shadowed.has(name)) free.add(name);
|
|
7789
|
+
};
|
|
7790
|
+
const walk = (node, shadowed) => {
|
|
7791
|
+
if (!node || typeof node !== "object") return;
|
|
7792
|
+
const n = node;
|
|
7793
|
+
let nextShadowed = shadowed;
|
|
7794
|
+
const pushShadow = (names) => {
|
|
7795
|
+
const add2 = [];
|
|
7796
|
+
for (const name of names) {
|
|
7797
|
+
if (name && !nextShadowed.has(name)) add2.push(name);
|
|
7798
|
+
}
|
|
7799
|
+
if (add2.length === 0) return;
|
|
7800
|
+
nextShadowed = new Set(nextShadowed);
|
|
7801
|
+
for (const name of add2) nextShadowed.add(name);
|
|
7802
|
+
};
|
|
7803
|
+
if (FUNCTION_SCOPE_TYPES.has(n.type)) {
|
|
7804
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7805
|
+
collectPatternNames(n.id, bound);
|
|
7806
|
+
for (const p of n.params ?? []) collectPatternNames(p, bound);
|
|
7807
|
+
pushShadow(bound);
|
|
7808
|
+
} else if (n.type === "CatchClause") {
|
|
7809
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7810
|
+
collectPatternNames(n.param, bound);
|
|
7811
|
+
pushShadow(bound);
|
|
7812
|
+
} else if (n.type === "ForOfStatement" || n.type === "ForInStatement") {
|
|
7813
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7814
|
+
const left = n.left;
|
|
7815
|
+
if (left?.type === "VariableDeclaration") {
|
|
7816
|
+
for (const d of left.declarations ?? []) collectPatternNames(d.id, bound);
|
|
7817
|
+
} else {
|
|
7818
|
+
collectPatternNames(left, bound);
|
|
7819
|
+
}
|
|
7820
|
+
pushShadow(bound);
|
|
7821
|
+
}
|
|
7822
|
+
if (n.type === "AssignmentExpression") {
|
|
7823
|
+
const left = n.left;
|
|
7824
|
+
if (left?.type === "Identifier") markFree(left.name, nextShadowed);
|
|
7825
|
+
else if (left?.type === "MemberExpression") {
|
|
7826
|
+
let cur = left;
|
|
7827
|
+
while (cur?.type === "MemberExpression") {
|
|
7828
|
+
cur = cur.object;
|
|
7829
|
+
}
|
|
7830
|
+
if (cur?.type === "Identifier") markFree(cur.name, nextShadowed);
|
|
7831
|
+
}
|
|
7832
|
+
}
|
|
7833
|
+
if (n.type === "UpdateExpression") {
|
|
7834
|
+
const arg = n.argument;
|
|
7835
|
+
if (arg?.type === "Identifier") markFree(arg.name, nextShadowed);
|
|
7836
|
+
}
|
|
7837
|
+
if (n.type === "CallExpression" && n.callee?.type === "MemberExpression" && n.callee.computed !== true && n.callee.property?.type === "Identifier" && ARR_MUTATOR_NAMES.has(n.callee.property.name)) {
|
|
7838
|
+
const obj2 = n.callee.object;
|
|
7839
|
+
if (obj2?.type === "Identifier") markFree(obj2.name, nextShadowed);
|
|
7840
|
+
else if (obj2?.type === "MemberExpression" || obj2?.type === "ThisExpression") {
|
|
7841
|
+
let cur = obj2;
|
|
7842
|
+
while (cur?.type === "MemberExpression") {
|
|
7843
|
+
cur = cur.object;
|
|
7844
|
+
}
|
|
7845
|
+
if (cur?.type === "Identifier") markFree(cur.name, nextShadowed);
|
|
7846
|
+
}
|
|
7847
|
+
}
|
|
7848
|
+
for (const key of Object.keys(n)) {
|
|
7849
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7850
|
+
if (key === "callee" || key === "property" || key === "param" || key === "params") continue;
|
|
7851
|
+
const child = n[key];
|
|
7852
|
+
if (Array.isArray(child)) {
|
|
7853
|
+
if (n.type === "BlockStatement" || n.type === "Program" || n.type === "StaticBlock" || n.type === "SwitchCase") {
|
|
7854
|
+
let blockShadow = nextShadowed;
|
|
7855
|
+
for (const stmt of child) {
|
|
7856
|
+
walk(stmt, blockShadow);
|
|
7857
|
+
const stmtNode = stmt;
|
|
7858
|
+
if (!stmtNode) continue;
|
|
7859
|
+
const declared = /* @__PURE__ */ new Set();
|
|
7860
|
+
if (stmtNode.type === "VariableDeclaration") {
|
|
7861
|
+
for (const d of stmtNode.declarations ?? []) collectPatternNames(d.id, declared);
|
|
7862
|
+
} else if (stmtNode.type === "FunctionDeclaration" || stmtNode.type === "ClassDeclaration") {
|
|
7863
|
+
collectPatternNames(stmtNode.id, declared);
|
|
7864
|
+
}
|
|
7865
|
+
if (declared.size > 0) {
|
|
7866
|
+
if (blockShadow === nextShadowed) blockShadow = new Set(blockShadow);
|
|
7867
|
+
for (const name of declared) blockShadow.add(name);
|
|
7868
|
+
}
|
|
7869
|
+
}
|
|
7870
|
+
continue;
|
|
7871
|
+
}
|
|
7872
|
+
for (const item of child) walk(item, nextShadowed);
|
|
7873
|
+
} else if (child && typeof child === "object") {
|
|
7874
|
+
walk(child, nextShadowed);
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
if (FUNCTION_SCOPE_TYPES.has(n.type) && n.body) {
|
|
7878
|
+
walk(n.body, nextShadowed);
|
|
7879
|
+
}
|
|
7880
|
+
};
|
|
7881
|
+
for (const node of pending) {
|
|
7882
|
+
walk(node, /* @__PURE__ */ new Set());
|
|
7883
|
+
}
|
|
7884
|
+
const computed = [...free];
|
|
7885
|
+
for (const node of pending) freeAssignedCache.set(node, computed);
|
|
7886
|
+
const merged = new Set(computed);
|
|
7887
|
+
for (const p of cachedParts) for (const n of p) merged.add(n);
|
|
7888
|
+
return [...merged];
|
|
7889
|
+
}
|
|
7890
|
+
function collectForkBindingNames(...nodes) {
|
|
7891
|
+
return collectFreeAssignedNames(...nodes);
|
|
7892
|
+
}
|
|
7893
|
+
function stmtCompletesControl(stmt) {
|
|
7894
|
+
if (!stmt) return false;
|
|
7895
|
+
switch (stmt.type) {
|
|
7896
|
+
case "BreakStatement":
|
|
7897
|
+
case "ReturnStatement":
|
|
7898
|
+
case "ThrowStatement":
|
|
7899
|
+
case "ContinueStatement":
|
|
7900
|
+
return true;
|
|
7901
|
+
case "BlockStatement":
|
|
7902
|
+
return stmtCompletesControl(stmt.body[stmt.body.length - 1]);
|
|
7903
|
+
case "IfStatement":
|
|
7904
|
+
return stmt.alternate != null && stmtCompletesControl(stmt.consequent) && stmtCompletesControl(stmt.alternate);
|
|
7905
|
+
default:
|
|
7906
|
+
return false;
|
|
7907
|
+
}
|
|
7908
|
+
}
|
|
5943
7909
|
function stmtReturns(stmt) {
|
|
5944
7910
|
if (stmt.type === "ReturnStatement" || stmt.type === "ThrowStatement") return true;
|
|
5945
7911
|
if (stmt.type === "BlockStatement") return stmt.body.some(stmtReturns);
|
|
5946
7912
|
if (stmt.type === "IfStatement") {
|
|
5947
7913
|
return stmtReturns(stmt.consequent) && stmt.alternate != null && stmtReturns(stmt.alternate);
|
|
5948
7914
|
}
|
|
7915
|
+
if (stmt.type === "SwitchStatement") {
|
|
7916
|
+
const arms = [];
|
|
7917
|
+
for (const c of stmt.cases) {
|
|
7918
|
+
const testIsDefault = c.test === null || c.test === void 0;
|
|
7919
|
+
const last = arms[arms.length - 1];
|
|
7920
|
+
if (last && !last.isDefault && last.stmts.length === 0 && !testIsDefault) {
|
|
7921
|
+
last.stmts = c.consequent;
|
|
7922
|
+
continue;
|
|
7923
|
+
}
|
|
7924
|
+
if (last && !last.isDefault && !testIsDefault && last.stmts.length > 0 && c.consequent.length === 0) {
|
|
7925
|
+
continue;
|
|
7926
|
+
}
|
|
7927
|
+
arms.push({ stmts: c.consequent, isDefault: testIsDefault });
|
|
7928
|
+
}
|
|
7929
|
+
const armOk = (a) => a.stmts.length > 0 && a.stmts.every(stmtReturns);
|
|
7930
|
+
const nonDefault = arms.filter((a) => !a.isDefault);
|
|
7931
|
+
const dflt = arms.find((a) => a.isDefault);
|
|
7932
|
+
if (dflt === void 0) return false;
|
|
7933
|
+
return nonDefault.length > 0 && nonDefault.every(armOk) && armOk(dflt);
|
|
7934
|
+
}
|
|
5949
7935
|
return false;
|
|
5950
7936
|
}
|
|
5951
7937
|
function transpileFnBodyStmts(stmts, depth, opts) {
|
|
@@ -5957,11 +7943,61 @@ function transpileFnBodyStmts(stmts, depth, opts) {
|
|
|
5957
7943
|
if (rest.length === 0) continue;
|
|
5958
7944
|
const head = stmts.slice(0, i).map((s) => transpileStatement(s, depth, opts)).join("\n");
|
|
5959
7945
|
const test = transpileExpression(stmt.test, opts);
|
|
5960
|
-
const
|
|
5961
|
-
|
|
5962
|
-
|
|
7946
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
7947
|
+
...collectForkBindingNames(stmt.consequent),
|
|
7948
|
+
...collectForkBindingNames(stmt.test),
|
|
7949
|
+
...rest.flatMap((r) => collectForkBindingNames(r))
|
|
7950
|
+
]);
|
|
7951
|
+
const names = [...recvSet];
|
|
7952
|
+
const pad = indent(depth);
|
|
7953
|
+
const padIn = indent(depth + 1);
|
|
7954
|
+
const wrapArm = (thunk, outPrefix) => {
|
|
7955
|
+
if (names.length === 0) return thunk;
|
|
7956
|
+
return [
|
|
7957
|
+
`() => {`,
|
|
7958
|
+
...names.map((n) => `${padIn}${n} = __fk0_${n};`),
|
|
7959
|
+
`${padIn}let __cont = true;`,
|
|
7960
|
+
`${padIn}try {`,
|
|
7961
|
+
`${padIn} return (${thunk})();`,
|
|
7962
|
+
`${padIn}} catch (e) {`,
|
|
7963
|
+
`${padIn} if ($isForkExit(e)) __cont = false;`,
|
|
7964
|
+
`${padIn} throw e;`,
|
|
7965
|
+
`${padIn}} finally {`,
|
|
7966
|
+
`${padIn} if (__cont) {`,
|
|
7967
|
+
...names.map((n) => `${padIn} __${outPrefix}${n} = ${n};`),
|
|
7968
|
+
...names.map((n) => `${padIn} __${outPrefix}set_${n} = true;`),
|
|
7969
|
+
`${padIn} }`,
|
|
7970
|
+
`${padIn}}`,
|
|
7971
|
+
`}`
|
|
7972
|
+
].join("\n");
|
|
7973
|
+
};
|
|
7974
|
+
const testRecvs = collectArrMutatorReceivers(stmt.test);
|
|
7975
|
+
const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, opts, pad) : [];
|
|
7976
|
+
const cons = wrapArm(transpileBlockAsThunk(stmt.consequent, depth, opts), "fk1_");
|
|
7977
|
+
const altBody = transpileFnBodyStmts(rest, depth + 1, { ...opts, inLoop: opts.inLoop });
|
|
7978
|
+
const altThunk = `() => {
|
|
5963
7979
|
${altBody}
|
|
5964
|
-
${
|
|
7980
|
+
${pad}}`;
|
|
7981
|
+
const alt = wrapArm(altThunk, "fk2_");
|
|
7982
|
+
const inCtrl = (opts.inLoop ?? 0) > 0 || (opts.inTry ?? 0) > 0;
|
|
7983
|
+
const applyJoin = names.length ? forkJoinBindings(names, pad).join("\n") : "";
|
|
7984
|
+
if (names.length === 0) {
|
|
7985
|
+
const promoted2 = [
|
|
7986
|
+
...testRebinds,
|
|
7987
|
+
inCtrl ? `${pad}$loopReturn($fork(${test}, ${cons}, ${alt}));` : `${pad}return $fork(${test}, ${cons}, ${alt});`
|
|
7988
|
+
].join("\n");
|
|
7989
|
+
return head ? `${head}
|
|
7990
|
+
${promoted2}` : promoted2;
|
|
7991
|
+
}
|
|
7992
|
+
const promoted = [
|
|
7993
|
+
`${pad}{`,
|
|
7994
|
+
...testRebinds,
|
|
7995
|
+
...forkBindingDecls(names, padIn),
|
|
7996
|
+
`${padIn}const __fkR = $fork(${test}, ${cons}, ${alt});`,
|
|
7997
|
+
applyJoin.split("\n").map((l) => l.replace(/^\s*/, padIn)).join("\n"),
|
|
7998
|
+
inCtrl ? `${padIn}$loopReturn(__fkR);` : `${padIn}return __fkR;`,
|
|
7999
|
+
`${pad}}`
|
|
8000
|
+
].join("\n");
|
|
5965
8001
|
return head ? `${head}
|
|
5966
8002
|
${promoted}` : promoted;
|
|
5967
8003
|
}
|
|
@@ -5973,11 +8009,18 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
5973
8009
|
return;
|
|
5974
8010
|
}
|
|
5975
8011
|
if (pattern.type === "ObjectPattern") {
|
|
8012
|
+
const namedKeys = [];
|
|
8013
|
+
let restName;
|
|
5976
8014
|
for (const prop of pattern.properties) {
|
|
8015
|
+
if (prop.type === "RestElement") {
|
|
8016
|
+
if (prop.argument.type === "Identifier") restName = prop.argument.name;
|
|
8017
|
+
continue;
|
|
8018
|
+
}
|
|
5977
8019
|
if (prop.type !== "ObjectProperty") continue;
|
|
5978
8020
|
if (prop.key.type !== "Identifier" && prop.key.type !== "StringLiteral") continue;
|
|
5979
8021
|
const key = prop.key.type === "Identifier" ? prop.key.name : String(prop.key.value);
|
|
5980
8022
|
const keyLit = JSON.stringify(key);
|
|
8023
|
+
namedKeys.push(key);
|
|
5981
8024
|
if (prop.value.type === "AssignmentPattern") {
|
|
5982
8025
|
const def = transpileExpression(prop.value.right, opts);
|
|
5983
8026
|
const left = prop.value.left;
|
|
@@ -6002,11 +8045,25 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
6002
8045
|
out.push(`${pad}${kw} ${prop.value.name} = $get(${fromSrc}, ${keyLit});`);
|
|
6003
8046
|
}
|
|
6004
8047
|
}
|
|
8048
|
+
if (restName) {
|
|
8049
|
+
out.push(
|
|
8050
|
+
`${pad}${kw} ${restName} = $objRest(${fromSrc}, ${JSON.stringify(namedKeys)});`
|
|
8051
|
+
);
|
|
8052
|
+
}
|
|
6005
8053
|
return;
|
|
6006
8054
|
}
|
|
6007
8055
|
if (pattern.type === "ArrayPattern") {
|
|
8056
|
+
let restName;
|
|
8057
|
+
let restAt = 0;
|
|
6008
8058
|
pattern.elements.forEach((el, i) => {
|
|
6009
8059
|
if (!el) return;
|
|
8060
|
+
if (el.type === "RestElement") {
|
|
8061
|
+
if (el.argument.type === "Identifier") {
|
|
8062
|
+
restName = el.argument.name;
|
|
8063
|
+
restAt = i;
|
|
8064
|
+
}
|
|
8065
|
+
return;
|
|
8066
|
+
}
|
|
6010
8067
|
if (el.type === "AssignmentPattern") {
|
|
6011
8068
|
const def = transpileExpression(el.right, opts);
|
|
6012
8069
|
const idx = `$idx(${fromSrc}, $lit(${i}))`;
|
|
@@ -6029,6 +8086,9 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
6029
8086
|
out.push(`${pad}${kw} ${el.name} = $idx(${fromSrc}, $lit(${i}));`);
|
|
6030
8087
|
}
|
|
6031
8088
|
});
|
|
8089
|
+
if (restName) {
|
|
8090
|
+
out.push(`${pad}${kw} ${restName} = $arrRest(${fromSrc}, ${restAt});`);
|
|
8091
|
+
}
|
|
6032
8092
|
}
|
|
6033
8093
|
}
|
|
6034
8094
|
function emitParamBinding(params, pad, opts) {
|
|
@@ -6069,6 +8129,122 @@ function emitParamBinding(params, pad, opts) {
|
|
|
6069
8129
|
});
|
|
6070
8130
|
return { sig, rest, prologue };
|
|
6071
8131
|
}
|
|
8132
|
+
function collectArrMutatorReceivers(node, acc = /* @__PURE__ */ new Set()) {
|
|
8133
|
+
if (!node || typeof node !== "object") return acc;
|
|
8134
|
+
const hit = mutatorRecvCache.get(node);
|
|
8135
|
+
if (hit) {
|
|
8136
|
+
for (const n of hit) acc.add(n);
|
|
8137
|
+
return acc;
|
|
8138
|
+
}
|
|
8139
|
+
const local = /* @__PURE__ */ new Set();
|
|
8140
|
+
collectArrMutatorReceiversUncached(node, local);
|
|
8141
|
+
mutatorRecvCache.set(node, local);
|
|
8142
|
+
for (const n of local) acc.add(n);
|
|
8143
|
+
return acc;
|
|
8144
|
+
}
|
|
8145
|
+
function collectArrMutatorReceiversUncached(node, acc = /* @__PURE__ */ new Set()) {
|
|
8146
|
+
if (!node || typeof node !== "object") return acc;
|
|
8147
|
+
const n = node;
|
|
8148
|
+
if (n.type === "FunctionExpression" || n.type === "ArrowFunctionExpression" || n.type === "ObjectMethod" || n.type === "ClassMethod" || n.type === "FunctionDeclaration") {
|
|
8149
|
+
return acc;
|
|
8150
|
+
}
|
|
8151
|
+
if (n.type === "CallExpression" && n.callee?.type === "MemberExpression") {
|
|
8152
|
+
const callee = n.callee;
|
|
8153
|
+
const propName = !callee.computed && callee.property?.type === "Identifier" ? callee.property.name : void 0;
|
|
8154
|
+
if (propName && ARR_MUTATOR_NAMES.has(propName)) {
|
|
8155
|
+
const obj2 = callee.object;
|
|
8156
|
+
if (obj2?.type === "Identifier") {
|
|
8157
|
+
acc.add(obj2.name);
|
|
8158
|
+
} else if (obj2?.type === "MemberExpression") {
|
|
8159
|
+
let cur = obj2;
|
|
8160
|
+
while (cur?.type === "MemberExpression") {
|
|
8161
|
+
cur = cur.object;
|
|
8162
|
+
}
|
|
8163
|
+
if (cur?.type === "Identifier") {
|
|
8164
|
+
acc.add(cur.name);
|
|
8165
|
+
}
|
|
8166
|
+
}
|
|
8167
|
+
}
|
|
8168
|
+
}
|
|
8169
|
+
for (const key of Object.keys(n)) {
|
|
8170
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
8171
|
+
const child = n[key];
|
|
8172
|
+
if (Array.isArray(child)) child.forEach((c) => collectArrMutatorReceiversUncached(c, acc));
|
|
8173
|
+
else if (child && typeof child === "object") collectArrMutatorReceiversUncached(child, acc);
|
|
8174
|
+
}
|
|
8175
|
+
return acc;
|
|
8176
|
+
}
|
|
8177
|
+
function forkArmThunk(bodyLines, outPrefix, names) {
|
|
8178
|
+
return [
|
|
8179
|
+
`() => {`,
|
|
8180
|
+
...names.map((n) => ` ${n} = __fk0_${n};`),
|
|
8181
|
+
` let __cont = true;`,
|
|
8182
|
+
` try {`,
|
|
8183
|
+
...bodyLines.map((l) => ` ${l}`),
|
|
8184
|
+
` } catch (e) {`,
|
|
8185
|
+
` if ($isForkExit(e)) __cont = false;`,
|
|
8186
|
+
` throw e;`,
|
|
8187
|
+
` } finally {`,
|
|
8188
|
+
` if (__cont) {`,
|
|
8189
|
+
...names.map((n) => ` __${outPrefix}${n} = ${n};`),
|
|
8190
|
+
...names.map((n) => ` __${outPrefix}set_${n} = true;`),
|
|
8191
|
+
` }`,
|
|
8192
|
+
` }`,
|
|
8193
|
+
`}`
|
|
8194
|
+
].join("\n");
|
|
8195
|
+
}
|
|
8196
|
+
function forkBindingDecls(names, pad = "") {
|
|
8197
|
+
return names.flatMap((n) => [
|
|
8198
|
+
`${pad}const __fk0_${n} = ${n};`,
|
|
8199
|
+
`${pad}let __fk1_${n}; let __fk2_${n};`,
|
|
8200
|
+
`${pad}let __fk1_set_${n} = false; let __fk2_set_${n} = false;`
|
|
8201
|
+
]);
|
|
8202
|
+
}
|
|
8203
|
+
function forkJoinBindings(names, pad = "") {
|
|
8204
|
+
return names.map(
|
|
8205
|
+
(n) => `${pad}${n} = (__fk1_set_${n} && __fk2_set_${n}) ? $join(__fk1_${n}, __fk2_${n}) : (__fk1_set_${n} ? __fk1_${n} : (__fk2_set_${n} ? __fk2_${n} : ${n}));`
|
|
8206
|
+
);
|
|
8207
|
+
}
|
|
8208
|
+
function transpileShortCircuitExpr(opts, parts) {
|
|
8209
|
+
const alwaysNames = new Set(collectForkBindingNames(...parts.alwaysNodes));
|
|
8210
|
+
const branchNames = new Set(alwaysNames);
|
|
8211
|
+
for (const n of parts.consNodes) for (const id of collectForkBindingNames(n)) branchNames.add(id);
|
|
8212
|
+
for (const n of parts.altNodes) for (const id of collectForkBindingNames(n)) branchNames.add(id);
|
|
8213
|
+
const names = [...branchNames];
|
|
8214
|
+
const alwaysRebinds = [];
|
|
8215
|
+
for (const n of parts.alwaysNodes) {
|
|
8216
|
+
alwaysRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8217
|
+
}
|
|
8218
|
+
const consRebinds = [];
|
|
8219
|
+
for (const n of parts.consNodes) {
|
|
8220
|
+
if (parts.alwaysNodes.includes(n)) continue;
|
|
8221
|
+
consRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8222
|
+
}
|
|
8223
|
+
const altRebinds = [];
|
|
8224
|
+
for (const n of parts.altNodes) {
|
|
8225
|
+
if (parts.alwaysNodes.includes(n)) continue;
|
|
8226
|
+
altRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8227
|
+
}
|
|
8228
|
+
if (alwaysNames.size === 0 && branchNames.size === 0) {
|
|
8229
|
+
const forkTest2 = parts.testSrc ?? parts.alwaysSrc;
|
|
8230
|
+
const consExpr = parts.consSrc === "__test" ? parts.alwaysSrc : parts.consSrc;
|
|
8231
|
+
const altExpr = parts.altSrc === "__test" ? parts.alwaysSrc : parts.altSrc;
|
|
8232
|
+
return `$fork(${forkTest2}, () => ${consExpr}, () => ${altExpr})`;
|
|
8233
|
+
}
|
|
8234
|
+
const consLines = parts.consSrc === "__test" ? [`return __test;`] : consRebinds.length === 0 ? [`return (${parts.consSrc});`] : [`const __v = (${parts.consSrc});`, ...consRebinds, `return __v;`];
|
|
8235
|
+
const altLines = parts.altSrc === "__test" ? [`return __test;`] : altRebinds.length === 0 ? [`return (${parts.altSrc});`] : [`const __v = (${parts.altSrc});`, ...altRebinds, `return __v;`];
|
|
8236
|
+
const forkTest = parts.testSrc ?? "__test";
|
|
8237
|
+
return [
|
|
8238
|
+
`(() => {`,
|
|
8239
|
+
` const __test = (${parts.alwaysSrc});`,
|
|
8240
|
+
...alwaysRebinds.map((l) => ` ${l}`),
|
|
8241
|
+
...names.length ? forkBindingDecls(names, " ") : [],
|
|
8242
|
+
` const __r = $fork(${forkTest}, ${forkArmThunk(consLines, "fk1_", names)}, ${forkArmThunk(altLines, "fk2_", names)});`,
|
|
8243
|
+
...forkJoinBindings(names, " "),
|
|
8244
|
+
` return __r;`,
|
|
8245
|
+
`})()`
|
|
8246
|
+
].join("\n");
|
|
8247
|
+
}
|
|
6072
8248
|
function transpileStatement(stmt, depth, opts) {
|
|
6073
8249
|
const pad = indent(depth);
|
|
6074
8250
|
switch (stmt.type) {
|
|
@@ -6106,20 +8282,22 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6106
8282
|
}
|
|
6107
8283
|
case "FunctionDeclaration": {
|
|
6108
8284
|
if (!stmt.id) return `${pad}// <anonymous fn skipped>`;
|
|
8285
|
+
const exportKw = depth === 0 ? "export " : "";
|
|
8286
|
+
const fnOpts = { ...opts, inLoop: 0 };
|
|
6109
8287
|
const { sig, rest, prologue } = emitParamBinding(
|
|
6110
8288
|
stmt.params,
|
|
6111
8289
|
indent(depth + 2),
|
|
6112
|
-
|
|
8290
|
+
fnOpts
|
|
6113
8291
|
);
|
|
6114
8292
|
const named = sig;
|
|
6115
8293
|
const paramsSig = rest ? [...named, `...${rest}`] : named;
|
|
6116
8294
|
const params = paramsSig.join(", ");
|
|
6117
|
-
const bodyStmts = stmt.body.type === "BlockStatement" ? [...prologue, transpileFnBodyStmts(stmt.body.body, depth + 2,
|
|
8295
|
+
const bodyStmts = stmt.body.type === "BlockStatement" ? [...prologue, transpileFnBodyStmts(stmt.body.body, depth + 2, fnOpts)].join("\n") : `${indent(depth + 2)}return ${transpileExpression(stmt.body, fnOpts)};`;
|
|
6118
8296
|
const restBind = rest ? `${indent(depth + 1)}const ${rest} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
|
|
6119
8297
|
` : "";
|
|
6120
8298
|
if (stmt.generator) {
|
|
6121
8299
|
return [
|
|
6122
|
-
`${pad}
|
|
8300
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6123
8301
|
restBind,
|
|
6124
8302
|
`${indent(depth + 1)}return $gen(() => {`,
|
|
6125
8303
|
bodyStmts,
|
|
@@ -6129,7 +8307,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6129
8307
|
}
|
|
6130
8308
|
if (stmt.async) {
|
|
6131
8309
|
return [
|
|
6132
|
-
`${pad}
|
|
8310
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6133
8311
|
restBind,
|
|
6134
8312
|
`${indent(depth + 1)}return $async(() => {`,
|
|
6135
8313
|
bodyStmts,
|
|
@@ -6138,7 +8316,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6138
8316
|
].join("\n");
|
|
6139
8317
|
}
|
|
6140
8318
|
return [
|
|
6141
|
-
`${pad}
|
|
8319
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6142
8320
|
restBind,
|
|
6143
8321
|
bodyStmts,
|
|
6144
8322
|
`${pad}}`
|
|
@@ -6146,16 +8324,73 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6146
8324
|
}
|
|
6147
8325
|
case "ReturnStatement": {
|
|
6148
8326
|
const asVar = matchAsOverride(stmt, opts);
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
8327
|
+
const prefix = (opts.inLoop ?? 0) > 0 ? "$loopReturn" : "return";
|
|
8328
|
+
const markExpr = opts.tryMarkName ?? "$tryCurrentMark()";
|
|
8329
|
+
const emitRet = (src, mutNodes) => {
|
|
8330
|
+
const retRebinds = mutNodes ? emitArrMutatorRebinds(mutNodes, opts, pad) : [];
|
|
8331
|
+
if ((opts.inTry ?? 0) > 0) {
|
|
8332
|
+
return [
|
|
8333
|
+
`${pad}const __nudoRet = ${src};`,
|
|
8334
|
+
...retRebinds,
|
|
8335
|
+
`${pad}{`,
|
|
8336
|
+
`${indent(depth + 1)}const __xs = $tryTakeSince(${markExpr});`,
|
|
8337
|
+
`${indent(depth + 1)}if (__xs.length) {`,
|
|
8338
|
+
`${indent(depth + 2)}$pushLoopExit(__nudoRet);`,
|
|
8339
|
+
`${indent(depth + 2)}$throw(__xs.reduce((a, b) => $join(a, b)));`,
|
|
8340
|
+
`${indent(depth + 1)}}`,
|
|
8341
|
+
`${pad}}`,
|
|
8342
|
+
`${pad}${prefix}(__nudoRet);`
|
|
8343
|
+
].join("\n");
|
|
8344
|
+
}
|
|
8345
|
+
if (retRebinds.length === 0) return `${pad}${prefix}(${src});`;
|
|
8346
|
+
return [
|
|
8347
|
+
`${pad}let __mutRet = ${src};`,
|
|
8348
|
+
...retRebinds,
|
|
8349
|
+
`${pad}${prefix}(__mutRet);`
|
|
8350
|
+
].join("\n");
|
|
8351
|
+
};
|
|
8352
|
+
if (asVar) return emitRet(asVar);
|
|
8353
|
+
if (!stmt.argument) return emitRet(`$lit(undefined)`);
|
|
8354
|
+
const retSrc = transpileExpression(stmt.argument, opts);
|
|
8355
|
+
return emitRet(retSrc, stmt.argument);
|
|
6152
8356
|
}
|
|
6153
8357
|
case "ThrowStatement": {
|
|
6154
8358
|
const arg = stmt.argument ? transpileExpression(stmt.argument, opts) : "$lit(undefined)";
|
|
6155
8359
|
return `${pad}$throw(${arg});`;
|
|
6156
8360
|
}
|
|
6157
|
-
case "ExpressionStatement":
|
|
8361
|
+
case "ExpressionStatement": {
|
|
8362
|
+
const expr = stmt.expression;
|
|
8363
|
+
const exprRebinds = emitArrMutatorRebinds(expr, opts, pad);
|
|
8364
|
+
if (expr.type === "CallExpression" && expr.callee.type === "MemberExpression" && !expr.callee.computed && expr.callee.property.type === "Identifier") {
|
|
8365
|
+
const methodName = expr.callee.property.name;
|
|
8366
|
+
if (["push", "unshift", "splice", "pop", "shift", "reverse", "sort"].includes(methodName)) {
|
|
8367
|
+
const argSrcs = expr.arguments.map(
|
|
8368
|
+
(a) => a.type === "SpreadElement" ? "$lit(undefined)" : transpileExpression(a, opts)
|
|
8369
|
+
).join(", ");
|
|
8370
|
+
const objNode = expr.callee.object;
|
|
8371
|
+
if (objNode.type === "Identifier") {
|
|
8372
|
+
const name = objNode.name;
|
|
8373
|
+
return `${pad}${name} = $arrMutContainer(${name}, ${JSON.stringify(methodName)}, [${argSrcs}]);`;
|
|
8374
|
+
}
|
|
8375
|
+
if (objNode.type === "MemberExpression" || objNode.type === "ThisExpression") {
|
|
8376
|
+
const path = objNode.type === "MemberExpression" ? memberPathOf(objNode, opts) : null;
|
|
8377
|
+
if (path) {
|
|
8378
|
+
const recvSrc = readPathSrc(path);
|
|
8379
|
+
const mutSrc = `$arrMutContainer(${recvSrc}, ${JSON.stringify(methodName)}, [${argSrcs}])`;
|
|
8380
|
+
return `${pad}${path.rootSrc} = ${setPathSrc(path, mutSrc)};`;
|
|
8381
|
+
}
|
|
8382
|
+
return `${pad}${transpileExpression(stmt.expression, opts)};`;
|
|
8383
|
+
}
|
|
8384
|
+
}
|
|
8385
|
+
}
|
|
8386
|
+
if (exprRebinds.length > 0) {
|
|
8387
|
+
return [
|
|
8388
|
+
`${pad}${transpileExpression(expr, opts)};`,
|
|
8389
|
+
...exprRebinds
|
|
8390
|
+
].join("\n");
|
|
8391
|
+
}
|
|
6158
8392
|
return `${pad}${transpileExpression(stmt.expression, opts)};`;
|
|
8393
|
+
}
|
|
6159
8394
|
case "VariableDeclaration": {
|
|
6160
8395
|
const kw = "let";
|
|
6161
8396
|
const asVar = matchAsOverride(stmt, opts);
|
|
@@ -6165,6 +8400,9 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6165
8400
|
if (d.id.type === "Identifier") {
|
|
6166
8401
|
const init = asVar ? asVar : d.init ? transpileExpression(d.init, opts) : "$lit(undefined)";
|
|
6167
8402
|
lines.push(`${pad}${kw} ${d.id.name} = ${init};`);
|
|
8403
|
+
if (d.init && !asVar) {
|
|
8404
|
+
lines.push(...emitArrMutatorRebinds(d.init, opts, pad));
|
|
8405
|
+
}
|
|
6168
8406
|
continue;
|
|
6169
8407
|
}
|
|
6170
8408
|
if (!d.init) {
|
|
@@ -6174,18 +8412,74 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6174
8412
|
const initSrc = transpileExpression(d.init, opts);
|
|
6175
8413
|
const tmp = `_d${tmpSeq++}_${stmt.loc?.start.line ?? 0}`;
|
|
6176
8414
|
lines.push(`${pad}const ${tmp} = ${initSrc};`);
|
|
8415
|
+
lines.push(...emitArrMutatorRebinds(d.init, opts, pad));
|
|
6177
8416
|
emitDestructure(d.id, tmp, kw, pad, opts, lines, { n: 0 });
|
|
6178
8417
|
}
|
|
6179
8418
|
return lines.join("\n");
|
|
6180
8419
|
}
|
|
6181
8420
|
case "IfStatement": {
|
|
6182
8421
|
const test = transpileExpression(stmt.test, opts);
|
|
6183
|
-
const
|
|
6184
|
-
|
|
8422
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
8423
|
+
...collectForkBindingNames(stmt.consequent),
|
|
8424
|
+
...collectForkBindingNames(stmt.alternate)
|
|
8425
|
+
]);
|
|
8426
|
+
const testRecvs = collectArrMutatorReceivers(stmt.test);
|
|
8427
|
+
const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, opts, pad) : [];
|
|
8428
|
+
const names = [...recvSet];
|
|
8429
|
+
const padIn = indent(depth + 1);
|
|
8430
|
+
const padDecl = names.length > 0 ? padIn : pad;
|
|
8431
|
+
const wrapArm = (thunk, outPrefix) => {
|
|
8432
|
+
if (names.length === 0) return thunk;
|
|
8433
|
+
return [
|
|
8434
|
+
`() => {`,
|
|
8435
|
+
...names.map((n) => `${padIn}${n} = __fk0_${n};`),
|
|
8436
|
+
`${padIn}let __cont = true;`,
|
|
8437
|
+
`${padIn}try {`,
|
|
8438
|
+
`${padIn} return (${thunk})();`,
|
|
8439
|
+
`${padIn}} catch (e) {`,
|
|
8440
|
+
`${padIn} if ($isForkExit(e)) __cont = false;`,
|
|
8441
|
+
`${padIn} throw e;`,
|
|
8442
|
+
`${padIn}} finally {`,
|
|
8443
|
+
`${padIn} if (__cont) {`,
|
|
8444
|
+
...names.map((n) => `${padIn} __${outPrefix}${n} = ${n};`),
|
|
8445
|
+
...names.map((n) => `${padIn} __${outPrefix}set_${n} = true;`),
|
|
8446
|
+
`${padIn} }`,
|
|
8447
|
+
`${padIn}}`,
|
|
8448
|
+
`}`
|
|
8449
|
+
].join("\n");
|
|
8450
|
+
};
|
|
8451
|
+
const consRaw = transpileBlockAsThunk(stmt.consequent, depth, opts);
|
|
8452
|
+
const altRaw = stmt.alternate ? transpileBlockAsThunk(stmt.alternate, depth, opts) : "undefined";
|
|
8453
|
+
const cons = wrapArm(consRaw, "fk1_");
|
|
8454
|
+
const alt = names.length ? wrapArm(altRaw === "undefined" ? "() => $lit(undefined)" : altRaw, "fk2_") : altRaw;
|
|
8455
|
+
const joinLines = names.length ? [...testRebinds, ...forkBindingDecls(names, padDecl)] : testRebinds;
|
|
8456
|
+
const applyJoin = names.length ? forkJoinBindings(names, padDecl).join("\n") : "";
|
|
8457
|
+
const inCtrl = (opts.inLoop ?? 0) > 0;
|
|
8458
|
+
const openBlock = names.length > 0 ? `${pad}{` : null;
|
|
8459
|
+
const closeBlock = names.length > 0 ? `${pad}}` : null;
|
|
6185
8460
|
if (stmtReturns(stmt.consequent) && stmt.alternate !== void 0 && stmt.alternate !== null && stmtReturns(stmt.alternate)) {
|
|
6186
|
-
|
|
8461
|
+
if (names.length === 0) {
|
|
8462
|
+
return [
|
|
8463
|
+
...joinLines,
|
|
8464
|
+
inCtrl ? `${pad}$loopReturn($fork(${test}, ${cons}, ${alt}));` : `${pad}return $fork(${test}, ${cons}, ${alt});`
|
|
8465
|
+
].join("\n");
|
|
8466
|
+
}
|
|
8467
|
+
return [
|
|
8468
|
+
openBlock,
|
|
8469
|
+
...joinLines,
|
|
8470
|
+
`${padDecl}const __fkR = $fork(${test}, ${cons}, ${alt});`,
|
|
8471
|
+
applyJoin,
|
|
8472
|
+
inCtrl ? `${padDecl}$loopReturn(__fkR);` : `${padDecl}return __fkR;`,
|
|
8473
|
+
closeBlock
|
|
8474
|
+
].join("\n");
|
|
6187
8475
|
}
|
|
6188
|
-
return
|
|
8476
|
+
return [
|
|
8477
|
+
openBlock,
|
|
8478
|
+
...joinLines,
|
|
8479
|
+
`${padDecl}$fork(${test}, ${cons}, ${alt});`,
|
|
8480
|
+
applyJoin,
|
|
8481
|
+
closeBlock
|
|
8482
|
+
].filter((l) => l !== null && l !== "").join("\n");
|
|
6189
8483
|
}
|
|
6190
8484
|
case "ForStatement": {
|
|
6191
8485
|
const initName = extractForInitName(stmt.init);
|
|
@@ -6193,8 +8487,21 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6193
8487
|
const initExpr = stmt.init && stmt.init.type === "VariableDeclaration" && stmt.init.declarations[0]?.init ? transpileExpression(stmt.init.declarations[0].init, opts) : "$lit(undefined)";
|
|
6194
8488
|
const testSrc = stmt.test ? transpileExpression(stmt.test, opts) : "$lit(true)";
|
|
6195
8489
|
const updateSrc = stmt.update ? transpileExpression(stmt.update, opts) : `$lit(undefined)`;
|
|
6196
|
-
const
|
|
8490
|
+
const forBodyOpts = {
|
|
8491
|
+
...opts,
|
|
8492
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8493
|
+
};
|
|
8494
|
+
const bodyStmts = stmt.body.type === "BlockStatement" ? stmt.body.body.map((s) => transpileStatement(s, depth + 2, forBodyOpts)).join("\n") : transpileStatement(stmt.body, depth + 2, forBodyOpts);
|
|
6197
8495
|
const max = opts.maxLoopIters ?? 8;
|
|
8496
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8497
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8498
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8499
|
+
collectAssignedIds(stmt.update, assigned);
|
|
8500
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8501
|
+
const names = [...assigned].filter((n) => n !== initName && n !== "undefined");
|
|
8502
|
+
const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8503
|
+
const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
8504
|
+
const optsSrc = packSrc && unpackSrc ? `, { pack: () => ${packSrc}, unpack: ${unpackSrc} }` : "";
|
|
6198
8505
|
return [
|
|
6199
8506
|
`${pad}// for \u2192 $for (bounded unroll, max=${max})`,
|
|
6200
8507
|
`${pad}$for(`,
|
|
@@ -6205,7 +8512,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6205
8512
|
bodyStmts,
|
|
6206
8513
|
`${indent(depth + 1)} return ${initName};`,
|
|
6207
8514
|
`${indent(depth + 1)}},`,
|
|
6208
|
-
`${indent(depth + 1)}${max}`,
|
|
8515
|
+
`${indent(depth + 1)}${max}${optsSrc}`,
|
|
6209
8516
|
`${pad});`
|
|
6210
8517
|
].join("\n");
|
|
6211
8518
|
}
|
|
@@ -6213,58 +8520,172 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6213
8520
|
return transpileFnBodyStmts(stmt.body, depth, opts);
|
|
6214
8521
|
case "SwitchStatement": {
|
|
6215
8522
|
const disc = transpileExpression(stmt.discriminant, opts);
|
|
6216
|
-
const
|
|
8523
|
+
const pre = [];
|
|
8524
|
+
let pendingTests = [];
|
|
6217
8525
|
for (const c of stmt.cases) {
|
|
6218
8526
|
const testSrc = c.test ? transpileExpression(c.test, opts) : null;
|
|
6219
8527
|
if (testSrc === null) {
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
arms.push({ tests: [testSrc], stmts: c.consequent, isDefault: false });
|
|
8528
|
+
if (pendingTests.length > 0 && c.consequent.length > 0) {
|
|
8529
|
+
pre.push({ tests: pendingTests, stmts: c.consequent, isDefault: false });
|
|
8530
|
+
pendingTests = [];
|
|
8531
|
+
}
|
|
8532
|
+
pre.push({ tests: [], stmts: c.consequent, isDefault: true });
|
|
8533
|
+
continue;
|
|
6227
8534
|
}
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
if (merged.length > 0 && merged[merged.length - 1].stmts === arm.stmts && !arm.isDefault) {
|
|
6232
|
-
merged[merged.length - 1].tests.push(...arm.tests);
|
|
6233
|
-
} else {
|
|
6234
|
-
merged.push({ ...arm, tests: [...arm.tests] });
|
|
8535
|
+
if (c.consequent.length === 0) {
|
|
8536
|
+
pendingTests.push(testSrc);
|
|
8537
|
+
continue;
|
|
6235
8538
|
}
|
|
8539
|
+
pre.push({ tests: [...pendingTests, testSrc], stmts: c.consequent, isDefault: false });
|
|
8540
|
+
pendingTests = [];
|
|
8541
|
+
}
|
|
8542
|
+
if (pendingTests.length > 0) {
|
|
8543
|
+
pre.push({ tests: pendingTests, stmts: [], isDefault: false });
|
|
8544
|
+
}
|
|
8545
|
+
const merged = pre.map((arm) => ({ ...arm, tests: [...arm.tests], stmts: [...arm.stmts] }));
|
|
8546
|
+
for (let i = 0; i < merged.length; i++) {
|
|
8547
|
+
const arm = merged[i];
|
|
8548
|
+
const body = [...arm.stmts];
|
|
8549
|
+
let j = i + 1;
|
|
8550
|
+
while (j < merged.length && !stmtCompletesControl(body[body.length - 1])) {
|
|
8551
|
+
body.push(...merged[j].stmts);
|
|
8552
|
+
if (stmtCompletesControl(body[body.length - 1])) break;
|
|
8553
|
+
j++;
|
|
8554
|
+
}
|
|
8555
|
+
arm.stmts = body;
|
|
6236
8556
|
}
|
|
8557
|
+
const armReturns = (arm) => arm.stmts.length > 0 && arm.stmts.every(stmtReturns);
|
|
8558
|
+
const nonDefaultArms = merged.filter((a) => !a.isDefault);
|
|
8559
|
+
const defaultArm = merged.find((a) => a.isDefault);
|
|
8560
|
+
const allReturn = defaultArm !== void 0 && nonDefaultArms.length > 0 && nonDefaultArms.every(armReturns) && armReturns(defaultArm);
|
|
6237
8561
|
const caseLines = [];
|
|
8562
|
+
const sharedBodyDecls = [];
|
|
6238
8563
|
let defaultSrc = null;
|
|
8564
|
+
const bodyIdxBase = switchBodySeq;
|
|
8565
|
+
let bodyIdx = 0;
|
|
8566
|
+
const armOpts = {
|
|
8567
|
+
...opts,
|
|
8568
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8569
|
+
};
|
|
8570
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
8571
|
+
...merged.flatMap((a) => collectForkBindingNames(...a.stmts)),
|
|
8572
|
+
...collectForkBindingNames(stmt.discriminant)
|
|
8573
|
+
]);
|
|
8574
|
+
const names = [...recvSet];
|
|
8575
|
+
const nArms = merged.filter((a) => !a.isDefault).length + (defaultArm ? 1 : 0) + (defaultArm ? 0 : 1);
|
|
8576
|
+
const wrapArmThunk = (thunk, outIdx) => {
|
|
8577
|
+
if (names.length === 0) return thunk;
|
|
8578
|
+
return [
|
|
8579
|
+
`() => {`,
|
|
8580
|
+
...names.map((n) => `${indent(depth + 1)}${n} = __sw0_${n};`),
|
|
8581
|
+
`${indent(depth + 1)}let __cont = true;`,
|
|
8582
|
+
`${indent(depth + 1)}try {`,
|
|
8583
|
+
`${indent(depth + 2)}return (${thunk})();`,
|
|
8584
|
+
`${indent(depth + 1)}} catch (e) {`,
|
|
8585
|
+
`${indent(depth + 2)}if ($isForkExit(e)) __cont = false;`,
|
|
8586
|
+
`${indent(depth + 2)}throw e;`,
|
|
8587
|
+
`${indent(depth + 1)}} finally {`,
|
|
8588
|
+
`${indent(depth + 2)}if (__cont) {`,
|
|
8589
|
+
...names.map((n) => `${indent(depth + 3)}__sw${outIdx + 1}_${n} = ${n};`),
|
|
8590
|
+
...names.map((n) => `${indent(depth + 3)}__sw${outIdx + 1}set_${n} = true;`),
|
|
8591
|
+
`${indent(depth + 2)}}`,
|
|
8592
|
+
`${indent(depth + 1)}}`,
|
|
8593
|
+
`}`
|
|
8594
|
+
].join("\n");
|
|
8595
|
+
};
|
|
8596
|
+
let armSeq = 0;
|
|
6239
8597
|
for (const arm of merged) {
|
|
6240
|
-
const body = arm.stmts.map((s) => transpileStatement(s, depth + 2,
|
|
6241
|
-
const
|
|
8598
|
+
const body = arm.stmts.length === 0 ? "" : arm.stmts.map((s) => transpileStatement(s, depth + 2, armOpts)).join("\n");
|
|
8599
|
+
const rawThunk = `() => {
|
|
6242
8600
|
${body}
|
|
6243
8601
|
${indent(depth + 1)}}`;
|
|
8602
|
+
const thunk = wrapArmThunk(rawThunk, armSeq);
|
|
8603
|
+
armSeq++;
|
|
8604
|
+
const shared = arm.tests.length > 1 && !arm.isDefault;
|
|
8605
|
+
const runRef = shared ? `__swBody${bodyIdxBase + bodyIdx++}` : thunk;
|
|
8606
|
+
if (shared) {
|
|
8607
|
+
sharedBodyDecls.push(`${pad}const ${runRef} = ${thunk};`);
|
|
8608
|
+
}
|
|
6244
8609
|
if (arm.isDefault) {
|
|
6245
8610
|
defaultSrc = thunk;
|
|
6246
8611
|
} else {
|
|
6247
8612
|
for (const t of arm.tests) {
|
|
6248
|
-
caseLines.push(`{ test: ${t}, run: ${
|
|
8613
|
+
caseLines.push(`{ test: ${t}, run: ${runRef} },`);
|
|
6249
8614
|
}
|
|
6250
8615
|
}
|
|
6251
8616
|
}
|
|
8617
|
+
if (!defaultArm && names.length > 0) {
|
|
8618
|
+
defaultSrc = wrapArmThunk(`() => {
|
|
8619
|
+
${indent(depth + 2)}return $lit(undefined);
|
|
8620
|
+
${indent(depth + 1)}}`, armSeq);
|
|
8621
|
+
}
|
|
8622
|
+
switchBodySeq += Math.max(bodyIdx, 1);
|
|
6252
8623
|
const dflt = defaultSrc ? `, ${defaultSrc}` : "";
|
|
8624
|
+
const discRebinds = collectArrMutatorReceivers(stmt.discriminant).size ? emitArrMutatorRebinds(stmt.discriminant, opts, pad) : [];
|
|
8625
|
+
const switchCall = `$switch(${disc}, [
|
|
8626
|
+
${caseLines.map((l) => indent(depth + 1) + l).join("\n")}
|
|
8627
|
+
${indent(depth + 1)}]${dflt})`;
|
|
8628
|
+
if (names.length === 0) {
|
|
8629
|
+
return [
|
|
8630
|
+
...discRebinds,
|
|
8631
|
+
...sharedBodyDecls,
|
|
8632
|
+
allReturn ? `${pad}return ${switchCall};` : `${pad}${switchCall};`
|
|
8633
|
+
].join("\n");
|
|
8634
|
+
}
|
|
8635
|
+
const decls = names.flatMap((n) => [
|
|
8636
|
+
`${pad}const __sw0_${n} = ${n};`,
|
|
8637
|
+
...Array.from(
|
|
8638
|
+
{ length: Math.max(nArms, armSeq + (defaultArm ? 0 : 1)) },
|
|
8639
|
+
(_, i) => `${pad}let __sw${i + 1}_${n}; let __sw${i + 1}set_${n} = false;`
|
|
8640
|
+
)
|
|
8641
|
+
]);
|
|
8642
|
+
const slotCount = Math.max(nArms, armSeq + (defaultArm ? 0 : 1));
|
|
8643
|
+
const joins = names.map((n) => {
|
|
8644
|
+
const slots = Array.from(
|
|
8645
|
+
{ length: slotCount },
|
|
8646
|
+
(_, i) => `(__sw${i + 1}set_${n} ? __sw${i + 1}_${n} : null)`
|
|
8647
|
+
);
|
|
8648
|
+
return `${pad}${n} = (() => { const __p = [${slots.join(",")}].filter((x) => x !== null); return __p.length === 0 ? ${n} : __p.reduce((a, b) => $join(a, b)); })();`;
|
|
8649
|
+
});
|
|
6253
8650
|
return [
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
8651
|
+
...discRebinds,
|
|
8652
|
+
`${pad}{`,
|
|
8653
|
+
...decls.map((l) => l.replace(new RegExp(`^${pad}`), `${pad}`)),
|
|
8654
|
+
...sharedBodyDecls.map(
|
|
8655
|
+
(l) => l.startsWith(pad) ? `${pad}${l.slice(pad.length)}` : `${pad}${l}`
|
|
8656
|
+
),
|
|
8657
|
+
`${pad}const __swR = ${switchCall};`,
|
|
8658
|
+
...joins,
|
|
8659
|
+
allReturn ? `${pad}return __swR;` : null,
|
|
8660
|
+
`${pad}}`
|
|
8661
|
+
].filter((l) => l !== null).join("\n");
|
|
6258
8662
|
}
|
|
6259
8663
|
case "TryStatement": {
|
|
6260
|
-
const
|
|
6261
|
-
const
|
|
8664
|
+
const markName = `__nudoTm_${stmt.loc?.start.line ?? 0}`;
|
|
8665
|
+
const tryOpts = {
|
|
8666
|
+
...opts,
|
|
8667
|
+
inTry: (opts.inTry ?? 0) + 1,
|
|
8668
|
+
tryMarkName: markName
|
|
8669
|
+
};
|
|
8670
|
+
const tryBody = stmt.block.type === "BlockStatement" ? stmt.block.body.map((s) => transpileStatement(s, depth + 1, tryOpts)).join("\n") : transpileStatement(stmt.block, depth + 1, tryOpts);
|
|
8671
|
+
const lines = [
|
|
8672
|
+
`${pad}const ${markName} = $tryMark();`,
|
|
8673
|
+
`${pad}try {`,
|
|
8674
|
+
tryBody,
|
|
8675
|
+
`${pad}}`
|
|
8676
|
+
];
|
|
8677
|
+
const catchParam = stmt.handler?.param?.type === "Identifier" ? stmt.handler.param.name : "e";
|
|
8678
|
+
const catchTmp = `__nudoE_${stmt.loc?.start.line ?? 0}`;
|
|
8679
|
+
const transpileCatchBody = (d, o) => !stmt.handler ? "" : stmt.handler.body.type === "BlockStatement" ? stmt.handler.body.body.map((s) => transpileStatement(s, d, o)).join("\n") : transpileStatement(stmt.handler.body, d, o);
|
|
6262
8680
|
if (stmt.handler) {
|
|
6263
|
-
const
|
|
6264
|
-
const catchTmp = `__nudoE_${stmt.loc?.start.line ?? 0}`;
|
|
6265
|
-
const catchBody = stmt.handler.body.type === "BlockStatement" ? stmt.handler.body.body.map((s) => transpileStatement(s, depth + 1, opts)).join("\n") : transpileStatement(stmt.handler.body, depth + 1, opts);
|
|
8681
|
+
const catchBody = transpileCatchBody(depth + 1, opts);
|
|
6266
8682
|
lines.push(`${pad}catch (${catchTmp}) {`);
|
|
6267
|
-
lines.push(`${indent(depth + 1)}
|
|
8683
|
+
lines.push(`${indent(depth + 1)}$rethrowIfNudoReturn(${catchTmp});`);
|
|
8684
|
+
lines.push(`${indent(depth + 1)}const __xs_${markName} = $tryTakeSince(${markName});`);
|
|
8685
|
+
lines.push(`${indent(depth + 1)}__xs_${markName}.push($catchVal(${catchTmp}));`);
|
|
8686
|
+
lines.push(
|
|
8687
|
+
`${indent(depth + 1)}const ${catchParam} = __xs_${markName}.reduce((a, b) => $join(a, b));`
|
|
8688
|
+
);
|
|
6268
8689
|
lines.push(catchBody);
|
|
6269
8690
|
lines.push(`${pad}}`);
|
|
6270
8691
|
}
|
|
@@ -6272,6 +8693,30 @@ ${indent(depth + 1)}}`;
|
|
|
6272
8693
|
const finBody = stmt.finalizer.type === "BlockStatement" ? stmt.finalizer.body.map((s) => transpileStatement(s, depth + 1, opts)).join("\n") : transpileStatement(stmt.finalizer, depth + 1, opts);
|
|
6273
8694
|
lines.push(`${pad}finally {`);
|
|
6274
8695
|
lines.push(finBody);
|
|
8696
|
+
lines.push(`${pad}$tryPopMark();`);
|
|
8697
|
+
lines.push(`${pad}}`);
|
|
8698
|
+
} else {
|
|
8699
|
+
lines.push(`${pad}$tryPopMark();`);
|
|
8700
|
+
}
|
|
8701
|
+
if (stmt.handler) {
|
|
8702
|
+
const catchBody = transpileCatchBody(depth + 2, opts);
|
|
8703
|
+
lines.push(`${pad}{`);
|
|
8704
|
+
lines.push(`${indent(depth + 1)}const __post_${markName} = $tryTakeSince(${markName});`);
|
|
8705
|
+
lines.push(`${indent(depth + 1)}if (__post_${markName}.length) {`);
|
|
8706
|
+
lines.push(
|
|
8707
|
+
`${indent(depth + 2)}const ${catchParam} = __post_${markName}.reduce((a, b) => $join(a, b));`
|
|
8708
|
+
);
|
|
8709
|
+
lines.push(
|
|
8710
|
+
catchBody.split("\n").map((l) => l ? `${indent(depth + 2)}${l.trimStart()}` : l).join("\n")
|
|
8711
|
+
);
|
|
8712
|
+
lines.push(`${indent(depth + 1)}}`);
|
|
8713
|
+
lines.push(`${pad}}`);
|
|
8714
|
+
} else {
|
|
8715
|
+
lines.push(`${pad}{`);
|
|
8716
|
+
lines.push(`${indent(depth + 1)}const __post_${markName} = $tryTakeSince(${markName});`);
|
|
8717
|
+
lines.push(`${indent(depth + 1)}if (__post_${markName}.length) {`);
|
|
8718
|
+
lines.push(`${indent(depth + 2)}$throw(__post_${markName}.reduce((a, b) => $join(a, b)));`);
|
|
8719
|
+
lines.push(`${indent(depth + 1)}}`);
|
|
6275
8720
|
lines.push(`${pad}}`);
|
|
6276
8721
|
}
|
|
6277
8722
|
return lines.join("\n");
|
|
@@ -6300,24 +8745,77 @@ ${indent(depth + 1)}}`;
|
|
|
6300
8745
|
{ n: 0 }
|
|
6301
8746
|
);
|
|
6302
8747
|
}
|
|
6303
|
-
const
|
|
8748
|
+
const bodyOpts = {
|
|
8749
|
+
...opts,
|
|
8750
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8751
|
+
};
|
|
8752
|
+
const bodyStmts = stmt.body.type === "BlockStatement" ? stmt.body.body.map((s) => transpileStatement(s, depth + 2, bodyOpts)).join("\n") : transpileStatement(stmt.body, depth + 2, bodyOpts);
|
|
6304
8753
|
const max = opts.maxLoopIters ?? 8;
|
|
8754
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8755
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8756
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8757
|
+
const names = [...assigned].filter((n) => n !== bindName && n !== "undefined");
|
|
8758
|
+
const optsSrc = names.length === 0 ? "" : `, { pack: () => $obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} }), unpack: (__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} } }`;
|
|
6305
8759
|
return [
|
|
6306
8760
|
`${pad}$forOf(${iter}, (${bindName}, _i) => {`,
|
|
6307
8761
|
...bodyLines,
|
|
6308
8762
|
bodyStmts,
|
|
6309
|
-
`${pad}}, ${max});`
|
|
8763
|
+
`${pad}}, ${max}${optsSrc});`
|
|
6310
8764
|
].join("\n");
|
|
6311
8765
|
}
|
|
6312
8766
|
case "WhileStatement": {
|
|
6313
8767
|
const test = transpileExpression(stmt.test, opts);
|
|
6314
|
-
const
|
|
8768
|
+
const bodyOpts = {
|
|
8769
|
+
...opts,
|
|
8770
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8771
|
+
};
|
|
8772
|
+
const body = stmt.body.type === "BlockStatement" ? stmt.body.body.map((s) => transpileStatement(s, depth + 1, bodyOpts)).join("\n") : transpileStatement(stmt.body, depth + 1, bodyOpts);
|
|
6315
8773
|
const max = opts.maxLoopIters ?? 8;
|
|
8774
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8775
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8776
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8777
|
+
const names = [...assigned].filter((n) => n !== "undefined");
|
|
8778
|
+
if (names.length === 0) {
|
|
8779
|
+
return [
|
|
8780
|
+
`${pad}// while \u2192 $whileSeq (bounded, max=${max})`,
|
|
8781
|
+
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
8782
|
+
body,
|
|
8783
|
+
`${pad}}, ${max});`
|
|
8784
|
+
].join("\n");
|
|
8785
|
+
}
|
|
8786
|
+
const packSrc = `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8787
|
+
const unpackSrc = `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
6316
8788
|
return [
|
|
6317
|
-
`${pad}// while \u2192 $whileSeq (
|
|
8789
|
+
`${pad}// while \u2192 $whileSeq (instrumented bindings: ${names.join(", ")})`,
|
|
6318
8790
|
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
6319
8791
|
body,
|
|
6320
|
-
`${pad}}, ${max});`
|
|
8792
|
+
`${pad}}, ${max}, { pack: () => ${packSrc}, unpack: ${unpackSrc} });`
|
|
8793
|
+
].join("\n");
|
|
8794
|
+
}
|
|
8795
|
+
case "DoWhileStatement": {
|
|
8796
|
+
const test = transpileExpression(stmt.test, opts);
|
|
8797
|
+
const bodyOpts = {
|
|
8798
|
+
...opts,
|
|
8799
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8800
|
+
};
|
|
8801
|
+
const bodyStmts = stmt.body.type === "BlockStatement" ? stmt.body.body.map((s) => transpileStatement(s, depth + 1, bodyOpts)).join("\n") : transpileStatement(stmt.body, depth + 1, bodyOpts);
|
|
8802
|
+
const max = opts.maxLoopIters ?? 8;
|
|
8803
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8804
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8805
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8806
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8807
|
+
const names = [...assigned].filter((n) => n !== "undefined");
|
|
8808
|
+
const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8809
|
+
const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
8810
|
+
const optsSrc = packSrc && unpackSrc ? `, { pack: () => ${packSrc}, unpack: ${unpackSrc} }` : "";
|
|
8811
|
+
return [
|
|
8812
|
+
`${pad}// do-while \u2192 body + $whileSeq (bounded, max=${max})`,
|
|
8813
|
+
`{`,
|
|
8814
|
+
bodyStmts,
|
|
8815
|
+
`${indent(depth + 1)}$whileSeq(() => ${test}, () => {`,
|
|
8816
|
+
bodyStmts,
|
|
8817
|
+
`${indent(depth + 1)}}, ${max}${optsSrc});`,
|
|
8818
|
+
`${pad}}`
|
|
6321
8819
|
].join("\n");
|
|
6322
8820
|
}
|
|
6323
8821
|
case "ClassDeclaration": {
|
|
@@ -6342,6 +8840,8 @@ function transpileClass(stmt, depth, opts) {
|
|
|
6342
8840
|
});
|
|
6343
8841
|
const methodOpts = {
|
|
6344
8842
|
...opts,
|
|
8843
|
+
inLoop: 0,
|
|
8844
|
+
inTry: 0,
|
|
6345
8845
|
thisParam: "__this",
|
|
6346
8846
|
className: name
|
|
6347
8847
|
};
|
|
@@ -6425,6 +8925,9 @@ ${indent(depth)}}`;
|
|
|
6425
8925
|
}
|
|
6426
8926
|
if (stmt.type === "ReturnStatement") {
|
|
6427
8927
|
const v2 = stmt.argument ? transpileExpression(stmt.argument, opts) : "$lit(undefined)";
|
|
8928
|
+
if ((opts.inLoop ?? 0) > 0) {
|
|
8929
|
+
return `() => { $loopReturn(${v2}); }`;
|
|
8930
|
+
}
|
|
6428
8931
|
return `() => ${v2}`;
|
|
6429
8932
|
}
|
|
6430
8933
|
const one = transpileStatement(stmt, depth + 1, opts);
|
|
@@ -6466,15 +8969,53 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6466
8969
|
}
|
|
6467
8970
|
case "LogicalExpression": {
|
|
6468
8971
|
const op = expr.operator;
|
|
8972
|
+
const lNode = expr.left;
|
|
8973
|
+
const rNode = expr.right;
|
|
6469
8974
|
const l = transpileExpression(expr.left, opts);
|
|
6470
8975
|
const r = transpileExpression(expr.right, opts);
|
|
6471
|
-
|
|
8976
|
+
if (op === "??") {
|
|
8977
|
+
return transpileShortCircuitExpr(opts, {
|
|
8978
|
+
alwaysNodes: [lNode],
|
|
8979
|
+
alwaysSrc: l,
|
|
8980
|
+
// 测试用 nullish;返回侧:nullish → right,否则 → left
|
|
8981
|
+
consSrc: r,
|
|
8982
|
+
consNodes: [rNode],
|
|
8983
|
+
altSrc: l,
|
|
8984
|
+
altNodes: [lNode],
|
|
8985
|
+
testSrc: `$nullishTest(${l})`
|
|
8986
|
+
});
|
|
8987
|
+
}
|
|
8988
|
+
return op === "&&" ? transpileShortCircuitExpr(opts, {
|
|
8989
|
+
alwaysNodes: [lNode],
|
|
8990
|
+
alwaysSrc: l,
|
|
8991
|
+
consSrc: r,
|
|
8992
|
+
consNodes: [rNode],
|
|
8993
|
+
altSrc: "__test",
|
|
8994
|
+
altNodes: []
|
|
8995
|
+
}) : transpileShortCircuitExpr(opts, {
|
|
8996
|
+
alwaysNodes: [lNode],
|
|
8997
|
+
alwaysSrc: l,
|
|
8998
|
+
consSrc: "__test",
|
|
8999
|
+
consNodes: [],
|
|
9000
|
+
altSrc: r,
|
|
9001
|
+
altNodes: [rNode]
|
|
9002
|
+
});
|
|
6472
9003
|
}
|
|
6473
9004
|
case "ConditionalExpression": {
|
|
9005
|
+
const testNode = expr.test;
|
|
9006
|
+
const consNode = expr.consequent;
|
|
9007
|
+
const altNode = expr.alternate;
|
|
6474
9008
|
const test = transpileExpression(expr.test, opts);
|
|
6475
9009
|
const c = transpileExpression(expr.consequent, opts);
|
|
6476
9010
|
const a = transpileExpression(expr.alternate, opts);
|
|
6477
|
-
return
|
|
9011
|
+
return transpileShortCircuitExpr(opts, {
|
|
9012
|
+
alwaysNodes: [testNode],
|
|
9013
|
+
alwaysSrc: test,
|
|
9014
|
+
consSrc: c,
|
|
9015
|
+
consNodes: [consNode],
|
|
9016
|
+
altSrc: a,
|
|
9017
|
+
altNodes: [altNode]
|
|
9018
|
+
});
|
|
6478
9019
|
}
|
|
6479
9020
|
case "RegExpLiteral": {
|
|
6480
9021
|
return `$regex(${JSON.stringify(expr.pattern)}${expr.flags ? `, ${JSON.stringify(expr.flags)}` : ""})`;
|
|
@@ -6543,6 +9084,22 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6543
9084
|
acc = acc === null ? arg : `$spread(${acc}, ${arg})`;
|
|
6544
9085
|
continue;
|
|
6545
9086
|
}
|
|
9087
|
+
if (prop.type === "ObjectMethod") {
|
|
9088
|
+
flushProps();
|
|
9089
|
+
const mkey = prop.key.type === "Identifier" ? JSON.stringify(prop.key.name) : prop.key.type === "StringLiteral" ? JSON.stringify(prop.key.value) : null;
|
|
9090
|
+
if (mkey === null) continue;
|
|
9091
|
+
const paramNames = prop.params.map(
|
|
9092
|
+
(p) => p.type === "Identifier" && p.name ? p.name : "_a"
|
|
9093
|
+
);
|
|
9094
|
+
const methodOpts = { ...opts, inLoop: 0, inTry: 0, thisParam: "__this" };
|
|
9095
|
+
const bodySrc = prop.body.type === "BlockStatement" ? `{
|
|
9096
|
+
${prop.body.body.map((s) => transpileStatement(s, 1, methodOpts)).join("\n")}
|
|
9097
|
+
}` : transpileExpression(prop.body, methodOpts);
|
|
9098
|
+
const bindParams = ["__this", ...paramNames];
|
|
9099
|
+
const fnValSrc = `$fnVal([${paramNames.map((p) => JSON.stringify(p)).join(", ")}], (${bindParams.join(", ")}) => ${bodySrc}, { bindThis: true })`;
|
|
9100
|
+
props.push(`${mkey}: ${fnValSrc}`);
|
|
9101
|
+
continue;
|
|
9102
|
+
}
|
|
6546
9103
|
if (prop.type !== "ObjectProperty") continue;
|
|
6547
9104
|
if (prop.computed) {
|
|
6548
9105
|
flushProps();
|
|
@@ -6554,6 +9111,23 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6554
9111
|
}
|
|
6555
9112
|
const key = prop.key.type === "Identifier" ? JSON.stringify(prop.key.name) : prop.key.type === "StringLiteral" ? JSON.stringify(prop.key.value) : null;
|
|
6556
9113
|
if (key === null) continue;
|
|
9114
|
+
if (prop.value.type === "FunctionExpression" && !prop.value.async) {
|
|
9115
|
+
const fn = prop.value;
|
|
9116
|
+
if (!fn.generator) {
|
|
9117
|
+
const paramNames = fn.params.map(
|
|
9118
|
+
(p) => p.type === "Identifier" && p.name ? p.name : "_a"
|
|
9119
|
+
);
|
|
9120
|
+
const methodOpts = { ...opts, inLoop: 0, thisParam: "__this" };
|
|
9121
|
+
const bodySrc = fn.body.type === "BlockStatement" ? `{
|
|
9122
|
+
${fn.body.body.map((s) => transpileStatement(s, 1, methodOpts)).join("\n")}
|
|
9123
|
+
}` : transpileExpression(fn.body, methodOpts);
|
|
9124
|
+
const bindParams = ["__this", ...paramNames];
|
|
9125
|
+
props.push(
|
|
9126
|
+
`${key}: $fnVal([${paramNames.map((p) => JSON.stringify(p)).join(", ")}], (${bindParams.join(", ")}) => ${bodySrc}, { bindThis: true })`
|
|
9127
|
+
);
|
|
9128
|
+
continue;
|
|
9129
|
+
}
|
|
9130
|
+
}
|
|
6557
9131
|
const valSrc = transpileExpression(prop.value, opts);
|
|
6558
9132
|
props.push(`${key}: ${valSrc}`);
|
|
6559
9133
|
}
|
|
@@ -6605,6 +9179,58 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6605
9179
|
case "AssignmentExpression": {
|
|
6606
9180
|
const compoundFn = COMPOUND_OPS[expr.operator];
|
|
6607
9181
|
const right = transpileExpression(expr.right, opts);
|
|
9182
|
+
const op = expr.operator;
|
|
9183
|
+
if (op === "||=" || op === "&&=" || op === "??=") {
|
|
9184
|
+
const rNode = expr.right;
|
|
9185
|
+
const emitLogicalAssign = (targetSrc, setSrc) => {
|
|
9186
|
+
if (op === "||=") {
|
|
9187
|
+
const sc2 = transpileShortCircuitExpr(opts, {
|
|
9188
|
+
alwaysNodes: [],
|
|
9189
|
+
alwaysSrc: targetSrc,
|
|
9190
|
+
consSrc: "__test",
|
|
9191
|
+
consNodes: [],
|
|
9192
|
+
altSrc: right,
|
|
9193
|
+
altNodes: [rNode]
|
|
9194
|
+
});
|
|
9195
|
+
return setSrc(sc2);
|
|
9196
|
+
}
|
|
9197
|
+
if (op === "&&=") {
|
|
9198
|
+
const sc2 = transpileShortCircuitExpr(opts, {
|
|
9199
|
+
alwaysNodes: [],
|
|
9200
|
+
alwaysSrc: targetSrc,
|
|
9201
|
+
consSrc: right,
|
|
9202
|
+
consNodes: [rNode],
|
|
9203
|
+
altSrc: "__test",
|
|
9204
|
+
altNodes: []
|
|
9205
|
+
});
|
|
9206
|
+
return setSrc(sc2);
|
|
9207
|
+
}
|
|
9208
|
+
const sc = transpileShortCircuitExpr(opts, {
|
|
9209
|
+
alwaysNodes: [],
|
|
9210
|
+
alwaysSrc: targetSrc,
|
|
9211
|
+
consSrc: right,
|
|
9212
|
+
consNodes: [rNode],
|
|
9213
|
+
altSrc: targetSrc,
|
|
9214
|
+
altNodes: [],
|
|
9215
|
+
testSrc: `$nullishTest(${targetSrc})`
|
|
9216
|
+
});
|
|
9217
|
+
return setSrc(sc);
|
|
9218
|
+
};
|
|
9219
|
+
if (expr.left.type === "Identifier") {
|
|
9220
|
+
return emitLogicalAssign(expr.left.name, (val) => `${expr.left.type === "Identifier" ? expr.left.name : ""} = ${val}`);
|
|
9221
|
+
}
|
|
9222
|
+
if (expr.left.type === "MemberExpression") {
|
|
9223
|
+
const m = expr.left;
|
|
9224
|
+
const path = memberPathOf(m, opts);
|
|
9225
|
+
if (path) {
|
|
9226
|
+
return emitLogicalAssign(readPathSrc(path), (val) => {
|
|
9227
|
+
const writeSrc = setPathSrc(path, val);
|
|
9228
|
+
return `${path.rootSrc} = ${writeSrc}`;
|
|
9229
|
+
});
|
|
9230
|
+
}
|
|
9231
|
+
}
|
|
9232
|
+
return `/* assign ${op} */ $lit(undefined)`;
|
|
9233
|
+
}
|
|
6608
9234
|
if (expr.left.type === "MemberExpression") {
|
|
6609
9235
|
const m = expr.left;
|
|
6610
9236
|
const path = memberPathOf(m, opts);
|
|
@@ -6694,10 +9320,11 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6694
9320
|
case "FunctionExpression": {
|
|
6695
9321
|
const fn = expr;
|
|
6696
9322
|
const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
|
|
9323
|
+
const fnBodyOpts = { ...opts, inLoop: 0 };
|
|
6697
9324
|
const paramParts = rest ? [...sig, `...${rest}`] : sig;
|
|
6698
9325
|
const nameList = `[${sig.map((p) => JSON.stringify(p)).join(", ")}]`;
|
|
6699
9326
|
if (fn.body.type === "BlockStatement") {
|
|
6700
|
-
const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1,
|
|
9327
|
+
const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1, fnBodyOpts)].join("\n");
|
|
6701
9328
|
if (fn.async) {
|
|
6702
9329
|
return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => {
|
|
6703
9330
|
${inner}
|
|
@@ -6707,7 +9334,7 @@ ${inner}
|
|
|
6707
9334
|
${inner}
|
|
6708
9335
|
})`;
|
|
6709
9336
|
}
|
|
6710
|
-
const bodySrc = transpileExpression(fn.body,
|
|
9337
|
+
const bodySrc = transpileExpression(fn.body, fnBodyOpts);
|
|
6711
9338
|
if (prologue.length > 0) {
|
|
6712
9339
|
const thunk = fn.async ? `$async(() => ${bodySrc})` : bodySrc;
|
|
6713
9340
|
return `$fnVal(${nameList}, (${paramParts.join(", ")}) => {
|
|
@@ -6807,7 +9434,7 @@ function $new(cls, args) {
|
|
|
6807
9434
|
if (args.length === 1) {
|
|
6808
9435
|
const n = litValue(args[0]);
|
|
6809
9436
|
if (typeof n === "number" && Number.isInteger(n) && n >= 0 && n <= 4096) {
|
|
6810
|
-
const els = Array.from({ length: n }, () =>
|
|
9437
|
+
const els = Array.from({ length: n }, () => undefAbs2());
|
|
6811
9438
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6812
9439
|
}
|
|
6813
9440
|
return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
|
|
@@ -6818,9 +9445,14 @@ function $new(cls, args) {
|
|
|
6818
9445
|
const p = args[0] ? litValue(args[0]) : void 0;
|
|
6819
9446
|
if (typeof p === "string") return $regex(p, args[1] ? String(litValue(args[1]) ?? "") : "");
|
|
6820
9447
|
}
|
|
6821
|
-
const
|
|
9448
|
+
const clsName = cls.name || "Object";
|
|
9449
|
+
if (isErrorCtorName(clsName)) {
|
|
9450
|
+
return errorBrandAbs(clsName, args[0]);
|
|
9451
|
+
}
|
|
9452
|
+
if (clsName === "Map") return makeMapAbs(args[0]);
|
|
9453
|
+
if (clsName === "Set") return makeSetAbs(args[0]);
|
|
6822
9454
|
const shape = objOf({});
|
|
6823
|
-
return abs({ k: "brand", name, shape }, void 0, void 0, "path");
|
|
9455
|
+
return abs({ k: "brand", name: clsName, shape }, void 0, void 0, "path");
|
|
6824
9456
|
}
|
|
6825
9457
|
const spec = specOf(cls);
|
|
6826
9458
|
if (!spec) {
|
|
@@ -6884,7 +9516,7 @@ function execRegexBrand(re, method, args) {
|
|
|
6884
9516
|
if (!m) {
|
|
6885
9517
|
return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
6886
9518
|
}
|
|
6887
|
-
const els = m.map((g) => g === void 0 ?
|
|
9519
|
+
const els = m.map((g) => g === void 0 ? undefAbs2() : strLit(g));
|
|
6888
9520
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6889
9521
|
}
|
|
6890
9522
|
function stringRegexMethod(recv, method, args) {
|
|
@@ -6917,10 +9549,69 @@ function stringRegexMethod(recv, method, args) {
|
|
|
6917
9549
|
if (!m) {
|
|
6918
9550
|
return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
6919
9551
|
}
|
|
6920
|
-
const els = m.map((g) => g === void 0 ?
|
|
9552
|
+
const els = m.map((g) => g === void 0 ? undefAbs2() : strLit(g));
|
|
6921
9553
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6922
9554
|
}
|
|
6923
9555
|
function $invoke(thisVal, method, args, loc) {
|
|
9556
|
+
if (method === "call" || method === "apply" || method === "bind") {
|
|
9557
|
+
const expandApplyArgs = (list) => {
|
|
9558
|
+
if (list === null || list === void 0) return [];
|
|
9559
|
+
if (Array.isArray(list)) {
|
|
9560
|
+
return list.map(
|
|
9561
|
+
(x) => x && typeof x === "object" && "shape" in x ? x : unknown
|
|
9562
|
+
);
|
|
9563
|
+
}
|
|
9564
|
+
if (typeof list === "object" && "shape" in list) {
|
|
9565
|
+
const s = list.shape;
|
|
9566
|
+
if (s.k === "tuple") return [...s.elements];
|
|
9567
|
+
if (s.k === "arr") return [s.element];
|
|
9568
|
+
}
|
|
9569
|
+
return [unknown];
|
|
9570
|
+
};
|
|
9571
|
+
const boundFnParams = (fnVal, boundCount) => {
|
|
9572
|
+
if (fnVal && typeof fnVal === "object" && "shape" in fnVal) {
|
|
9573
|
+
const s = fnVal.shape;
|
|
9574
|
+
if (s.k === "fn" && Array.isArray(s.params)) {
|
|
9575
|
+
return s.params.slice(boundCount);
|
|
9576
|
+
}
|
|
9577
|
+
}
|
|
9578
|
+
if (typeof fnVal === "function") {
|
|
9579
|
+
const arity = fnVal.length ?? 0;
|
|
9580
|
+
const rem = Math.max(0, arity - boundCount);
|
|
9581
|
+
return Array.from({ length: rem }, (_, i) => `_a${boundCount + i}`);
|
|
9582
|
+
}
|
|
9583
|
+
return ["_rest"];
|
|
9584
|
+
};
|
|
9585
|
+
if (typeof thisVal === "function") {
|
|
9586
|
+
const fn = thisVal;
|
|
9587
|
+
if (method === "call") {
|
|
9588
|
+
return callAtFunctionBoundary(() => fn(...args.slice(1)));
|
|
9589
|
+
}
|
|
9590
|
+
if (method === "apply") {
|
|
9591
|
+
return callAtFunctionBoundary(() => fn(...expandApplyArgs(args[1])));
|
|
9592
|
+
}
|
|
9593
|
+
const bound = args.slice(1);
|
|
9594
|
+
return absFunction(boundFnParams(thisVal, bound.length), {
|
|
9595
|
+
apply: (callArgs) => callAtFunctionBoundary(() => fn(...bound, ...callArgs))
|
|
9596
|
+
});
|
|
9597
|
+
}
|
|
9598
|
+
if (thisVal && typeof thisVal === "object" && "shape" in thisVal) {
|
|
9599
|
+
const fnImpl = getFnImpl(thisVal);
|
|
9600
|
+
const isCallable = thisVal.shape.k === "fn" || fnImpl !== void 0;
|
|
9601
|
+
if (isCallable) {
|
|
9602
|
+
if (method === "call") {
|
|
9603
|
+
return $call(thisVal, args.slice(1));
|
|
9604
|
+
}
|
|
9605
|
+
if (method === "apply") {
|
|
9606
|
+
return $call(thisVal, expandApplyArgs(args[1]));
|
|
9607
|
+
}
|
|
9608
|
+
const bound = args.slice(1);
|
|
9609
|
+
return absFunction(boundFnParams(thisVal, bound.length), {
|
|
9610
|
+
apply: (callArgs) => callAtFunctionBoundary(() => $call(thisVal, [...bound, ...callArgs]))
|
|
9611
|
+
});
|
|
9612
|
+
}
|
|
9613
|
+
}
|
|
9614
|
+
}
|
|
6924
9615
|
if (!thisVal || typeof thisVal !== "object" || !("shape" in thisVal)) {
|
|
6925
9616
|
const ns = namespaceNameOf(thisVal);
|
|
6926
9617
|
return (ns ? evalNamespaceCall(ns, method, args) : void 0) ?? unknown;
|
|
@@ -6936,6 +9627,10 @@ function $invoke(thisVal, method, args, loc) {
|
|
|
6936
9627
|
}
|
|
6937
9628
|
const brandName = thisVal.shape.k === "brand" ? thisVal.shape.name : void 0;
|
|
6938
9629
|
if (brandName) {
|
|
9630
|
+
if (brandName === "Map" || brandName === "Set") {
|
|
9631
|
+
const viaCol = evalBuiltinInstanceMethod(brandName, method, thisVal, args);
|
|
9632
|
+
if (viaCol !== void 0) return viaCol;
|
|
9633
|
+
}
|
|
6939
9634
|
const m = findMethod(brandName, method);
|
|
6940
9635
|
if (m) return m(thisVal, ...args);
|
|
6941
9636
|
const spec = getBClass(brandName);
|
|
@@ -6957,6 +9652,7 @@ function $invoke(thisVal, method, args, loc) {
|
|
|
6957
9652
|
const prop = $get(thisVal, method, { silent: true });
|
|
6958
9653
|
const impl = prop && typeof prop === "object" && "shape" in prop ? getFnImpl(prop) : void 0;
|
|
6959
9654
|
if (impl) {
|
|
9655
|
+
if (impl.bindThis) return $call(prop, [thisVal, ...args]);
|
|
6960
9656
|
return $call(prop, args);
|
|
6961
9657
|
}
|
|
6962
9658
|
if (notePrimMemberMissing(thisVal, method, "method", loc)) return unknown;
|
|
@@ -6974,8 +9670,21 @@ function memberLikelyHasMethod(m, method) {
|
|
|
6974
9670
|
function invokeArrMethod(arr, method, args) {
|
|
6975
9671
|
const shape = arr.shape;
|
|
6976
9672
|
const callFn = (fn, ...fnArgs) => {
|
|
9673
|
+
const sumIdx = fnArgs.findIndex(
|
|
9674
|
+
(a) => a && typeof a === "object" && "shape" in a && a.shape.k === "sum"
|
|
9675
|
+
);
|
|
9676
|
+
if (sumIdx >= 0) {
|
|
9677
|
+
const members = fnArgs[sumIdx].shape.members;
|
|
9678
|
+
let acc;
|
|
9679
|
+
for (const m of members) {
|
|
9680
|
+
const next = fnArgs.map((a, i) => i === sumIdx ? m : a);
|
|
9681
|
+
const r = callFn(fn, ...next);
|
|
9682
|
+
acc = acc === void 0 ? r : joinAbs(acc, r);
|
|
9683
|
+
}
|
|
9684
|
+
return acc ?? unknown;
|
|
9685
|
+
}
|
|
6977
9686
|
if (typeof fn === "function") {
|
|
6978
|
-
const r = fn(...fnArgs);
|
|
9687
|
+
const r = callAtFunctionBoundary(() => fn(...fnArgs));
|
|
6979
9688
|
if (r && typeof r === "object" && "shape" in r) return r;
|
|
6980
9689
|
return unknown;
|
|
6981
9690
|
}
|
|
@@ -7033,7 +9742,7 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7033
9742
|
if (method === "forEach" && args[0]) {
|
|
7034
9743
|
const list = shape.k === "tuple" ? shape.elements : [shape.element];
|
|
7035
9744
|
for (const el of list) callFn(args[0], el);
|
|
7036
|
-
return
|
|
9745
|
+
return undefAbs2();
|
|
7037
9746
|
}
|
|
7038
9747
|
if ((method === "some" || method === "every") && args[0]) {
|
|
7039
9748
|
const list = shape.k === "tuple" ? shape.elements : [shape.element];
|
|
@@ -7043,7 +9752,7 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7043
9752
|
if (method === "find" && args[0]) {
|
|
7044
9753
|
const el = shape.k === "tuple" ? shape.elements[0] ?? unknown : shape.element;
|
|
7045
9754
|
callFn(args[0], el);
|
|
7046
|
-
return joinAbs(el,
|
|
9755
|
+
return joinAbs(el, undefAbs2());
|
|
7047
9756
|
}
|
|
7048
9757
|
if (method === "join") {
|
|
7049
9758
|
return abs({ k: "prim", type: "string" }, void 0, void 0, "path");
|
|
@@ -7063,11 +9772,35 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7063
9772
|
if (method === "includes") {
|
|
7064
9773
|
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
7065
9774
|
}
|
|
7066
|
-
if (method === "
|
|
9775
|
+
if (method === "push" || method === "unshift") {
|
|
9776
|
+
return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
|
|
9777
|
+
}
|
|
9778
|
+
if (method === "pop") {
|
|
9779
|
+
if (shape.k === "tuple") {
|
|
9780
|
+
return shape.elements.length > 0 ? shape.elements[shape.elements.length - 1] ?? unknown : undefAbs2();
|
|
9781
|
+
}
|
|
9782
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
9783
|
+
}
|
|
9784
|
+
if (method === "shift") {
|
|
7067
9785
|
if (shape.k === "tuple" && shape.elements.length > 0) {
|
|
7068
9786
|
return shape.elements[0] ?? unknown;
|
|
7069
9787
|
}
|
|
7070
|
-
if (shape.k === "arr") return shape.element;
|
|
9788
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
9789
|
+
}
|
|
9790
|
+
if (method === "at") {
|
|
9791
|
+
const raw = args[0] !== void 0 ? litValue(args[0]) : void 0;
|
|
9792
|
+
const iv = typeof raw === "number" && Number.isInteger(raw) ? raw : void 0;
|
|
9793
|
+
if (shape.k === "tuple") {
|
|
9794
|
+
const els = shape.elements;
|
|
9795
|
+
if (iv === void 0) {
|
|
9796
|
+
if (els.length === 0) return undefAbs2();
|
|
9797
|
+
return joinAbs(els.reduce((a, b) => joinAbs(a, b)), undefAbs2());
|
|
9798
|
+
}
|
|
9799
|
+
const idx = iv < 0 ? els.length + iv : iv;
|
|
9800
|
+
if (idx >= 0 && idx < els.length) return els[idx] ?? unknown;
|
|
9801
|
+
return undefAbs2();
|
|
9802
|
+
}
|
|
9803
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
7071
9804
|
}
|
|
7072
9805
|
return void 0;
|
|
7073
9806
|
}
|
|
@@ -7109,13 +9842,32 @@ function $thisSet(thisVal, key, value) {
|
|
|
7109
9842
|
}
|
|
7110
9843
|
function $orDefault(v2, dflt) {
|
|
7111
9844
|
if (v2 === void 0) return asAbsVal(dflt());
|
|
7112
|
-
if (
|
|
7113
|
-
|
|
7114
|
-
|
|
9845
|
+
if (isDefinitelyUndefinedAbs(v2)) return asAbsVal(dflt());
|
|
9846
|
+
if (v2.shape.k === "sum") {
|
|
9847
|
+
const d = asAbsVal(dflt());
|
|
9848
|
+
const parts = [];
|
|
9849
|
+
let sawUndef = false;
|
|
9850
|
+
for (const m of v2.shape.members) {
|
|
9851
|
+
if (isDefinitelyUndefinedAbs(m)) {
|
|
9852
|
+
sawUndef = true;
|
|
9853
|
+
continue;
|
|
9854
|
+
}
|
|
9855
|
+
parts.push(m);
|
|
9856
|
+
}
|
|
9857
|
+
if (!sawUndef) return v2;
|
|
9858
|
+
if (parts.length === 0) return d;
|
|
9859
|
+
let joined = parts[0];
|
|
9860
|
+
for (let i = 1; i < parts.length; i++) joined = joinAbs(joined, parts[i]);
|
|
9861
|
+
return joinAbs(joined, d);
|
|
7115
9862
|
}
|
|
7116
|
-
if (v2.term?.op === "lit" && v2.term.value === void 0) return asAbsVal(dflt());
|
|
7117
9863
|
return v2;
|
|
7118
9864
|
}
|
|
9865
|
+
function isDefinitelyUndefinedAbs(v2) {
|
|
9866
|
+
if (!v2) return false;
|
|
9867
|
+
if (v2.term?.op === "lit" && v2.term.value === void 0) return true;
|
|
9868
|
+
if (v2.shape.k === "unknown" && v2.term?.op === "lit" && litValue(v2) === void 0) return true;
|
|
9869
|
+
return false;
|
|
9870
|
+
}
|
|
7119
9871
|
function isNullishAbs(v2) {
|
|
7120
9872
|
if (!v2 || v2.term?.op !== "lit") return false;
|
|
7121
9873
|
const lv = v2.term.value;
|
|
@@ -7154,11 +9906,47 @@ function $setKey(o, key, value) {
|
|
|
7154
9906
|
if (typeof k === "string" || typeof k === "number") {
|
|
7155
9907
|
return $set(o, String(k), value);
|
|
7156
9908
|
}
|
|
7157
|
-
|
|
9909
|
+
const val = asAbsVal(value);
|
|
9910
|
+
if (o.shape.k === "brand") {
|
|
9911
|
+
const inner = $setKey(o.shape.shape, key, value);
|
|
9912
|
+
return abs(
|
|
9913
|
+
{ k: "brand", name: o.shape.name, shape: inner },
|
|
9914
|
+
o.term,
|
|
9915
|
+
o.pred,
|
|
9916
|
+
confJoin(o.conf, value.conf)
|
|
9917
|
+
);
|
|
9918
|
+
}
|
|
9919
|
+
if (o.shape.k !== "obj") {
|
|
9920
|
+
return abs(
|
|
9921
|
+
{
|
|
9922
|
+
k: "obj",
|
|
9923
|
+
slots: {},
|
|
9924
|
+
index: { key: unknown, value: val },
|
|
9925
|
+
open: true
|
|
9926
|
+
},
|
|
9927
|
+
void 0,
|
|
9928
|
+
void 0,
|
|
9929
|
+
confJoin("path", value.conf)
|
|
9930
|
+
);
|
|
9931
|
+
}
|
|
9932
|
+
const shape = o.shape;
|
|
9933
|
+
const prevIndex = shape.index?.value;
|
|
9934
|
+
const indexVal = prevIndex ? joinAbs(prevIndex, val) : val;
|
|
9935
|
+
const next = objOf({ ...shape.slots }, {
|
|
9936
|
+
index: { key: shape.index?.key ?? unknown, value: indexVal },
|
|
9937
|
+
open: true
|
|
9938
|
+
});
|
|
9939
|
+
next.conf = confJoin(o.conf, value.conf);
|
|
9940
|
+
return next;
|
|
7158
9941
|
}
|
|
7159
9942
|
|
|
7160
9943
|
// src/algebra/exec/run.ts
|
|
7161
9944
|
var rtAll = { ...runtime_exports, ...class_exports, ...calls_exports };
|
|
9945
|
+
rtAll.isNudoReturn = isNudoReturn;
|
|
9946
|
+
rtAll.isNudoThrow = isNudoThrow;
|
|
9947
|
+
rtAll.$isForkExit = $isForkExit;
|
|
9948
|
+
rtAll.runWithLoopExits = runWithLoopExits;
|
|
9949
|
+
rtAll.takeLoopExits = takeLoopExits;
|
|
7162
9950
|
var RUNTIME_IMPORT_RE = /^import\s*\{[^}]+\}\s*from\s*"[^"]+";\s*$/m;
|
|
7163
9951
|
function rewriteUserImports(js) {
|
|
7164
9952
|
js = js.replace(
|
|
@@ -7364,33 +10152,59 @@ function isAbsVal(v2) {
|
|
|
7364
10152
|
function callTranspiledExportFull(exports, name, args) {
|
|
7365
10153
|
const fn = exports[name];
|
|
7366
10154
|
if (typeof fn === "function") {
|
|
7367
|
-
|
|
7368
|
-
const r = fn(...args);
|
|
7369
|
-
if (!isAbsVal(r)) return { result: unknown, throws: never };
|
|
7370
|
-
return { result: r, throws: never };
|
|
7371
|
-
} catch (e) {
|
|
7372
|
-
if (isNudoThrow(e)) {
|
|
7373
|
-
return { result: never, throws: e.absValue };
|
|
7374
|
-
}
|
|
7375
|
-
return { result: unknown, throws: never };
|
|
7376
|
-
}
|
|
7377
|
-
}
|
|
7378
|
-
if (isAbsVal(fn)) {
|
|
7379
|
-
if (fn.shape.k === "fn") {
|
|
10155
|
+
return runWithLoopExits(() => {
|
|
7380
10156
|
try {
|
|
7381
|
-
const r =
|
|
7382
|
-
|
|
10157
|
+
const r = fn(...args);
|
|
10158
|
+
if (!isAbsVal(r)) return joinControlExits(unknown);
|
|
10159
|
+
return joinControlExits(r);
|
|
7383
10160
|
} catch (e) {
|
|
10161
|
+
if (isNudoReturn(e)) {
|
|
10162
|
+
return joinControlExits(e.absValue);
|
|
10163
|
+
}
|
|
7384
10164
|
if (isNudoThrow(e)) {
|
|
7385
|
-
|
|
10165
|
+
const result = joinLoopExits(never);
|
|
10166
|
+
const throws = joinThrowExits(e.absValue);
|
|
10167
|
+
return { result, throws };
|
|
7386
10168
|
}
|
|
7387
|
-
return
|
|
10169
|
+
return joinControlExits(unknown);
|
|
7388
10170
|
}
|
|
10171
|
+
});
|
|
10172
|
+
}
|
|
10173
|
+
if (isAbsVal(fn)) {
|
|
10174
|
+
if (fn.shape.k === "fn") {
|
|
10175
|
+
return runWithLoopExits(() => {
|
|
10176
|
+
try {
|
|
10177
|
+
const r = $call(fn, args);
|
|
10178
|
+
return joinControlExits(r);
|
|
10179
|
+
} catch (e) {
|
|
10180
|
+
if (isNudoReturn(e)) {
|
|
10181
|
+
return joinControlExits(e.absValue);
|
|
10182
|
+
}
|
|
10183
|
+
if (isNudoThrow(e)) {
|
|
10184
|
+
return { result: joinLoopExits(never), throws: joinThrowExits(e.absValue) };
|
|
10185
|
+
}
|
|
10186
|
+
return joinControlExits(unknown);
|
|
10187
|
+
}
|
|
10188
|
+
});
|
|
7389
10189
|
}
|
|
7390
10190
|
return { result: fn, throws: never };
|
|
7391
10191
|
}
|
|
7392
10192
|
return { result: unknown, throws: never };
|
|
7393
10193
|
}
|
|
10194
|
+
function joinLoopExits(normal) {
|
|
10195
|
+
const exits = takeLoopExits();
|
|
10196
|
+
if (exits.length === 0) return normal;
|
|
10197
|
+
return exits.reduce((acc, x) => joinAbs(acc, x), normal);
|
|
10198
|
+
}
|
|
10199
|
+
function joinThrowExits(base) {
|
|
10200
|
+
const exits = takeThrowExits();
|
|
10201
|
+
let t = base;
|
|
10202
|
+
for (const x of exits) t = t ? joinAbs(t, x) : x;
|
|
10203
|
+
return t ?? never;
|
|
10204
|
+
}
|
|
10205
|
+
function joinControlExits(normal) {
|
|
10206
|
+
return { result: joinLoopExits(normal), throws: joinThrowExits(void 0) };
|
|
10207
|
+
}
|
|
7394
10208
|
function callTranspiledExport(exports, name, args) {
|
|
7395
10209
|
return callTranspiledExportFull(exports, name, args).result;
|
|
7396
10210
|
}
|
|
@@ -7494,7 +10308,7 @@ export {
|
|
|
7494
10308
|
instantiateReturn,
|
|
7495
10309
|
setApplyCallbackHost,
|
|
7496
10310
|
applyCallbackAbs,
|
|
7497
|
-
undefAbs,
|
|
10311
|
+
undefAbs2 as undefAbs,
|
|
7498
10312
|
mapElementFallback,
|
|
7499
10313
|
projectFlatMapResult,
|
|
7500
10314
|
asAbs,
|
|
@@ -7530,6 +10344,34 @@ export {
|
|
|
7530
10344
|
definitelyNotNullishShape,
|
|
7531
10345
|
isNullishLitAbs,
|
|
7532
10346
|
strictEqAbs,
|
|
10347
|
+
looseEqAbs,
|
|
10348
|
+
pushCollectionArm,
|
|
10349
|
+
popCollectionArm,
|
|
10350
|
+
mergeCollectionArms,
|
|
10351
|
+
beginCollectionFork,
|
|
10352
|
+
noteCollectionWrite,
|
|
10353
|
+
endCollectionFork,
|
|
10354
|
+
isMapAbs,
|
|
10355
|
+
isSetAbs,
|
|
10356
|
+
makeMapAbs,
|
|
10357
|
+
makeSetAbs,
|
|
10358
|
+
mapSetEntry,
|
|
10359
|
+
mapDeleteEntry,
|
|
10360
|
+
mapClearEntries,
|
|
10361
|
+
mapGetEntry,
|
|
10362
|
+
mapHasEntry,
|
|
10363
|
+
mapSizeAbs,
|
|
10364
|
+
mapValuesAbs,
|
|
10365
|
+
mapEntriesAbs,
|
|
10366
|
+
setAddEntry,
|
|
10367
|
+
setDeleteEntry,
|
|
10368
|
+
setClearEntries,
|
|
10369
|
+
setHasEntry,
|
|
10370
|
+
setSizeAbs,
|
|
10371
|
+
setElementsAbs,
|
|
10372
|
+
collectionExactLen,
|
|
10373
|
+
collectionElementJoin,
|
|
10374
|
+
clearCollectionTables,
|
|
7533
10375
|
evalMathMethod,
|
|
7534
10376
|
evalObjectMethod,
|
|
7535
10377
|
evalJsonMethod,
|
|
@@ -7544,6 +10386,8 @@ export {
|
|
|
7544
10386
|
evalPromiseCtor,
|
|
7545
10387
|
evalPromiseStatic,
|
|
7546
10388
|
evalNamespaceCall,
|
|
10389
|
+
isErrorCtorName,
|
|
10390
|
+
errorBrandAbs,
|
|
7547
10391
|
evalBuiltinNew,
|
|
7548
10392
|
evalBuiltinInstanceMethod,
|
|
7549
10393
|
callAbsMethod,
|
|
@@ -7577,6 +10421,10 @@ export {
|
|
|
7577
10421
|
notePrimMemberMissing,
|
|
7578
10422
|
noteUnknownMemberMissing,
|
|
7579
10423
|
noteMemberDispatchMiss,
|
|
10424
|
+
setEvalMissingSlotEnabled,
|
|
10425
|
+
isEvalMissingSlotEnabled,
|
|
10426
|
+
runWithEvalMissingSlot,
|
|
10427
|
+
noteObjSlotMissing,
|
|
7580
10428
|
registerBClass,
|
|
7581
10429
|
getBClass,
|
|
7582
10430
|
clearBClasses,
|
|
@@ -7618,27 +10466,44 @@ export {
|
|
|
7618
10466
|
$not,
|
|
7619
10467
|
$eq,
|
|
7620
10468
|
$ne,
|
|
10469
|
+
$eqLoose,
|
|
10470
|
+
$neLoose,
|
|
7621
10471
|
$lt,
|
|
7622
10472
|
$le,
|
|
7623
10473
|
$gt,
|
|
7624
10474
|
$ge,
|
|
7625
10475
|
$join,
|
|
7626
10476
|
asAbsVal,
|
|
10477
|
+
callAtFunctionBoundary,
|
|
7627
10478
|
$fnVal,
|
|
7628
10479
|
$lit,
|
|
7629
10480
|
litTruth,
|
|
7630
10481
|
isDefinitelyTrue,
|
|
7631
10482
|
isDefinitelyFalse,
|
|
10483
|
+
runWithLoopExits,
|
|
10484
|
+
takeLoopExits,
|
|
10485
|
+
takeThrowExits,
|
|
10486
|
+
pushLoopExit,
|
|
10487
|
+
pushThrowExit,
|
|
10488
|
+
$pushLoopExit,
|
|
10489
|
+
$tryMark,
|
|
10490
|
+
$tryCurrentMark,
|
|
10491
|
+
$tryPopMark,
|
|
10492
|
+
$tryTakeSince,
|
|
7632
10493
|
$fork,
|
|
7633
10494
|
DEFAULT_MAX_LOOP_ITERS,
|
|
7634
10495
|
$forIter,
|
|
7635
10496
|
$for,
|
|
7636
10497
|
$arr,
|
|
10498
|
+
isArrMutator,
|
|
10499
|
+
$arrMutContainer,
|
|
7637
10500
|
$idx,
|
|
7638
10501
|
$idxSet,
|
|
7639
10502
|
$len,
|
|
7640
10503
|
$obj,
|
|
7641
10504
|
$spread,
|
|
10505
|
+
$objRest,
|
|
10506
|
+
$arrRest,
|
|
7642
10507
|
$concat,
|
|
7643
10508
|
$elems,
|
|
7644
10509
|
$forOf,
|
|
@@ -7648,9 +10513,14 @@ export {
|
|
|
7648
10513
|
$set,
|
|
7649
10514
|
$while,
|
|
7650
10515
|
$whileSeq,
|
|
10516
|
+
NudoReturn,
|
|
10517
|
+
$loopReturn,
|
|
10518
|
+
isNudoReturn,
|
|
10519
|
+
$rethrowIfNudoReturn,
|
|
7651
10520
|
NudoThrow,
|
|
7652
10521
|
$throw,
|
|
7653
10522
|
isNudoThrow,
|
|
10523
|
+
$isForkExit,
|
|
7654
10524
|
$catchVal,
|
|
7655
10525
|
$async,
|
|
7656
10526
|
$await,
|
|
@@ -7658,6 +10528,7 @@ export {
|
|
|
7658
10528
|
$gen,
|
|
7659
10529
|
$yield,
|
|
7660
10530
|
$switch,
|
|
10531
|
+
$nullishTest,
|
|
7661
10532
|
transpileSource,
|
|
7662
10533
|
transpileFile,
|
|
7663
10534
|
transpileExpression,
|