@nudojs/core 1.0.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-P3G2TODS.js → chunk-6REHMIAE.js} +3331 -441
- 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 +241 -14
- package/dist/index.js +819 -257
- 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;
|
|
@@ -2102,6 +2811,15 @@ function ok() {
|
|
|
2102
2811
|
function fail(reason) {
|
|
2103
2812
|
return { ok: false, reason };
|
|
2104
2813
|
}
|
|
2814
|
+
function requiredFnArity(params) {
|
|
2815
|
+
if (!params) return 0;
|
|
2816
|
+
let n = 0;
|
|
2817
|
+
for (const p of params) {
|
|
2818
|
+
if (!p || p.startsWith("...") || p.endsWith("?")) continue;
|
|
2819
|
+
n++;
|
|
2820
|
+
}
|
|
2821
|
+
return n;
|
|
2822
|
+
}
|
|
2105
2823
|
function leqAbs(src, tgt, opts = {}) {
|
|
2106
2824
|
const phi2 = opts.phi ?? pTrue;
|
|
2107
2825
|
return leqWithPred(src, tgt, phi2, opts.env ?? null, 0);
|
|
@@ -2115,6 +2833,13 @@ function leqWithPred(src, tgt, phi2, env, depth) {
|
|
|
2115
2833
|
const tv = litValue(tgt);
|
|
2116
2834
|
if (sv !== void 0 && tv !== void 0) {
|
|
2117
2835
|
if (sv === tv) return ok();
|
|
2836
|
+
if (tgt.shape.k === "prim") {
|
|
2837
|
+
return fail(`lit ${String(sv)} \u22AD lit ${String(tv)}`);
|
|
2838
|
+
}
|
|
2839
|
+
} else if (tv !== void 0 && sv === void 0) {
|
|
2840
|
+
if (tgt.shape.k === "prim") {
|
|
2841
|
+
return fail(`non-lit prim \u22AD lit ${String(tv)}`);
|
|
2842
|
+
}
|
|
2118
2843
|
}
|
|
2119
2844
|
const shapeR = leqShape(src, tgt, phi2, env, depth);
|
|
2120
2845
|
if (!shapeR.ok) return shapeR;
|
|
@@ -2215,6 +2940,11 @@ function leqShape(src, tgt, phi2, env, depth) {
|
|
|
2215
2940
|
if (srcSlot.optional && !slot.optional) {
|
|
2216
2941
|
return fail(`slot ${key}: optional \u22AD required`);
|
|
2217
2942
|
}
|
|
2943
|
+
const ssv = litValue(srcSlot.value);
|
|
2944
|
+
const stv = litValue(slot.value);
|
|
2945
|
+
if (ssv !== void 0 && stv !== void 0 && primOf(srcSlot.value) !== void 0 && primOf(srcSlot.value) === primOf(slot.value)) {
|
|
2946
|
+
continue;
|
|
2947
|
+
}
|
|
2218
2948
|
const r = leqWithPred(srcSlot.value, slot.value, phi2, env, depth + 1);
|
|
2219
2949
|
if (!r.ok) return fail(`slot ${key}: ${r.reason}`);
|
|
2220
2950
|
}
|
|
@@ -2242,8 +2972,12 @@ function leqShape(src, tgt, phi2, env, depth) {
|
|
|
2242
2972
|
}
|
|
2243
2973
|
if (t.k === "fn") {
|
|
2244
2974
|
if (s.k !== "fn") return fail(`shape ${s.k} \u22AD fn`);
|
|
2245
|
-
|
|
2246
|
-
|
|
2975
|
+
const sReq = requiredFnArity(s.params);
|
|
2976
|
+
const tReq = requiredFnArity(t.params);
|
|
2977
|
+
if (sReq > tReq) {
|
|
2978
|
+
return fail(
|
|
2979
|
+
`fn arity required ${sReq} \u22AD target required ${tReq} (params ${s.params.length} / ${t.params.length})`
|
|
2980
|
+
);
|
|
2247
2981
|
}
|
|
2248
2982
|
if (t.returnType !== void 0) {
|
|
2249
2983
|
const sr = s.returnType;
|
|
@@ -2481,6 +3215,10 @@ function evalArrayStatic(name, args) {
|
|
|
2481
3215
|
return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
|
|
2482
3216
|
case "from": {
|
|
2483
3217
|
if (!a0) return unknown;
|
|
3218
|
+
if (isSetAbs(a0) || isMapAbs(a0)) {
|
|
3219
|
+
const el = collectionElementJoin(a0);
|
|
3220
|
+
return abs({ k: "arr", element: el }, void 0, void 0, "path");
|
|
3221
|
+
}
|
|
2484
3222
|
const k = a0.shape.k;
|
|
2485
3223
|
if (k === "arr") return a0;
|
|
2486
3224
|
if (k === "tuple") {
|
|
@@ -2599,6 +3337,35 @@ function evalNamespaceCall(ns, method, args) {
|
|
|
2599
3337
|
return void 0;
|
|
2600
3338
|
}
|
|
2601
3339
|
}
|
|
3340
|
+
var ERROR_CTOR_NAMES = /* @__PURE__ */ new Set([
|
|
3341
|
+
"Error",
|
|
3342
|
+
"TypeError",
|
|
3343
|
+
"RangeError",
|
|
3344
|
+
"SyntaxError",
|
|
3345
|
+
"ReferenceError",
|
|
3346
|
+
"URIError",
|
|
3347
|
+
"EvalError",
|
|
3348
|
+
"AggregateError"
|
|
3349
|
+
]);
|
|
3350
|
+
function isErrorCtorName(name) {
|
|
3351
|
+
return !!name && ERROR_CTOR_NAMES.has(name);
|
|
3352
|
+
}
|
|
3353
|
+
function errorBrandAbs(name, messageArg) {
|
|
3354
|
+
const message = messageArg ?? strPrim();
|
|
3355
|
+
return abs(
|
|
3356
|
+
{
|
|
3357
|
+
k: "brand",
|
|
3358
|
+
name,
|
|
3359
|
+
shape: objOf({
|
|
3360
|
+
name: { value: strLit(name) },
|
|
3361
|
+
message: { value: message }
|
|
3362
|
+
})
|
|
3363
|
+
},
|
|
3364
|
+
void 0,
|
|
3365
|
+
void 0,
|
|
3366
|
+
"path"
|
|
3367
|
+
);
|
|
3368
|
+
}
|
|
2602
3369
|
function evalBuiltinNew(className, args) {
|
|
2603
3370
|
switch (className) {
|
|
2604
3371
|
case "Date":
|
|
@@ -2608,20 +3375,13 @@ function evalBuiltinNew(className, args) {
|
|
|
2608
3375
|
case "Promise":
|
|
2609
3376
|
return evalPromiseCtor(args);
|
|
2610
3377
|
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
|
-
);
|
|
3378
|
+
return makeMapAbs(args[0]);
|
|
2617
3379
|
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
|
-
);
|
|
3380
|
+
return makeSetAbs(args[0]);
|
|
2624
3381
|
default:
|
|
3382
|
+
if (isErrorCtorName(className)) {
|
|
3383
|
+
return errorBrandAbs(className, args[0]);
|
|
3384
|
+
}
|
|
2625
3385
|
return void 0;
|
|
2626
3386
|
}
|
|
2627
3387
|
}
|
|
@@ -2631,13 +3391,17 @@ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
|
|
|
2631
3391
|
if (brandName === "Map") {
|
|
2632
3392
|
switch (method) {
|
|
2633
3393
|
case "get":
|
|
2634
|
-
return
|
|
3394
|
+
return mapGetEntry(recv, args[0]);
|
|
2635
3395
|
case "has":
|
|
2636
|
-
return
|
|
3396
|
+
return mapHasEntry(recv, args[0]);
|
|
2637
3397
|
case "set":
|
|
2638
|
-
return recv;
|
|
3398
|
+
return mapSetEntry(recv, args[0], args[1] ?? unknown);
|
|
3399
|
+
case "delete":
|
|
3400
|
+
return mapDeleteEntry(recv, args[0]);
|
|
3401
|
+
case "clear":
|
|
3402
|
+
return mapClearEntries(recv);
|
|
2639
3403
|
case "size":
|
|
2640
|
-
return
|
|
3404
|
+
return mapSizeAbs(recv);
|
|
2641
3405
|
default:
|
|
2642
3406
|
return void 0;
|
|
2643
3407
|
}
|
|
@@ -2645,11 +3409,15 @@ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
|
|
|
2645
3409
|
if (brandName === "Set") {
|
|
2646
3410
|
switch (method) {
|
|
2647
3411
|
case "has":
|
|
2648
|
-
return
|
|
3412
|
+
return setHasEntry(recv, args[0]);
|
|
2649
3413
|
case "add":
|
|
2650
|
-
return recv;
|
|
3414
|
+
return setAddEntry(recv, args[0] ?? unknown);
|
|
3415
|
+
case "delete":
|
|
3416
|
+
return setDeleteEntry(recv, args[0]);
|
|
3417
|
+
case "clear":
|
|
3418
|
+
return setClearEntries(recv);
|
|
2651
3419
|
case "size":
|
|
2652
|
-
return
|
|
3420
|
+
return setSizeAbs(recv);
|
|
2653
3421
|
default:
|
|
2654
3422
|
return void 0;
|
|
2655
3423
|
}
|
|
@@ -2663,11 +3431,15 @@ __export(calls_exports, {
|
|
|
2663
3431
|
$callNamed: () => $callNamed,
|
|
2664
3432
|
getAbsOrigin: () => getAbsOrigin,
|
|
2665
3433
|
getBCallCollector: () => getBCallCollector,
|
|
3434
|
+
isEvalMissingSlotEnabled: () => isEvalMissingSlotEnabled,
|
|
2666
3435
|
noteMemberDispatchMiss: () => noteMemberDispatchMiss,
|
|
3436
|
+
noteObjSlotMissing: () => noteObjSlotMissing,
|
|
2667
3437
|
notePrimMemberMissing: () => notePrimMemberMissing,
|
|
2668
3438
|
noteUnknownMemberMissing: () => noteUnknownMemberMissing,
|
|
2669
3439
|
recordMemberDiag: () => recordMemberDiag,
|
|
3440
|
+
runWithEvalMissingSlot: () => runWithEvalMissingSlot,
|
|
2670
3441
|
setBCallCollector: () => setBCallCollector,
|
|
3442
|
+
setEvalMissingSlotEnabled: () => setEvalMissingSlotEnabled,
|
|
2671
3443
|
setMemberDiagCollector: () => setMemberDiagCollector,
|
|
2672
3444
|
tagAbsOrigin: () => tagAbsOrigin
|
|
2673
3445
|
});
|
|
@@ -3120,7 +3892,12 @@ function isRelFn(a) {
|
|
|
3120
3892
|
if (!s || s.k !== "fn") return false;
|
|
3121
3893
|
if (s.returnType === void 0) return false;
|
|
3122
3894
|
if (s.paramTypes === void 0) return s.params.length === 0;
|
|
3123
|
-
|
|
3895
|
+
if (s.paramTypes.length === s.params.length) return true;
|
|
3896
|
+
let required = 0;
|
|
3897
|
+
for (const p of s.params) {
|
|
3898
|
+
if (p && !p.startsWith("...") && !p.endsWith("?")) required++;
|
|
3899
|
+
}
|
|
3900
|
+
return s.paramTypes.length === required;
|
|
3124
3901
|
}
|
|
3125
3902
|
function litOfTerm(t) {
|
|
3126
3903
|
return t.op === "lit" ? t.value : void 0;
|
|
@@ -3394,6 +4171,19 @@ function setApplyCallbackHost(fn) {
|
|
|
3394
4171
|
applyCallbackHost = fn;
|
|
3395
4172
|
}
|
|
3396
4173
|
function applyCallbackAbs(cb, args, env, phi2, budget) {
|
|
4174
|
+
const sumIdx = args.findIndex(
|
|
4175
|
+
(a) => a && typeof a === "object" && "shape" in a && a.shape.k === "sum"
|
|
4176
|
+
);
|
|
4177
|
+
if (sumIdx >= 0) {
|
|
4178
|
+
const members = args[sumIdx].shape.members;
|
|
4179
|
+
let acc;
|
|
4180
|
+
for (const m of members) {
|
|
4181
|
+
const nextArgs = args.map((a, i) => i === sumIdx ? m : a);
|
|
4182
|
+
const r = applyCallbackAbs(cb, nextArgs, env, phi2, budget);
|
|
4183
|
+
acc = acc === void 0 ? r : joinAbs(acc, r);
|
|
4184
|
+
}
|
|
4185
|
+
return acc ?? unknown;
|
|
4186
|
+
}
|
|
3397
4187
|
if (!applyCallbackHost) {
|
|
3398
4188
|
if (cb && typeof cb === "object" && "shape" in cb) {
|
|
3399
4189
|
const a = cb;
|
|
@@ -3405,7 +4195,7 @@ function applyCallbackAbs(cb, args, env, phi2, budget) {
|
|
|
3405
4195
|
}
|
|
3406
4196
|
return applyCallbackHost(cb, args, env, phi2, budget);
|
|
3407
4197
|
}
|
|
3408
|
-
function
|
|
4198
|
+
function undefAbs2() {
|
|
3409
4199
|
return abs(
|
|
3410
4200
|
{ k: "unknown" },
|
|
3411
4201
|
{ op: "lit", value: void 0 },
|
|
@@ -3585,6 +4375,7 @@ function getAbsProperty(recv, name) {
|
|
|
3585
4375
|
}
|
|
3586
4376
|
|
|
3587
4377
|
// src/algebra/exec/member-diag.ts
|
|
4378
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
3588
4379
|
var memberDiagCollector = null;
|
|
3589
4380
|
var callLocStack = [];
|
|
3590
4381
|
var absOrigins = /* @__PURE__ */ new WeakMap();
|
|
@@ -3684,7 +4475,41 @@ function noteUnknownMemberMissing(recv, name, kind, loc) {
|
|
|
3684
4475
|
}
|
|
3685
4476
|
function noteMemberDispatchMiss(recv, name, kind, loc) {
|
|
3686
4477
|
if (notePrimMemberMissing(recv, name, kind, loc)) return;
|
|
3687
|
-
noteUnknownMemberMissing(recv, name, kind, loc);
|
|
4478
|
+
if (noteUnknownMemberMissing(recv, name, kind, loc)) return;
|
|
4479
|
+
noteObjSlotMissing(recv, name, loc);
|
|
4480
|
+
}
|
|
4481
|
+
var evalMissingSlotAls = new AsyncLocalStorage();
|
|
4482
|
+
var evalMissingSlotFallback = false;
|
|
4483
|
+
function setEvalMissingSlotEnabled(enabled) {
|
|
4484
|
+
evalMissingSlotFallback = enabled;
|
|
4485
|
+
evalMissingSlotAls.enterWith(enabled);
|
|
4486
|
+
}
|
|
4487
|
+
function isEvalMissingSlotEnabled() {
|
|
4488
|
+
return evalMissingSlotAls.getStore() ?? evalMissingSlotFallback;
|
|
4489
|
+
}
|
|
4490
|
+
function runWithEvalMissingSlot(enabled, body) {
|
|
4491
|
+
return evalMissingSlotAls.run(enabled, body);
|
|
4492
|
+
}
|
|
4493
|
+
function noteObjSlotMissing(recv, name, loc) {
|
|
4494
|
+
if (!isEvalMissingSlotEnabled()) return false;
|
|
4495
|
+
const shape = recv?.shape;
|
|
4496
|
+
if (!shape || shape.k !== "obj") return false;
|
|
4497
|
+
const obj2 = shape;
|
|
4498
|
+
if (obj2.open) return false;
|
|
4499
|
+
if (obj2.slots && name in obj2.slots) return false;
|
|
4500
|
+
const conf = recv?.conf;
|
|
4501
|
+
if (conf === "opaque" || conf === "widened") return false;
|
|
4502
|
+
const origin = getAbsOrigin(recv);
|
|
4503
|
+
recordMemberDiag({
|
|
4504
|
+
kind: "property",
|
|
4505
|
+
name,
|
|
4506
|
+
receiver: "object",
|
|
4507
|
+
code: "nudo:missing-slot",
|
|
4508
|
+
line: loc?.[0],
|
|
4509
|
+
column: loc?.[1],
|
|
4510
|
+
...origin ? { origin } : {}
|
|
4511
|
+
});
|
|
4512
|
+
return true;
|
|
3688
4513
|
}
|
|
3689
4514
|
|
|
3690
4515
|
// src/algebra/exec/class-registry.ts
|
|
@@ -3809,6 +4634,28 @@ function withVar(env, name, value) {
|
|
|
3809
4634
|
vars.set(name, value);
|
|
3810
4635
|
return { vars, fns: env.fns, classes: env.classes, hofCollect: env.hofCollect };
|
|
3811
4636
|
}
|
|
4637
|
+
function joinEnvs(a, b, base) {
|
|
4638
|
+
const vars = new Map(base.vars);
|
|
4639
|
+
const keys = /* @__PURE__ */ new Set([...a.vars.keys(), ...b.vars.keys()]);
|
|
4640
|
+
for (const k of keys) {
|
|
4641
|
+
const va = a.vars.get(k);
|
|
4642
|
+
const vb = b.vars.get(k);
|
|
4643
|
+
const baseV = base.vars.get(k);
|
|
4644
|
+
if (va !== void 0 && vb !== void 0) {
|
|
4645
|
+
vars.set(k, va === vb ? va : joinAbs(va, vb));
|
|
4646
|
+
} else if (va !== void 0) {
|
|
4647
|
+
vars.set(k, baseV !== void 0 ? joinAbs(baseV, va) : va);
|
|
4648
|
+
} else if (vb !== void 0) {
|
|
4649
|
+
vars.set(k, baseV !== void 0 ? joinAbs(baseV, vb) : vb);
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
return {
|
|
4653
|
+
vars,
|
|
4654
|
+
fns: a.fns ?? b.fns,
|
|
4655
|
+
classes: a.classes ?? b.classes,
|
|
4656
|
+
hofCollect: a.hofCollect ?? b.hofCollect
|
|
4657
|
+
};
|
|
4658
|
+
}
|
|
3812
4659
|
var MAX_CALL_DEPTH = 64;
|
|
3813
4660
|
var MAX_TOTAL_CALLS = 2e5;
|
|
3814
4661
|
var _absCallDepth = 0;
|
|
@@ -4169,8 +5016,66 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4169
5016
|
}
|
|
4170
5017
|
case "AssignmentExpression": {
|
|
4171
5018
|
const ae = node;
|
|
4172
|
-
|
|
4173
|
-
const
|
|
5019
|
+
const op = ae.operator;
|
|
5020
|
+
const applyBin = (binOp, lhs, rhsAbs) => {
|
|
5021
|
+
switch (binOp) {
|
|
5022
|
+
case "+":
|
|
5023
|
+
return leakIfNeeded(add(lhs, rhsAbs, phi2), budget, "add");
|
|
5024
|
+
case "-":
|
|
5025
|
+
return leakIfNeeded(sub(lhs, rhsAbs, phi2), budget, "sub");
|
|
5026
|
+
case "*":
|
|
5027
|
+
return leakIfNeeded(mul(lhs, rhsAbs, phi2), budget, "mul");
|
|
5028
|
+
case "/":
|
|
5029
|
+
return leakIfNeeded(div(lhs, rhsAbs, phi2), budget, "div");
|
|
5030
|
+
case "%":
|
|
5031
|
+
return leakIfNeeded(mod(lhs, rhsAbs, phi2), budget, "mod");
|
|
5032
|
+
default:
|
|
5033
|
+
return unknown;
|
|
5034
|
+
}
|
|
5035
|
+
};
|
|
5036
|
+
let rhs;
|
|
5037
|
+
if (op === "=") {
|
|
5038
|
+
rhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5039
|
+
} else if (op === "||=" || op === "&&=" || op === "??=") {
|
|
5040
|
+
const lhs = evalNode(ae.left, env, phi2, budget).value;
|
|
5041
|
+
const lv = litValue(lhs);
|
|
5042
|
+
const nullishLit = isNullishLitAbs(lhs);
|
|
5043
|
+
const definitelyNotNullish = definitelyNotNullishShape(lhs.shape) && !nullishLit;
|
|
5044
|
+
const falsy = lv === false || nullishLit || lv === null || lv === void 0 && lhs.term?.op === "lit" && lhs.term.value === void 0;
|
|
5045
|
+
const truthy = lv !== void 0 && !falsy && !nullishLit;
|
|
5046
|
+
let assignRhs = null;
|
|
5047
|
+
if (op === "||=") {
|
|
5048
|
+
if (truthy) return ok2(lhs, phi2, env);
|
|
5049
|
+
if (falsy || nullishLit) {
|
|
5050
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5051
|
+
}
|
|
5052
|
+
} else if (op === "&&=") {
|
|
5053
|
+
if (falsy) return ok2(lhs, phi2, env);
|
|
5054
|
+
if (truthy) {
|
|
5055
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5056
|
+
}
|
|
5057
|
+
} else {
|
|
5058
|
+
if (definitelyNotNullish || lv !== void 0 && lv !== null && !nullishLit) {
|
|
5059
|
+
return ok2(lhs, phi2, env);
|
|
5060
|
+
}
|
|
5061
|
+
if (nullishLit || lv === null || lv === void 0 && lhs.term?.op === "lit") {
|
|
5062
|
+
assignRhs = evalNode(ae.right, env, phi2, budget).value;
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5065
|
+
if (assignRhs === null) {
|
|
5066
|
+
const r = evalNode(ae.right, env, phi2, budget).value;
|
|
5067
|
+
rhs = joinAbs(lhs, r);
|
|
5068
|
+
} else {
|
|
5069
|
+
rhs = assignRhs;
|
|
5070
|
+
}
|
|
5071
|
+
} else if (op.endsWith("=")) {
|
|
5072
|
+
const binOp = op.slice(0, -1);
|
|
5073
|
+
const lhs = evalNode(ae.left, env, phi2, budget).value;
|
|
5074
|
+
const rhsVal = evalNode(ae.right, env, phi2, budget).value;
|
|
5075
|
+
rhs = applyBin(binOp, lhs, rhsVal);
|
|
5076
|
+
} else {
|
|
5077
|
+
return ok2(unknown, phi2, env);
|
|
5078
|
+
}
|
|
4174
5079
|
if (ae.left.type === "MemberExpression" && ae.left.object.type === "ThisExpression") {
|
|
4175
5080
|
const prop = ae.left.property;
|
|
4176
5081
|
const key = !ae.left.computed && prop.type === "Identifier" ? prop.name : prop.type === "StringLiteral" ? prop.value : void 0;
|
|
@@ -4204,6 +5109,25 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4204
5109
|
recordAbsAssign(name, prev, rhs, loc);
|
|
4205
5110
|
return { value: rhs, phi: phi2, env: withVar(env, name, rhs) };
|
|
4206
5111
|
}
|
|
5112
|
+
if (ae.left.type === "MemberExpression") {
|
|
5113
|
+
const m = ae.left;
|
|
5114
|
+
if (m.object.type === "Identifier") {
|
|
5115
|
+
const root = m.object.name;
|
|
5116
|
+
const prev = env.vars.get(root);
|
|
5117
|
+
const key = !m.computed ? m.property.type === "Identifier" ? m.property.name : m.property.type === "StringLiteral" ? m.property.value : void 0 : void 0;
|
|
5118
|
+
if (prev && key && prev.shape.k === "obj") {
|
|
5119
|
+
const slots = { ...prev.shape.slots };
|
|
5120
|
+
slots[key] = { value: rhs };
|
|
5121
|
+
const updated = abs(
|
|
5122
|
+
{ k: "obj", slots },
|
|
5123
|
+
void 0,
|
|
5124
|
+
void 0,
|
|
5125
|
+
prev.conf === "exact" ? "path" : prev.conf
|
|
5126
|
+
);
|
|
5127
|
+
return { value: rhs, phi: phi2, env: withVar(env, root, updated) };
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
4207
5131
|
return ok2(rhs, phi2, env);
|
|
4208
5132
|
}
|
|
4209
5133
|
case "AwaitExpression": {
|
|
@@ -4233,7 +5157,7 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4233
5157
|
if (tv === false) return evalNode(cond.alternate, env, phi2, budget);
|
|
4234
5158
|
const a = evalNode(cond.consequent, env, phi2, budget);
|
|
4235
5159
|
const b = evalNode(cond.alternate, env, phi2, budget);
|
|
4236
|
-
return { value: joinAbs(a.value, b.value), phi: phi2, env };
|
|
5160
|
+
return { value: joinAbs(a.value, b.value), phi: phi2, env: joinEnvs(a.env, b.env, env) };
|
|
4237
5161
|
}
|
|
4238
5162
|
case "ForStatement":
|
|
4239
5163
|
return evalFor(node, env, phi2, budget);
|
|
@@ -4264,6 +5188,8 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4264
5188
|
}
|
|
4265
5189
|
case "IfStatement":
|
|
4266
5190
|
return evalIf(node, env, phi2, budget);
|
|
5191
|
+
case "SwitchStatement":
|
|
5192
|
+
return evalSwitch(node, env, phi2, budget);
|
|
4267
5193
|
case "ExpressionStatement":
|
|
4268
5194
|
return evalNode(node.expression, env, phi2, budget);
|
|
4269
5195
|
case "VariableDeclaration":
|
|
@@ -4285,8 +5211,10 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4285
5211
|
const le3 = node;
|
|
4286
5212
|
const l = evalNode(le3.left, env, phi2, budget);
|
|
4287
5213
|
const lv = litValue(l.value);
|
|
4288
|
-
const
|
|
4289
|
-
const
|
|
5214
|
+
const nullishLit = isNullishLitAbs(l.value);
|
|
5215
|
+
const definitelyNotNullish = definitelyNotNullishShape(l.value.shape) && !nullishLit;
|
|
5216
|
+
const falsy = lv === false || nullishLit || lv === void 0 && l.value.term?.op === "lit" && l.value.term.value === void 0 || lv === null;
|
|
5217
|
+
const truthy = lv !== void 0 && !falsy && !nullishLit;
|
|
4290
5218
|
if (le3.operator === "&&") {
|
|
4291
5219
|
if (falsy) return ok2(l.value, phi2, env);
|
|
4292
5220
|
if (truthy) return evalNode(le3.right, env, phi2, budget);
|
|
@@ -4299,6 +5227,14 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4299
5227
|
const r = evalNode(le3.right, env, phi2, budget);
|
|
4300
5228
|
return ok2(joinAbs(l.value, r.value), phi2, env);
|
|
4301
5229
|
}
|
|
5230
|
+
if (le3.operator === "??") {
|
|
5231
|
+
if (nullishLit || lv === null) return evalNode(le3.right, env, phi2, budget);
|
|
5232
|
+
if (definitelyNotNullish || lv !== void 0 && lv !== null) {
|
|
5233
|
+
return ok2(l.value, phi2, env);
|
|
5234
|
+
}
|
|
5235
|
+
const r = evalNode(le3.right, env, phi2, budget);
|
|
5236
|
+
return ok2(joinAbs(l.value, r.value), phi2, env);
|
|
5237
|
+
}
|
|
4302
5238
|
return ok2(unknown, phi2, env);
|
|
4303
5239
|
}
|
|
4304
5240
|
case "TemplateLiteral": {
|
|
@@ -4388,12 +5324,39 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
4388
5324
|
acc = spread(acc, sp);
|
|
4389
5325
|
continue;
|
|
4390
5326
|
}
|
|
4391
|
-
|
|
5327
|
+
if (p.type === "ObjectMethod") {
|
|
5328
|
+
const om = p;
|
|
5329
|
+
const keyNode2 = om.key;
|
|
5330
|
+
let key2;
|
|
5331
|
+
if (keyNode2 && keyNode2.type === "Identifier") key2 = keyNode2.name;
|
|
5332
|
+
if (keyNode2 && keyNode2.type === "StringLiteral") key2 = keyNode2.value;
|
|
5333
|
+
if (!key2 || !om.body) continue;
|
|
5334
|
+
const paramNames = (om.params ?? []).map(
|
|
5335
|
+
(pp, i) => pp.type === "Identifier" ? pp.name : `_a${i}`
|
|
5336
|
+
);
|
|
5337
|
+
const methodBody = om.body;
|
|
5338
|
+
const fnAbs = absFunction(paramNames, {
|
|
5339
|
+
body: methodBody,
|
|
5340
|
+
apply: (args) => {
|
|
5341
|
+
let e2 = env;
|
|
5342
|
+
for (let i = 0; i < paramNames.length; i++) {
|
|
5343
|
+
e2 = withVar(e2, paramNames[i], args[i] ?? unknown);
|
|
5344
|
+
}
|
|
5345
|
+
const r = evalNode(methodBody, e2, phi2, budget);
|
|
5346
|
+
return r.value;
|
|
5347
|
+
}
|
|
5348
|
+
});
|
|
5349
|
+
pending[key2] = { value: fnAbs };
|
|
5350
|
+
continue;
|
|
5351
|
+
}
|
|
5352
|
+
if (p.type !== "ObjectProperty") continue;
|
|
5353
|
+
const op = p;
|
|
5354
|
+
const keyNode = op.key;
|
|
4392
5355
|
let key;
|
|
4393
5356
|
if (keyNode && keyNode.type === "Identifier") key = keyNode.name;
|
|
4394
5357
|
if (keyNode && keyNode.type === "StringLiteral") key = keyNode.value;
|
|
4395
|
-
if (!key || !
|
|
4396
|
-
pending[key] = { value: evalNode(
|
|
5358
|
+
if (!key || !op.value) continue;
|
|
5359
|
+
pending[key] = { value: evalNode(op.value, env, phi2, budget).value };
|
|
4397
5360
|
}
|
|
4398
5361
|
acc = flushPending(acc);
|
|
4399
5362
|
return ok2(acc, phi2, env);
|
|
@@ -4446,6 +5409,16 @@ function evalBinary(node, env, phi2, budget) {
|
|
|
4446
5409
|
if (eq2 !== void 0) return ok2(boolLit(!eq2), phi2, env);
|
|
4447
5410
|
return ok2(cmp("ne", l, r, phi2), phi2, env);
|
|
4448
5411
|
}
|
|
5412
|
+
case "==": {
|
|
5413
|
+
const eq2 = looseEqAbs(l, r);
|
|
5414
|
+
if (eq2 !== void 0) return ok2(boolLit(eq2), phi2, env);
|
|
5415
|
+
return ok2(unknown, phi2, env);
|
|
5416
|
+
}
|
|
5417
|
+
case "!=": {
|
|
5418
|
+
const eq2 = looseEqAbs(l, r);
|
|
5419
|
+
if (eq2 !== void 0) return ok2(boolLit(!eq2), phi2, env);
|
|
5420
|
+
return ok2(unknown, phi2, env);
|
|
5421
|
+
}
|
|
4449
5422
|
case "/":
|
|
4450
5423
|
return ok2(leakIfNeeded(div(l, r, phi2), budget, "div"), phi2, env);
|
|
4451
5424
|
case "%":
|
|
@@ -4737,7 +5710,7 @@ function evalCall(node, env, phi2, budget) {
|
|
|
4737
5710
|
} else if (obj2.shape.k === "arr") {
|
|
4738
5711
|
applyUnaryCallback(fnNode, obj2.shape.element, env, phi2, budget);
|
|
4739
5712
|
}
|
|
4740
|
-
return ok2(
|
|
5713
|
+
return ok2(undefAbs2(), phi2, env);
|
|
4741
5714
|
}
|
|
4742
5715
|
if ((method === "some" || method === "every") && rawArgs.length >= 1) {
|
|
4743
5716
|
const fnNode = rawArgs[0];
|
|
@@ -4754,7 +5727,7 @@ function evalCall(node, env, phi2, budget) {
|
|
|
4754
5727
|
const fnNode = rawArgs[0];
|
|
4755
5728
|
const elem = obj2.shape.k === "arr" ? obj2.shape.element : obj2.shape.k === "tuple" ? obj2.shape.elements[0] ?? unknown : unknown;
|
|
4756
5729
|
applyUnaryCallback(fnNode, elem, env, phi2, budget);
|
|
4757
|
-
return ok2(joinAbs(elem,
|
|
5730
|
+
return ok2(joinAbs(elem, undefAbs2()), phi2, env);
|
|
4758
5731
|
}
|
|
4759
5732
|
{
|
|
4760
5733
|
const loc = node.loc ? [node.loc.start.line, node.loc.start.column] : void 0;
|
|
@@ -4819,7 +5792,16 @@ function applyAbsFn(fnVal, args, env, phi2, budget) {
|
|
|
4819
5792
|
const label = fnVal.shape.name ?? "anonymous";
|
|
4820
5793
|
if (!enterCall(key, label)) return truncatedAbs();
|
|
4821
5794
|
try {
|
|
4822
|
-
if (impl.apply)
|
|
5795
|
+
if (impl.apply) {
|
|
5796
|
+
try {
|
|
5797
|
+
return impl.apply(args);
|
|
5798
|
+
} catch (e) {
|
|
5799
|
+
if (e && typeof e === "object" && e.name === "NudoReturn") {
|
|
5800
|
+
return e.absValue;
|
|
5801
|
+
}
|
|
5802
|
+
throw e;
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
4823
5805
|
const base = impl.env ?? env;
|
|
4824
5806
|
let local = { vars: new Map(base.vars), fns: base.fns, hofCollect: env.hofCollect };
|
|
4825
5807
|
if (base.classes) {
|
|
@@ -4939,18 +5921,29 @@ function evalFor(node, env, phi2, budget) {
|
|
|
4939
5921
|
const r = evalNode(node.init, local, phi2, budget);
|
|
4940
5922
|
local = r.env;
|
|
4941
5923
|
}
|
|
5924
|
+
const entry = local;
|
|
4942
5925
|
let acc = unknown;
|
|
5926
|
+
let exitEnv;
|
|
5927
|
+
let sawAbstractTest = false;
|
|
4943
5928
|
for (let i = 0; i < MAX_LOOP_ITERS; i++) {
|
|
4944
5929
|
if (node.test) {
|
|
4945
5930
|
const t = evalNode(node.test, local, phi2, budget);
|
|
4946
5931
|
const lv = litValue(t.value);
|
|
4947
|
-
if (lv === false || lv === null || lv === void 0)
|
|
5932
|
+
if (lv === false || lv === null || lv === void 0) {
|
|
5933
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5934
|
+
break;
|
|
5935
|
+
}
|
|
5936
|
+
if (lv !== true) {
|
|
5937
|
+
sawAbstractTest = true;
|
|
5938
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5939
|
+
}
|
|
4948
5940
|
}
|
|
4949
5941
|
const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
|
|
4950
5942
|
if (bodyR.returned) return bodyR;
|
|
4951
5943
|
if (bodyR.threw) return bodyR;
|
|
4952
5944
|
if (bodyR.brk) {
|
|
4953
5945
|
local = bodyR.env;
|
|
5946
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
4954
5947
|
break;
|
|
4955
5948
|
}
|
|
4956
5949
|
local = bodyR.env;
|
|
@@ -4960,25 +5953,42 @@ function evalFor(node, env, phi2, budget) {
|
|
|
4960
5953
|
local = u.env;
|
|
4961
5954
|
}
|
|
4962
5955
|
}
|
|
4963
|
-
|
|
5956
|
+
if (sawAbstractTest) {
|
|
5957
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5958
|
+
}
|
|
5959
|
+
return ok2(acc, phi2, exitEnv ?? local);
|
|
4964
5960
|
}
|
|
4965
5961
|
function evalWhile(node, env, phi2, budget) {
|
|
4966
5962
|
let local = env;
|
|
5963
|
+
const entry = local;
|
|
4967
5964
|
let acc = unknown;
|
|
5965
|
+
let exitEnv;
|
|
5966
|
+
let sawAbstractTest = false;
|
|
4968
5967
|
for (let i = 0; i < MAX_LOOP_ITERS; i++) {
|
|
4969
5968
|
const t = evalNode(node.test, local, phi2, budget);
|
|
4970
5969
|
const lv = litValue(t.value);
|
|
4971
|
-
if (lv === false || lv === null || lv === void 0)
|
|
5970
|
+
if (lv === false || lv === null || lv === void 0) {
|
|
5971
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5972
|
+
break;
|
|
5973
|
+
}
|
|
5974
|
+
if (lv !== true) {
|
|
5975
|
+
sawAbstractTest = true;
|
|
5976
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5977
|
+
}
|
|
4972
5978
|
const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
|
|
4973
5979
|
if (bodyR.returned || bodyR.threw) return bodyR;
|
|
4974
5980
|
if (bodyR.brk) {
|
|
4975
5981
|
local = bodyR.env;
|
|
5982
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
4976
5983
|
break;
|
|
4977
5984
|
}
|
|
4978
5985
|
local = bodyR.env;
|
|
4979
5986
|
acc = joinAbs(acc, bodyR.value);
|
|
4980
5987
|
}
|
|
4981
|
-
|
|
5988
|
+
if (sawAbstractTest) {
|
|
5989
|
+
exitEnv = exitEnv ? joinEnvs(exitEnv, local, entry) : local;
|
|
5990
|
+
}
|
|
5991
|
+
return ok2(acc, phi2, exitEnv ?? local);
|
|
4982
5992
|
}
|
|
4983
5993
|
function evalDoWhile(node, env, phi2, budget) {
|
|
4984
5994
|
let local = env;
|
|
@@ -5009,13 +6019,50 @@ function evalForOf(node, env, phi2, budget) {
|
|
|
5009
6019
|
);
|
|
5010
6020
|
if (promoted) iterVal = promoted;
|
|
5011
6021
|
}
|
|
5012
|
-
const
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
6022
|
+
const shape = iterVal.shape;
|
|
6023
|
+
const isTuple = shape.k === "tuple";
|
|
6024
|
+
const isArr = shape.k === "arr";
|
|
6025
|
+
let elements = [];
|
|
6026
|
+
if (isArr) {
|
|
6027
|
+
elements = [shape.element];
|
|
6028
|
+
} else if (isTuple) {
|
|
6029
|
+
elements = [...shape.elements];
|
|
6030
|
+
} else if (shape.k === "sum") {
|
|
6031
|
+
elements = shape.members.flatMap(
|
|
6032
|
+
(m) => m.shape.k === "arr" ? [m.shape.element] : m.shape.k === "tuple" ? [...m.shape.elements] : []
|
|
6033
|
+
);
|
|
6034
|
+
} else {
|
|
6035
|
+
elements = [unknown];
|
|
6036
|
+
}
|
|
5016
6037
|
const left = node.left;
|
|
5017
6038
|
const bindName = left.type === "Identifier" ? left.name : left.type === "VariableDeclaration" ? left.declarations[0]?.id?.name : void 0;
|
|
5018
6039
|
if (!bindName) return ok2(unknown, phi2, env);
|
|
6040
|
+
if (isTuple && elements.length === 0) {
|
|
6041
|
+
return ok2(unknown, phi2, env);
|
|
6042
|
+
}
|
|
6043
|
+
const unbounded = !isTuple;
|
|
6044
|
+
if (unbounded) {
|
|
6045
|
+
let cur = env;
|
|
6046
|
+
let joinedEnv = env;
|
|
6047
|
+
let joinedVal = unknown;
|
|
6048
|
+
const el = elements.length > 0 ? elements[0] : unknown;
|
|
6049
|
+
const n2 = elements.length > 0 || isArr || shape.k === "sum" ? MAX_LOOP_ITERS : 0;
|
|
6050
|
+
for (let i = 0; i < n2; i++) {
|
|
6051
|
+
cur = withVar(cur, bindName, el);
|
|
6052
|
+
const bodyR = evalInConditionalFlow(() => evalNode(node.body, cur, phi2, budget));
|
|
6053
|
+
if (bodyR.returned || bodyR.threw) return bodyR;
|
|
6054
|
+
if (bodyR.brk) {
|
|
6055
|
+
cur = bodyR.env;
|
|
6056
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6057
|
+
break;
|
|
6058
|
+
}
|
|
6059
|
+
cur = bodyR.env;
|
|
6060
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6061
|
+
joinedVal = joinAbs(joinedVal, bodyR.value);
|
|
6062
|
+
}
|
|
6063
|
+
joinedEnv = joinEnvs(joinedEnv, cur, env);
|
|
6064
|
+
return ok2(joinedVal, phi2, joinedEnv);
|
|
6065
|
+
}
|
|
5019
6066
|
let local = env;
|
|
5020
6067
|
let acc = unknown;
|
|
5021
6068
|
const n = Math.min(elements.length, MAX_LOOP_ITERS);
|
|
@@ -5053,6 +6100,20 @@ function evalTry(node, env, phi2, budget) {
|
|
|
5053
6100
|
if (node.finalizer) evalNode(node.finalizer, local, curPhi, budget);
|
|
5054
6101
|
return { value: catchR.value, phi: curPhi, env: local, threw: true };
|
|
5055
6102
|
}
|
|
6103
|
+
} else if (tryR.partialThrow && node.handler) {
|
|
6104
|
+
const param = node.handler.param && node.handler.param.type === "Identifier" ? node.handler.param.name : void 0;
|
|
6105
|
+
let catchEnv = env;
|
|
6106
|
+
if (param) catchEnv = withVar(env, param, tryR.throwValue ?? tryR.value);
|
|
6107
|
+
const catchR = evalNode(node.handler.body, catchEnv, phi2, budget);
|
|
6108
|
+
value = joinAbs(tryR.value, catchR.value);
|
|
6109
|
+
local = joinEnvs(tryR.env, catchR.env, env);
|
|
6110
|
+
curPhi = catchR.phi;
|
|
6111
|
+
if (catchR.returned && tryR.returned) {
|
|
6112
|
+
return { value, phi: curPhi, env: local, returned: true };
|
|
6113
|
+
}
|
|
6114
|
+
if (catchR.threw && tryR.threw) {
|
|
6115
|
+
return { value, phi: curPhi, env: local, threw: true };
|
|
6116
|
+
}
|
|
5056
6117
|
} else if (tryR.returned) {
|
|
5057
6118
|
if (node.finalizer) evalNode(node.finalizer, local, curPhi, budget);
|
|
5058
6119
|
return tryR;
|
|
@@ -5065,7 +6126,13 @@ function evalTry(node, env, phi2, budget) {
|
|
|
5065
6126
|
if (fR.returned || fR.threw) return fR;
|
|
5066
6127
|
local = fR.env;
|
|
5067
6128
|
}
|
|
5068
|
-
return {
|
|
6129
|
+
return {
|
|
6130
|
+
value,
|
|
6131
|
+
phi: curPhi,
|
|
6132
|
+
env: local,
|
|
6133
|
+
returned: tryR.returned,
|
|
6134
|
+
...tryR.partialReturn || tryR.partialThrow ? { partialReturn: tryR.partialReturn } : {}
|
|
6135
|
+
};
|
|
5069
6136
|
}
|
|
5070
6137
|
function evalVarDecl(node, env, phi2, budget) {
|
|
5071
6138
|
let local = env;
|
|
@@ -5105,12 +6172,157 @@ function evalIf(node, env, phi2, budget) {
|
|
|
5105
6172
|
const b = evalInConditionalFlow(
|
|
5106
6173
|
() => evalNode(alt, env, fCons ? and(phi2, fCons) : phi2, budget)
|
|
5107
6174
|
);
|
|
5108
|
-
|
|
6175
|
+
const bothRet = !!a.returned && !!b.returned;
|
|
6176
|
+
const eitherRet = !!a.returned || !!b.returned;
|
|
6177
|
+
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);
|
|
6178
|
+
return {
|
|
6179
|
+
value: joinAbs(a.value, b.value),
|
|
6180
|
+
phi: phi2,
|
|
6181
|
+
env: contEnv,
|
|
6182
|
+
...bothRet ? { returned: true } : eitherRet ? { partialReturn: true } : {},
|
|
6183
|
+
...a.threw && b.threw ? { threw: true, throwValue: joinAbs(a.value, b.value) } : {},
|
|
6184
|
+
...(a.threw || b.threw) && !(a.threw && b.threw) ? { partialThrow: true, throwValue: a.threw ? a.value : b.value } : {}
|
|
6185
|
+
};
|
|
5109
6186
|
}
|
|
5110
|
-
if (a.returned
|
|
6187
|
+
if (a.returned && a.threw) {
|
|
5111
6188
|
return { value: a.value, phi: phi2, env, partialReturn: true };
|
|
5112
6189
|
}
|
|
5113
|
-
|
|
6190
|
+
if (a.returned || a.threw) {
|
|
6191
|
+
return {
|
|
6192
|
+
value: a.value,
|
|
6193
|
+
phi: phi2,
|
|
6194
|
+
env,
|
|
6195
|
+
...a.returned ? { partialReturn: true } : {},
|
|
6196
|
+
...a.threw ? { partialThrow: true, throwValue: a.value } : {}
|
|
6197
|
+
};
|
|
6198
|
+
}
|
|
6199
|
+
return { value: unknown, phi: phi2, env: joinEnvs(a.env, env, env) };
|
|
6200
|
+
}
|
|
6201
|
+
function evalSwitch(node, env, phi2, budget) {
|
|
6202
|
+
const stmtCompletes = (s) => {
|
|
6203
|
+
if (!s) return false;
|
|
6204
|
+
switch (s.type) {
|
|
6205
|
+
case "BreakStatement":
|
|
6206
|
+
case "ReturnStatement":
|
|
6207
|
+
case "ThrowStatement":
|
|
6208
|
+
case "ContinueStatement":
|
|
6209
|
+
return true;
|
|
6210
|
+
case "BlockStatement":
|
|
6211
|
+
return stmtCompletes(s.body[s.body.length - 1]);
|
|
6212
|
+
case "IfStatement": {
|
|
6213
|
+
const ifs = s;
|
|
6214
|
+
return ifs.alternate != null && stmtCompletes(ifs.consequent) && stmtCompletes(ifs.alternate);
|
|
6215
|
+
}
|
|
6216
|
+
default:
|
|
6217
|
+
return false;
|
|
6218
|
+
}
|
|
6219
|
+
};
|
|
6220
|
+
const pre = [];
|
|
6221
|
+
let pending = [];
|
|
6222
|
+
for (const c of node.cases) {
|
|
6223
|
+
if (c.test == null) {
|
|
6224
|
+
if (pending.length > 0 && c.consequent.length > 0) {
|
|
6225
|
+
pre.push({ tests: pending, body: [...c.consequent], isDefault: false });
|
|
6226
|
+
pending = [];
|
|
6227
|
+
}
|
|
6228
|
+
pre.push({ tests: [], body: [...c.consequent], isDefault: true });
|
|
6229
|
+
continue;
|
|
6230
|
+
}
|
|
6231
|
+
if (c.consequent.length === 0) {
|
|
6232
|
+
pending.push(c.test);
|
|
6233
|
+
continue;
|
|
6234
|
+
}
|
|
6235
|
+
pre.push({ tests: [...pending, c.test], body: [...c.consequent], isDefault: false });
|
|
6236
|
+
pending = [];
|
|
6237
|
+
}
|
|
6238
|
+
if (pending.length > 0) pre.push({ tests: pending, body: [], isDefault: false });
|
|
6239
|
+
const arms = pre.map((a) => ({ ...a, tests: [...a.tests], body: [...a.body] }));
|
|
6240
|
+
for (let i = 0; i < arms.length; i++) {
|
|
6241
|
+
const arm = arms[i];
|
|
6242
|
+
const body = [...arm.body];
|
|
6243
|
+
let j = i + 1;
|
|
6244
|
+
while (j < arms.length && !stmtCompletes(body[body.length - 1])) {
|
|
6245
|
+
body.push(...arms[j].body);
|
|
6246
|
+
if (stmtCompletes(body[body.length - 1])) break;
|
|
6247
|
+
j++;
|
|
6248
|
+
}
|
|
6249
|
+
arm.body = body;
|
|
6250
|
+
}
|
|
6251
|
+
const runBody = (body, e) => {
|
|
6252
|
+
let local = e;
|
|
6253
|
+
let value2 = unknown;
|
|
6254
|
+
for (const s of body) {
|
|
6255
|
+
const r = evalInConditionalFlow(() => evalNode(s, local, phi2, budget));
|
|
6256
|
+
local = r.env;
|
|
6257
|
+
value2 = r.value;
|
|
6258
|
+
if (r.returned || r.threw || r.brk) return { ...r, env: local, value: value2 };
|
|
6259
|
+
}
|
|
6260
|
+
return { value: value2, phi: phi2, env: local };
|
|
6261
|
+
};
|
|
6262
|
+
const disc = evalNode(node.discriminant, env, phi2, budget).value;
|
|
6263
|
+
const dlv = litValue(disc);
|
|
6264
|
+
const hasDefault = arms.some((a) => a.isDefault);
|
|
6265
|
+
const testLit = (t) => {
|
|
6266
|
+
if (t == null) return null;
|
|
6267
|
+
return litValue(evalNode(t, env, phi2, budget).value);
|
|
6268
|
+
};
|
|
6269
|
+
if (dlv !== void 0) {
|
|
6270
|
+
let matched = null;
|
|
6271
|
+
let sawAbstractTest = false;
|
|
6272
|
+
for (const arm of arms) {
|
|
6273
|
+
if (arm.isDefault) continue;
|
|
6274
|
+
let hit = false;
|
|
6275
|
+
for (const t of arm.tests) {
|
|
6276
|
+
const tv = testLit(t);
|
|
6277
|
+
if (tv === null) continue;
|
|
6278
|
+
if (tv === void 0) {
|
|
6279
|
+
sawAbstractTest = true;
|
|
6280
|
+
continue;
|
|
6281
|
+
}
|
|
6282
|
+
if (tv === dlv) {
|
|
6283
|
+
hit = true;
|
|
6284
|
+
break;
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
if (hit) {
|
|
6288
|
+
matched = arm;
|
|
6289
|
+
break;
|
|
6290
|
+
}
|
|
6291
|
+
}
|
|
6292
|
+
if (!sawAbstractTest) {
|
|
6293
|
+
if (matched) return runBody(matched.body, env);
|
|
6294
|
+
const dflt = arms.find((a) => a.isDefault);
|
|
6295
|
+
if (dflt) return runBody(dflt.body, env);
|
|
6296
|
+
return ok2(unknown, phi2, env);
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
const results = [];
|
|
6300
|
+
if (!hasDefault) results.push(ok2(unknown, phi2, env));
|
|
6301
|
+
for (const arm of arms) {
|
|
6302
|
+
if (arm.body.length === 0 && !arm.isDefault) continue;
|
|
6303
|
+
results.push(runBody(arm.body, env));
|
|
6304
|
+
}
|
|
6305
|
+
if (results.length === 0) return ok2(unknown, phi2, env);
|
|
6306
|
+
let value = results[0].value;
|
|
6307
|
+
let envOut = results[0].env;
|
|
6308
|
+
let allRet = !!results[0].returned;
|
|
6309
|
+
let anyRet = !!results[0].returned;
|
|
6310
|
+
let anyThrew = !!results[0].threw;
|
|
6311
|
+
for (let i = 1; i < results.length; i++) {
|
|
6312
|
+
const r = results[i];
|
|
6313
|
+
value = joinAbs(value, r.value);
|
|
6314
|
+
envOut = joinEnvs(envOut, r.env, env);
|
|
6315
|
+
allRet = allRet && !!r.returned;
|
|
6316
|
+
anyRet = anyRet || !!r.returned;
|
|
6317
|
+
anyThrew = anyThrew || !!r.threw;
|
|
6318
|
+
}
|
|
6319
|
+
return {
|
|
6320
|
+
value,
|
|
6321
|
+
phi: phi2,
|
|
6322
|
+
env: envOut,
|
|
6323
|
+
...allRet ? { returned: true } : anyRet ? { partialReturn: true } : {},
|
|
6324
|
+
...anyThrew ? { partialThrow: true } : {}
|
|
6325
|
+
};
|
|
5114
6326
|
}
|
|
5115
6327
|
function analyzeFn(source, fnName, args, phi2 = pTrue, budget, file, modules) {
|
|
5116
6328
|
return evalSource(source, { fn: fnName, args }, { phi: phi2, budget, file, modules }).value;
|
|
@@ -5281,7 +6493,7 @@ function $callNamed(name, fn, args, loc, argLocs) {
|
|
|
5281
6493
|
try {
|
|
5282
6494
|
if (typeof fn === "function") {
|
|
5283
6495
|
const g = GLOBAL_FNS.has(name) && fn === globalThis[name] ? evalGlobalFn(name, args) : void 0;
|
|
5284
|
-
result = g ?? fn(...args);
|
|
6496
|
+
result = g ?? callAtFunctionBoundary(() => fn(...args));
|
|
5285
6497
|
} else if (fn && typeof fn === "object" && "shape" in fn) {
|
|
5286
6498
|
result = $call(fn, args);
|
|
5287
6499
|
}
|
|
@@ -5352,6 +6564,14 @@ function $ne(a, b) {
|
|
|
5352
6564
|
const r = strictEqAbs(a, b);
|
|
5353
6565
|
return r === void 0 ? bool() : boolLit(!r);
|
|
5354
6566
|
}
|
|
6567
|
+
function $eqLoose(a, b) {
|
|
6568
|
+
const r = looseEqAbs(a, b);
|
|
6569
|
+
return r === void 0 ? bool() : boolLit(r);
|
|
6570
|
+
}
|
|
6571
|
+
function $neLoose(a, b) {
|
|
6572
|
+
const r = looseEqAbs(a, b);
|
|
6573
|
+
return r === void 0 ? bool() : boolLit(!r);
|
|
6574
|
+
}
|
|
5355
6575
|
function $lt(a, b) {
|
|
5356
6576
|
return cmp("lt", a, b, phi);
|
|
5357
6577
|
}
|
|
@@ -5375,13 +6595,28 @@ function asAbsVal(v2) {
|
|
|
5375
6595
|
const params = Array.from({ length: n }, (_, i) => `arg${i}`);
|
|
5376
6596
|
return absFunction(params, {
|
|
5377
6597
|
body: noBody,
|
|
5378
|
-
|
|
6598
|
+
// 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
|
|
6599
|
+
apply: (args) => callAtFunctionBoundary(() => v2(...args))
|
|
5379
6600
|
});
|
|
5380
6601
|
}
|
|
5381
6602
|
return $lit(v2);
|
|
5382
6603
|
}
|
|
5383
|
-
function
|
|
5384
|
-
return
|
|
6604
|
+
function callAtFunctionBoundary(body) {
|
|
6605
|
+
return runWithLoopExits(() => {
|
|
6606
|
+
try {
|
|
6607
|
+
return body();
|
|
6608
|
+
} catch (e) {
|
|
6609
|
+
if (isNudoReturn(e)) return e.absValue;
|
|
6610
|
+
throw e;
|
|
6611
|
+
}
|
|
6612
|
+
});
|
|
6613
|
+
}
|
|
6614
|
+
function $fnVal(params, impl, opts) {
|
|
6615
|
+
return absFunction(params, {
|
|
6616
|
+
body: noBody,
|
|
6617
|
+
apply: (args) => callAtFunctionBoundary(() => impl(...args)),
|
|
6618
|
+
...opts?.bindThis ? { bindThis: true } : {}
|
|
6619
|
+
});
|
|
5385
6620
|
}
|
|
5386
6621
|
function $lit(v2) {
|
|
5387
6622
|
if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
|
|
@@ -5436,12 +6671,163 @@ function isDefinitelyFalse(a) {
|
|
|
5436
6671
|
function undef() {
|
|
5437
6672
|
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
|
|
5438
6673
|
}
|
|
6674
|
+
var loopExitsAls = new AsyncLocalStorage2();
|
|
6675
|
+
var throwExitsAls = new AsyncLocalStorage2();
|
|
6676
|
+
var tryMarksAls = new AsyncLocalStorage2();
|
|
6677
|
+
function runWithLoopExits(body) {
|
|
6678
|
+
return loopExitsAls.run(
|
|
6679
|
+
[],
|
|
6680
|
+
() => throwExitsAls.run([], () => tryMarksAls.run([], body))
|
|
6681
|
+
);
|
|
6682
|
+
}
|
|
6683
|
+
function takeLoopExits() {
|
|
6684
|
+
return loopExitsAls.getStore() ?? [];
|
|
6685
|
+
}
|
|
6686
|
+
function takeThrowExits() {
|
|
6687
|
+
return throwExitsAls.getStore() ?? [];
|
|
6688
|
+
}
|
|
6689
|
+
function pushLoopExit(v2) {
|
|
6690
|
+
loopExitsAls.getStore()?.push(v2);
|
|
6691
|
+
}
|
|
6692
|
+
function pushThrowExit(v2) {
|
|
6693
|
+
throwExitsAls.getStore()?.push(v2);
|
|
6694
|
+
}
|
|
6695
|
+
function $pushLoopExit(v2) {
|
|
6696
|
+
pushLoopExit(v2);
|
|
6697
|
+
}
|
|
6698
|
+
function $tryMark() {
|
|
6699
|
+
const store = throwExitsAls.getStore();
|
|
6700
|
+
const m = store?.length ?? 0;
|
|
6701
|
+
tryMarksAls.getStore()?.push(m);
|
|
6702
|
+
return m;
|
|
6703
|
+
}
|
|
6704
|
+
function $tryCurrentMark() {
|
|
6705
|
+
const stack = tryMarksAls.getStore();
|
|
6706
|
+
return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
|
|
6707
|
+
}
|
|
6708
|
+
function $tryPopMark() {
|
|
6709
|
+
tryMarksAls.getStore()?.pop();
|
|
6710
|
+
}
|
|
6711
|
+
function $tryTakeSince(mark) {
|
|
6712
|
+
const store = throwExitsAls.getStore();
|
|
6713
|
+
if (!store) return [];
|
|
6714
|
+
return store.splice(Math.min(mark, store.length));
|
|
6715
|
+
}
|
|
6716
|
+
var yieldStack = [];
|
|
6717
|
+
var genPathSensitive = 0;
|
|
6718
|
+
var genJoinOverride = null;
|
|
6719
|
+
function withIsolatedYields(fn) {
|
|
6720
|
+
const top = yieldStack[yieldStack.length - 1];
|
|
6721
|
+
if (!top) return { v: fn(), ys: null };
|
|
6722
|
+
const armYs = [];
|
|
6723
|
+
yieldStack[yieldStack.length - 1] = armYs;
|
|
6724
|
+
try {
|
|
6725
|
+
return { v: fn(), ys: armYs };
|
|
6726
|
+
} finally {
|
|
6727
|
+
yieldStack[yieldStack.length - 1] = top;
|
|
6728
|
+
}
|
|
6729
|
+
}
|
|
6730
|
+
function mergeArmYields(armYsList) {
|
|
6731
|
+
const top = yieldStack[yieldStack.length - 1];
|
|
6732
|
+
if (!top || armYsList.length === 0) return;
|
|
6733
|
+
const concrete = armYsList.filter((x) => x !== null);
|
|
6734
|
+
if (concrete.length === 0) return;
|
|
6735
|
+
if (concrete.length === 1) {
|
|
6736
|
+
top.push(...concrete[0]);
|
|
6737
|
+
return;
|
|
6738
|
+
}
|
|
6739
|
+
let joined = null;
|
|
6740
|
+
for (const ys of concrete) {
|
|
6741
|
+
joined = joined ? joinAbs(joined, $arr(ys)) : $arr(ys);
|
|
6742
|
+
}
|
|
6743
|
+
genPathSensitive++;
|
|
6744
|
+
if (joined) genJoinOverride = joined;
|
|
6745
|
+
for (const ys of concrete) top.push(...ys);
|
|
6746
|
+
}
|
|
6747
|
+
function runForkArm(arm, exits) {
|
|
6748
|
+
try {
|
|
6749
|
+
return { kind: "val", v: asAbsVal(arm()) };
|
|
6750
|
+
} catch (e) {
|
|
6751
|
+
if (isNudoReturn(e)) {
|
|
6752
|
+
exits?.push(e.absValue);
|
|
6753
|
+
return { kind: "ret", v: e.absValue };
|
|
6754
|
+
}
|
|
6755
|
+
if (isNudoThrow(e)) {
|
|
6756
|
+
pushThrowExit(e.absValue);
|
|
6757
|
+
return { kind: "throw", v: e.absValue };
|
|
6758
|
+
}
|
|
6759
|
+
throw e;
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
function settleForkArms(a, b, exits) {
|
|
6763
|
+
const throws = [a, b].filter((r) => r.kind === "throw");
|
|
6764
|
+
const nonThrow = [a, b].filter((r) => r.kind !== "throw");
|
|
6765
|
+
if (nonThrow.length === 0) {
|
|
6766
|
+
throw new NudoThrow(throws.map((t) => t.v).reduce((x, y) => joinAbs(x, y)));
|
|
6767
|
+
}
|
|
6768
|
+
const first = nonThrow[0];
|
|
6769
|
+
const second = nonThrow[1] ?? first;
|
|
6770
|
+
if (first.kind === "ret" && second.kind === "ret") {
|
|
6771
|
+
throw new NudoReturn(joinAbs(first.v, second.v));
|
|
6772
|
+
}
|
|
6773
|
+
if (nonThrow.length === 1) {
|
|
6774
|
+
if (first.kind === "ret") {
|
|
6775
|
+
if (!exits) throw new NudoReturn(first.v);
|
|
6776
|
+
return undef();
|
|
6777
|
+
}
|
|
6778
|
+
return first.v;
|
|
6779
|
+
}
|
|
6780
|
+
if (first.kind === "ret") {
|
|
6781
|
+
if (!exits) throw new NudoReturn(first.v);
|
|
6782
|
+
return second.kind === "val" ? second.v : undef();
|
|
6783
|
+
}
|
|
6784
|
+
if (second.kind === "ret") {
|
|
6785
|
+
if (!exits) throw new NudoReturn(second.v);
|
|
6786
|
+
return first.v;
|
|
6787
|
+
}
|
|
6788
|
+
return joinAbs(first.v, second.v);
|
|
6789
|
+
}
|
|
5439
6790
|
function $fork(test, consequent, alternate) {
|
|
5440
6791
|
if (isDefinitelyTrue(test)) return asAbsVal(consequent());
|
|
5441
6792
|
if (isDefinitelyFalse(test)) return alternate ? asAbsVal(alternate()) : undef();
|
|
5442
|
-
const
|
|
5443
|
-
|
|
5444
|
-
|
|
6793
|
+
const exits = loopExitsAls.getStore();
|
|
6794
|
+
beginCollectionFork();
|
|
6795
|
+
const arms = [];
|
|
6796
|
+
const armYsList = [];
|
|
6797
|
+
let a;
|
|
6798
|
+
let b;
|
|
6799
|
+
try {
|
|
6800
|
+
pushCollectionArm();
|
|
6801
|
+
try {
|
|
6802
|
+
const r = withIsolatedYields(() => runForkArm(consequent, exits));
|
|
6803
|
+
a = r.v;
|
|
6804
|
+
armYsList.push(r.ys);
|
|
6805
|
+
} finally {
|
|
6806
|
+
arms.push(popCollectionArm());
|
|
6807
|
+
}
|
|
6808
|
+
if (alternate) {
|
|
6809
|
+
pushCollectionArm();
|
|
6810
|
+
try {
|
|
6811
|
+
const r = withIsolatedYields(() => runForkArm(alternate, exits));
|
|
6812
|
+
b = r.v;
|
|
6813
|
+
armYsList.push(r.ys);
|
|
6814
|
+
} finally {
|
|
6815
|
+
arms.push(popCollectionArm());
|
|
6816
|
+
}
|
|
6817
|
+
} else {
|
|
6818
|
+
pushCollectionArm();
|
|
6819
|
+
try {
|
|
6820
|
+
b = { kind: "val", v: undef() };
|
|
6821
|
+
armYsList.push(null);
|
|
6822
|
+
} finally {
|
|
6823
|
+
arms.push(popCollectionArm());
|
|
6824
|
+
}
|
|
6825
|
+
}
|
|
6826
|
+
} finally {
|
|
6827
|
+
endCollectionFork(arms);
|
|
6828
|
+
if (yieldStack.length > 0) mergeArmYields(armYsList);
|
|
6829
|
+
}
|
|
6830
|
+
return settleForkArms(a, b, exits);
|
|
5445
6831
|
}
|
|
5446
6832
|
var DEFAULT_MAX_LOOP_ITERS = 8;
|
|
5447
6833
|
function* $forIter(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
@@ -5457,30 +6843,67 @@ function* $forIter(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
|
5457
6843
|
s = step(afterBody);
|
|
5458
6844
|
}
|
|
5459
6845
|
}
|
|
5460
|
-
function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
6846
|
+
function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
5461
6847
|
let state = init;
|
|
5462
6848
|
let exitJoin;
|
|
6849
|
+
let extJoin;
|
|
6850
|
+
const pack = opts?.pack;
|
|
6851
|
+
const unpack = opts?.unpack;
|
|
6852
|
+
const snapCounter = () => {
|
|
6853
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, state) : state;
|
|
6854
|
+
};
|
|
6855
|
+
const snapExt = () => {
|
|
6856
|
+
if (!pack) return;
|
|
6857
|
+
const p = pack();
|
|
6858
|
+
extJoin = extJoin ? joinAbs(extJoin, p) : p;
|
|
6859
|
+
};
|
|
6860
|
+
const applyExtJoin = () => {
|
|
6861
|
+
if (!extJoin || !pack || !unpack) return;
|
|
6862
|
+
unpack(joinAbs(extJoin, pack()));
|
|
6863
|
+
};
|
|
5463
6864
|
for (let i = 0; i < maxIters; i++) {
|
|
5464
6865
|
const t = test(state);
|
|
5465
6866
|
if (isDefinitelyFalse(t)) {
|
|
5466
|
-
|
|
6867
|
+
snapCounter();
|
|
6868
|
+
snapExt();
|
|
6869
|
+
applyExtJoin();
|
|
6870
|
+
return exitJoin ?? state;
|
|
5467
6871
|
}
|
|
5468
|
-
|
|
5469
|
-
|
|
6872
|
+
const abstractTest = !isDefinitelyTrue(t);
|
|
6873
|
+
if (abstractTest) {
|
|
6874
|
+
snapCounter();
|
|
6875
|
+
snapExt();
|
|
6876
|
+
}
|
|
6877
|
+
let afterBody;
|
|
6878
|
+
try {
|
|
6879
|
+
afterBody = body(state);
|
|
6880
|
+
} catch (e) {
|
|
6881
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
6882
|
+
throw e;
|
|
5470
6883
|
}
|
|
5471
|
-
const afterBody = body(state);
|
|
5472
6884
|
const next = step(afterBody);
|
|
6885
|
+
if (abstractTest) {
|
|
6886
|
+
state = afterBody;
|
|
6887
|
+
snapExt();
|
|
6888
|
+
}
|
|
5473
6889
|
if (i > 0) {
|
|
5474
6890
|
const nv = litValue(next);
|
|
5475
6891
|
const sv = litValue(state);
|
|
5476
6892
|
const stuck = nv !== void 0 && sv !== void 0 && nv === sv || nv === void 0 && sv === void 0 && leqAbs(next, state).ok;
|
|
5477
6893
|
if (stuck) {
|
|
5478
|
-
|
|
6894
|
+
state = next;
|
|
6895
|
+
snapCounter();
|
|
6896
|
+
snapExt();
|
|
6897
|
+
applyExtJoin();
|
|
6898
|
+
return exitJoin ?? next;
|
|
5479
6899
|
}
|
|
5480
6900
|
}
|
|
5481
6901
|
state = next;
|
|
5482
6902
|
}
|
|
5483
|
-
|
|
6903
|
+
snapCounter();
|
|
6904
|
+
snapExt();
|
|
6905
|
+
applyExtJoin();
|
|
6906
|
+
return exitJoin ?? state;
|
|
5484
6907
|
}
|
|
5485
6908
|
function tupleOrWiden(els, conf) {
|
|
5486
6909
|
if (shouldWidenArrayLiteral(els.length)) {
|
|
@@ -5496,6 +6919,99 @@ function tupleOrWiden(els, conf) {
|
|
|
5496
6919
|
function $arr(items) {
|
|
5497
6920
|
return tupleOrWiden(items.map(asAbsVal), "exact");
|
|
5498
6921
|
}
|
|
6922
|
+
var ARR_MUTATORS = /* @__PURE__ */ new Set([
|
|
6923
|
+
"push",
|
|
6924
|
+
"unshift",
|
|
6925
|
+
"pop",
|
|
6926
|
+
"shift",
|
|
6927
|
+
"splice",
|
|
6928
|
+
"reverse",
|
|
6929
|
+
"sort"
|
|
6930
|
+
]);
|
|
6931
|
+
function isArrMutator(name) {
|
|
6932
|
+
return ARR_MUTATORS.has(name);
|
|
6933
|
+
}
|
|
6934
|
+
function $arrMutContainer(arr, method, args) {
|
|
6935
|
+
const shape = arr.shape;
|
|
6936
|
+
if (shape.k !== "tuple" && shape.k !== "arr") return arr;
|
|
6937
|
+
const vals = args.map((a) => asAbsVal(a));
|
|
6938
|
+
const asArrEl = (els) => els.length > 0 ? els.reduce((x, y) => joinAbs(x, y)) : unknown;
|
|
6939
|
+
if (method === "push" || method === "unshift") {
|
|
6940
|
+
if (shape.k === "tuple") {
|
|
6941
|
+
const els = method === "push" ? [...shape.elements, ...vals] : [...vals, ...shape.elements];
|
|
6942
|
+
const conf = vals.reduce(
|
|
6943
|
+
(acc, v2) => confJoin(acc, v2.conf),
|
|
6944
|
+
arr.conf
|
|
6945
|
+
);
|
|
6946
|
+
return abs(
|
|
6947
|
+
{ k: "tuple", elements: els },
|
|
6948
|
+
void 0,
|
|
6949
|
+
void 0,
|
|
6950
|
+
conf
|
|
6951
|
+
);
|
|
6952
|
+
}
|
|
6953
|
+
const el = vals.reduce((acc, v2) => joinAbs(acc, v2), shape.element);
|
|
6954
|
+
return abs({ k: "arr", element: el }, void 0, void 0, confJoin(arr.conf, "path"));
|
|
6955
|
+
}
|
|
6956
|
+
if (method === "pop") {
|
|
6957
|
+
if (shape.k === "tuple") {
|
|
6958
|
+
if (shape.elements.length === 0) return arr;
|
|
6959
|
+
return abs(
|
|
6960
|
+
{ k: "tuple", elements: shape.elements.slice(0, -1) },
|
|
6961
|
+
void 0,
|
|
6962
|
+
void 0,
|
|
6963
|
+
arr.conf
|
|
6964
|
+
);
|
|
6965
|
+
}
|
|
6966
|
+
return arr;
|
|
6967
|
+
}
|
|
6968
|
+
if (method === "shift") {
|
|
6969
|
+
if (shape.k === "tuple") {
|
|
6970
|
+
if (shape.elements.length === 0) return arr;
|
|
6971
|
+
return abs(
|
|
6972
|
+
{ k: "tuple", elements: shape.elements.slice(1) },
|
|
6973
|
+
void 0,
|
|
6974
|
+
void 0,
|
|
6975
|
+
arr.conf
|
|
6976
|
+
);
|
|
6977
|
+
}
|
|
6978
|
+
return arr;
|
|
6979
|
+
}
|
|
6980
|
+
if (method === "splice") {
|
|
6981
|
+
if (shape.k === "tuple") {
|
|
6982
|
+
return abs(
|
|
6983
|
+
{ k: "arr", element: asArrEl(shape.elements) },
|
|
6984
|
+
void 0,
|
|
6985
|
+
void 0,
|
|
6986
|
+
confJoin(arr.conf, "path")
|
|
6987
|
+
);
|
|
6988
|
+
}
|
|
6989
|
+
return arr;
|
|
6990
|
+
}
|
|
6991
|
+
if (method === "reverse") {
|
|
6992
|
+
if (shape.k === "tuple") {
|
|
6993
|
+
return abs(
|
|
6994
|
+
{ k: "tuple", elements: [...shape.elements].reverse() },
|
|
6995
|
+
void 0,
|
|
6996
|
+
void 0,
|
|
6997
|
+
arr.conf
|
|
6998
|
+
);
|
|
6999
|
+
}
|
|
7000
|
+
return arr;
|
|
7001
|
+
}
|
|
7002
|
+
if (method === "sort") {
|
|
7003
|
+
if (shape.k === "tuple") {
|
|
7004
|
+
return abs(
|
|
7005
|
+
{ k: "arr", element: asArrEl(shape.elements) },
|
|
7006
|
+
void 0,
|
|
7007
|
+
void 0,
|
|
7008
|
+
confJoin(arr.conf, "path")
|
|
7009
|
+
);
|
|
7010
|
+
}
|
|
7011
|
+
return arr;
|
|
7012
|
+
}
|
|
7013
|
+
return arr;
|
|
7014
|
+
}
|
|
5499
7015
|
function $idx(a, i) {
|
|
5500
7016
|
const iv = litValue(i);
|
|
5501
7017
|
if (a.shape.k === "tuple") {
|
|
@@ -5511,6 +7027,22 @@ function $idx(a, i) {
|
|
|
5511
7027
|
if (a.shape.k === "sum") {
|
|
5512
7028
|
return a.shape.members.map((m) => $idx(m, i)).reduce((x, y) => joinAbs(x, y));
|
|
5513
7029
|
}
|
|
7030
|
+
if (a.shape.k === "obj" || a.shape.k === "brand" && a.shape.shape.shape.k === "obj") {
|
|
7031
|
+
const objShape = a.shape.k === "obj" ? a.shape : a.shape.shape.shape;
|
|
7032
|
+
const slots = Object.values(objShape.slots).map((s) => s.value);
|
|
7033
|
+
if (slots.length === 0) return objShape.open ? unknown : undef();
|
|
7034
|
+
const joinSlotsWithUndef = () => joinAbs(slots.reduce((x, y) => joinAbs(x, y)), undef());
|
|
7035
|
+
if (typeof iv === "string" || typeof iv === "number" || typeof iv === "boolean") {
|
|
7036
|
+
const slot = objShape.slots[String(iv)];
|
|
7037
|
+
if (slot) return slot.value;
|
|
7038
|
+
if (objShape.open) return unknown;
|
|
7039
|
+
return undef();
|
|
7040
|
+
}
|
|
7041
|
+
if (objShape.open && slots.length > 0) {
|
|
7042
|
+
return joinAbs(slots.reduce((x, y) => joinAbs(x, y)), unknown);
|
|
7043
|
+
}
|
|
7044
|
+
return joinSlotsWithUndef();
|
|
7045
|
+
}
|
|
5514
7046
|
const sv = litValue(a);
|
|
5515
7047
|
if (typeof sv === "string") {
|
|
5516
7048
|
if (typeof iv === "number" && Number.isInteger(iv)) {
|
|
@@ -5570,6 +7102,35 @@ function $obj(slots) {
|
|
|
5570
7102
|
function $spread(a, b) {
|
|
5571
7103
|
return spread(asAbsVal(a), asAbsVal(b));
|
|
5572
7104
|
}
|
|
7105
|
+
function $objRest(o, keys) {
|
|
7106
|
+
o = asAbsVal(o);
|
|
7107
|
+
if (o.shape.k === "sum") {
|
|
7108
|
+
return o.shape.members.map((m) => $objRest(m, keys)).reduce((a, b) => joinAbs(a, b));
|
|
7109
|
+
}
|
|
7110
|
+
if (!isObj(o)) return unknown;
|
|
7111
|
+
const drop = new Set(keys);
|
|
7112
|
+
const slots = {};
|
|
7113
|
+
let openRest = o.shape.open === true;
|
|
7114
|
+
for (const [k, s] of Object.entries(o.shape.slots)) {
|
|
7115
|
+
if (drop.has(k)) continue;
|
|
7116
|
+
slots[k] = s;
|
|
7117
|
+
}
|
|
7118
|
+
if (o.shape.open) openRest = true;
|
|
7119
|
+
const shape = { k: "obj", slots };
|
|
7120
|
+
if (openRest) shape.open = true;
|
|
7121
|
+
return { shape, conf: o.conf === "exact" ? "exact" : confJoin(o.conf, "partial") };
|
|
7122
|
+
}
|
|
7123
|
+
function $arrRest(a, start) {
|
|
7124
|
+
a = asAbsVal(a);
|
|
7125
|
+
if (a.shape.k === "sum") {
|
|
7126
|
+
return a.shape.members.map((m) => $arrRest(m, start)).reduce((x, y) => joinAbs(x, y));
|
|
7127
|
+
}
|
|
7128
|
+
if (a.shape.k === "tuple") {
|
|
7129
|
+
return tupleOrWiden(a.shape.elements.slice(start), a.conf);
|
|
7130
|
+
}
|
|
7131
|
+
if (a.shape.k === "arr") return a;
|
|
7132
|
+
return unknown;
|
|
7133
|
+
}
|
|
5573
7134
|
function $concat(a, b) {
|
|
5574
7135
|
a = asAbsVal(a);
|
|
5575
7136
|
b = asAbsVal(b);
|
|
@@ -5604,20 +7165,49 @@ function $concat(a, b) {
|
|
|
5604
7165
|
function $elems(a) {
|
|
5605
7166
|
if (a.shape.k === "tuple") return [...a.shape.elements];
|
|
5606
7167
|
if (a.shape.k === "arr") return [a.shape.element];
|
|
7168
|
+
if (isSetAbs(a)) return setElementsAbs(a);
|
|
7169
|
+
if (isMapAbs(a)) return mapEntriesAbs(a);
|
|
5607
7170
|
return [unknown];
|
|
5608
7171
|
}
|
|
5609
|
-
function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
7172
|
+
function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
7173
|
+
const pack = opts?.pack;
|
|
7174
|
+
const unpack = opts?.unpack;
|
|
7175
|
+
let exitJoin;
|
|
7176
|
+
const snapExit = () => {
|
|
7177
|
+
if (!pack) return;
|
|
7178
|
+
const s = pack();
|
|
7179
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, s) : s;
|
|
7180
|
+
};
|
|
7181
|
+
const applyExitJoin = () => {
|
|
7182
|
+
if (!exitJoin || !pack || !unpack) return;
|
|
7183
|
+
unpack(joinAbs(exitJoin, pack()));
|
|
7184
|
+
};
|
|
7185
|
+
const shape = iterable.shape;
|
|
5610
7186
|
const items = $elems(iterable);
|
|
5611
|
-
const
|
|
7187
|
+
const knownLen = shape.k === "tuple" ? shape.elements.length : collectionExactLen(iterable);
|
|
7188
|
+
const unbounded = knownLen === void 0;
|
|
7189
|
+
if (unbounded) snapExit();
|
|
7190
|
+
const n = knownLen !== void 0 ? Math.min(knownLen, maxIters) : items.length > 0 ? maxIters : 0;
|
|
5612
7191
|
for (let i = 0; i < n; i++) {
|
|
5613
7192
|
const item = items.length > 0 ? items[Math.min(i, items.length - 1)] : unknown;
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
7193
|
+
try {
|
|
7194
|
+
body(
|
|
7195
|
+
item,
|
|
7196
|
+
abs(
|
|
7197
|
+
{ k: "prim", type: "number" },
|
|
7198
|
+
{ op: "lit", value: i },
|
|
7199
|
+
pTrue,
|
|
7200
|
+
"exact"
|
|
7201
|
+
)
|
|
7202
|
+
);
|
|
7203
|
+
} catch (e) {
|
|
7204
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
7205
|
+
throw e;
|
|
7206
|
+
}
|
|
7207
|
+
if (unbounded) snapExit();
|
|
5620
7208
|
}
|
|
7209
|
+
if (unbounded && n === 0) snapExit();
|
|
7210
|
+
applyExitJoin();
|
|
5621
7211
|
}
|
|
5622
7212
|
function namespaceNameOf(v2) {
|
|
5623
7213
|
if (typeof v2 !== "object" && typeof v2 !== "function") return void 0;
|
|
@@ -5665,11 +7255,19 @@ function $get(o, key, opts) {
|
|
|
5665
7255
|
}
|
|
5666
7256
|
return unknown;
|
|
5667
7257
|
}
|
|
5668
|
-
if (o.shape.k === "brand")
|
|
7258
|
+
if (o.shape.k === "brand") {
|
|
7259
|
+
if (key === "size" && o.shape.name === "Map") return mapSizeAbs(o);
|
|
7260
|
+
if (key === "size" && o.shape.name === "Set") return setSizeAbs(o);
|
|
7261
|
+
return $get(o.shape.shape, key, opts);
|
|
7262
|
+
}
|
|
5669
7263
|
if (isObj(o)) {
|
|
5670
7264
|
const slot = o.shape.slots[key];
|
|
5671
|
-
if (slot)
|
|
7265
|
+
if (slot) {
|
|
7266
|
+
if (slot.optional) return joinAbs(slot.value, undef());
|
|
7267
|
+
return slot.value;
|
|
7268
|
+
}
|
|
5672
7269
|
if (o.shape.open) return unknown;
|
|
7270
|
+
noteObjSlotMissing(o, key);
|
|
5673
7271
|
return undef();
|
|
5674
7272
|
}
|
|
5675
7273
|
if (o.shape.k === "sum") {
|
|
@@ -5678,6 +7276,7 @@ function $get(o, key, opts) {
|
|
|
5678
7276
|
}
|
|
5679
7277
|
if (!opts?.silent) {
|
|
5680
7278
|
noteUnknownMemberMissing(o, key, "property");
|
|
7279
|
+
noteObjSlotMissing(o, key);
|
|
5681
7280
|
}
|
|
5682
7281
|
return unknown;
|
|
5683
7282
|
}
|
|
@@ -5725,12 +7324,52 @@ function $while(init, test, step, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
|
5725
7324
|
}
|
|
5726
7325
|
return exitJoin ? joinAbs(exitJoin, state) : state;
|
|
5727
7326
|
}
|
|
5728
|
-
function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
|
|
7327
|
+
function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
|
|
7328
|
+
const pack = opts?.pack;
|
|
7329
|
+
const unpack = opts?.unpack;
|
|
7330
|
+
let exitJoin;
|
|
7331
|
+
const snapExit = () => {
|
|
7332
|
+
if (!pack) return;
|
|
7333
|
+
const s = pack();
|
|
7334
|
+
exitJoin = exitJoin ? joinAbs(exitJoin, s) : s;
|
|
7335
|
+
};
|
|
7336
|
+
const applyExitJoin = () => {
|
|
7337
|
+
if (!exitJoin || !pack || !unpack) return;
|
|
7338
|
+
unpack(joinAbs(exitJoin, pack()));
|
|
7339
|
+
};
|
|
5729
7340
|
for (let i = 0; i < maxIters; i++) {
|
|
5730
7341
|
const t = test();
|
|
5731
|
-
if (isDefinitelyFalse(t))
|
|
5732
|
-
|
|
7342
|
+
if (isDefinitelyFalse(t)) {
|
|
7343
|
+
applyExitJoin();
|
|
7344
|
+
return;
|
|
7345
|
+
}
|
|
7346
|
+
if (!isDefinitelyTrue(t)) snapExit();
|
|
7347
|
+
try {
|
|
7348
|
+
body();
|
|
7349
|
+
} catch (e) {
|
|
7350
|
+
if (isNudoReturn(e) || isNudoThrow(e)) throw e;
|
|
7351
|
+
throw e;
|
|
7352
|
+
}
|
|
7353
|
+
}
|
|
7354
|
+
snapExit();
|
|
7355
|
+
applyExitJoin();
|
|
7356
|
+
}
|
|
7357
|
+
var NudoReturn = class extends Error {
|
|
7358
|
+
absValue;
|
|
7359
|
+
constructor(absValue) {
|
|
7360
|
+
super("nudo:return");
|
|
7361
|
+
this.name = "NudoReturn";
|
|
7362
|
+
this.absValue = absValue;
|
|
5733
7363
|
}
|
|
7364
|
+
};
|
|
7365
|
+
function $loopReturn(v2) {
|
|
7366
|
+
throw new NudoReturn(v2);
|
|
7367
|
+
}
|
|
7368
|
+
function isNudoReturn(e) {
|
|
7369
|
+
return e instanceof NudoReturn;
|
|
7370
|
+
}
|
|
7371
|
+
function $rethrowIfNudoReturn(e) {
|
|
7372
|
+
if (isNudoReturn(e)) throw e;
|
|
5734
7373
|
}
|
|
5735
7374
|
var NudoThrow = class extends Error {
|
|
5736
7375
|
absValue;
|
|
@@ -5746,11 +7385,35 @@ function $throw(v2) {
|
|
|
5746
7385
|
function isNudoThrow(e) {
|
|
5747
7386
|
return e instanceof NudoThrow;
|
|
5748
7387
|
}
|
|
7388
|
+
function $isForkExit(e) {
|
|
7389
|
+
return isNudoReturn(e) || isNudoThrow(e);
|
|
7390
|
+
}
|
|
5749
7391
|
function $catchVal(e) {
|
|
5750
7392
|
if (isNudoThrow(e)) return e.absValue;
|
|
5751
7393
|
if (e instanceof Error) {
|
|
7394
|
+
const name = e.name || "Error";
|
|
7395
|
+
const msgAbs = typeof e.message === "string" ? abs(
|
|
7396
|
+
{ k: "prim", type: "string" },
|
|
7397
|
+
{ op: "lit", value: e.message },
|
|
7398
|
+
pTrue,
|
|
7399
|
+
"exact"
|
|
7400
|
+
) : abs({ k: "prim", type: "string" }, void 0, void 0, "path");
|
|
5752
7401
|
return abs(
|
|
5753
|
-
{
|
|
7402
|
+
{
|
|
7403
|
+
k: "brand",
|
|
7404
|
+
name,
|
|
7405
|
+
shape: objOf({
|
|
7406
|
+
name: {
|
|
7407
|
+
value: abs(
|
|
7408
|
+
{ k: "prim", type: "string" },
|
|
7409
|
+
{ op: "lit", value: name },
|
|
7410
|
+
pTrue,
|
|
7411
|
+
"exact"
|
|
7412
|
+
)
|
|
7413
|
+
},
|
|
7414
|
+
message: { value: msgAbs }
|
|
7415
|
+
})
|
|
7416
|
+
},
|
|
5754
7417
|
void 0,
|
|
5755
7418
|
void 0,
|
|
5756
7419
|
"path"
|
|
@@ -5781,16 +7444,28 @@ function $asyncReturn(v2) {
|
|
|
5781
7444
|
if (v2.shape.k === "eff") return v2;
|
|
5782
7445
|
return wrapPromiseAbs(v2);
|
|
5783
7446
|
}
|
|
5784
|
-
var yieldStack = [];
|
|
5785
7447
|
function $gen(body) {
|
|
5786
7448
|
const ys = [];
|
|
7449
|
+
const marker = genPathSensitive;
|
|
7450
|
+
const prevOverride = genJoinOverride;
|
|
7451
|
+
genJoinOverride = null;
|
|
5787
7452
|
yieldStack.push(ys);
|
|
5788
7453
|
try {
|
|
5789
7454
|
body();
|
|
5790
7455
|
} finally {
|
|
5791
7456
|
yieldStack.pop();
|
|
5792
7457
|
}
|
|
5793
|
-
|
|
7458
|
+
if (genJoinOverride) {
|
|
7459
|
+
const joined = genJoinOverride;
|
|
7460
|
+
genJoinOverride = prevOverride;
|
|
7461
|
+
return { ...joined, conf: joined.conf === "exact" ? "path" : joined.conf };
|
|
7462
|
+
}
|
|
7463
|
+
genJoinOverride = prevOverride;
|
|
7464
|
+
const arr = $arr(ys);
|
|
7465
|
+
if (genPathSensitive > marker) {
|
|
7466
|
+
return { ...arr, conf: arr.conf === "exact" ? "path" : arr.conf };
|
|
7467
|
+
}
|
|
7468
|
+
return arr;
|
|
5794
7469
|
}
|
|
5795
7470
|
function $yield(v2) {
|
|
5796
7471
|
const top = yieldStack[yieldStack.length - 1];
|
|
@@ -5806,10 +7481,63 @@ function $switch(disc, cases, dflt) {
|
|
|
5806
7481
|
}
|
|
5807
7482
|
return dflt ? asAbsVal(dflt()) : undef();
|
|
5808
7483
|
}
|
|
5809
|
-
const
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
7484
|
+
const exits = loopExitsAls.getStore();
|
|
7485
|
+
beginCollectionFork();
|
|
7486
|
+
const armOverlays2 = [];
|
|
7487
|
+
const armYsList = [];
|
|
7488
|
+
const runArm = (fn) => {
|
|
7489
|
+
pushCollectionArm();
|
|
7490
|
+
try {
|
|
7491
|
+
const r = withIsolatedYields(() => runForkArm(fn, exits));
|
|
7492
|
+
armYsList.push(r.ys);
|
|
7493
|
+
return r.v;
|
|
7494
|
+
} finally {
|
|
7495
|
+
armOverlays2.push(popCollectionArm());
|
|
7496
|
+
}
|
|
7497
|
+
};
|
|
7498
|
+
const results = [];
|
|
7499
|
+
try {
|
|
7500
|
+
const seenRuns = /* @__PURE__ */ new Set();
|
|
7501
|
+
for (const c of cases) {
|
|
7502
|
+
if (seenRuns.has(c.run)) continue;
|
|
7503
|
+
seenRuns.add(c.run);
|
|
7504
|
+
results.push(runArm(c.run));
|
|
7505
|
+
}
|
|
7506
|
+
if (dflt) {
|
|
7507
|
+
if (!seenRuns.has(dflt)) results.push(runArm(dflt));
|
|
7508
|
+
} else {
|
|
7509
|
+
pushCollectionArm();
|
|
7510
|
+
try {
|
|
7511
|
+
results.push({ kind: "val", v: undef() });
|
|
7512
|
+
armYsList.push(null);
|
|
7513
|
+
} finally {
|
|
7514
|
+
armOverlays2.push(popCollectionArm());
|
|
7515
|
+
}
|
|
7516
|
+
}
|
|
7517
|
+
} finally {
|
|
7518
|
+
endCollectionFork(armOverlays2);
|
|
7519
|
+
if (yieldStack.length > 0) mergeArmYields(armYsList);
|
|
7520
|
+
}
|
|
7521
|
+
if (results.length === 0) return undef();
|
|
7522
|
+
const throws = results.filter((r) => r.kind === "throw");
|
|
7523
|
+
const nonThrow = results.filter((r) => r.kind !== "throw");
|
|
7524
|
+
if (nonThrow.length === 0) {
|
|
7525
|
+
throw new NudoThrow(throws.map((t) => t.v).reduce((x, y) => joinAbs(x, y)));
|
|
7526
|
+
}
|
|
7527
|
+
const allRet = nonThrow.every((r) => r.kind === "ret");
|
|
7528
|
+
if (allRet) {
|
|
7529
|
+
throw new NudoReturn(nonThrow.map((r) => r.v).reduce((a, b) => joinAbs(a, b)));
|
|
7530
|
+
}
|
|
7531
|
+
const valParts = nonThrow.filter((r) => r.kind === "val").map((r) => r.v);
|
|
7532
|
+
if (valParts.length === 0) return undef();
|
|
7533
|
+
return valParts.reduce((a, b) => joinAbs(a, b));
|
|
7534
|
+
}
|
|
7535
|
+
function $nullishTest(v2) {
|
|
7536
|
+
if (definitelyNotNullishShape(v2.shape)) return boolLit(false);
|
|
7537
|
+
if (isNullishLitAbs(v2)) return boolLit(true);
|
|
7538
|
+
const t = v2.term;
|
|
7539
|
+
if (t?.op === "lit" && t.value !== null && t.value !== void 0) return boolLit(false);
|
|
7540
|
+
return bool();
|
|
5813
7541
|
}
|
|
5814
7542
|
|
|
5815
7543
|
// src/algebra/exec/transpile.ts
|
|
@@ -5824,6 +7552,7 @@ function matchAsOverride(stmt, opts) {
|
|
|
5824
7552
|
function normWs(s) {
|
|
5825
7553
|
return s.replace(/\s+/g, "");
|
|
5826
7554
|
}
|
|
7555
|
+
var switchBodySeq = 0;
|
|
5827
7556
|
function matchReplacement(node, opts) {
|
|
5828
7557
|
if (!opts.source || !opts.replacements?.length) return null;
|
|
5829
7558
|
if (node.start == null || node.end == null || !node.loc) return null;
|
|
@@ -5848,7 +7577,9 @@ var BIN_OPS = {
|
|
|
5848
7577
|
">": "$gt",
|
|
5849
7578
|
">=": "$ge",
|
|
5850
7579
|
"===": "$eq",
|
|
5851
|
-
"!==": "$ne"
|
|
7580
|
+
"!==": "$ne",
|
|
7581
|
+
"==": "$eqLoose",
|
|
7582
|
+
"!=": "$neLoose"
|
|
5852
7583
|
};
|
|
5853
7584
|
var COMPOUND_OPS = {
|
|
5854
7585
|
"+=": "$add",
|
|
@@ -5921,6 +7652,65 @@ function setPathSrc(p, valSrc) {
|
|
|
5921
7652
|
function readPrefix(p, j) {
|
|
5922
7653
|
return p.layers.slice(0, j + 1).reduce((acc, l) => l.get(acc), p.rootSrc);
|
|
5923
7654
|
}
|
|
7655
|
+
var ARR_MUTATOR_NAMES = /* @__PURE__ */ new Set([
|
|
7656
|
+
"push",
|
|
7657
|
+
"unshift",
|
|
7658
|
+
"splice",
|
|
7659
|
+
"pop",
|
|
7660
|
+
"shift",
|
|
7661
|
+
"reverse",
|
|
7662
|
+
"sort"
|
|
7663
|
+
]);
|
|
7664
|
+
function emitArrMutatorRebinds(expr, opts, pad) {
|
|
7665
|
+
const lines = [];
|
|
7666
|
+
if (!expr || typeof expr !== "object") return lines;
|
|
7667
|
+
const visit = (n) => {
|
|
7668
|
+
if (!n || typeof n !== "object") return;
|
|
7669
|
+
const node = n;
|
|
7670
|
+
if (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "ObjectMethod" || node.type === "ClassMethod") {
|
|
7671
|
+
return;
|
|
7672
|
+
}
|
|
7673
|
+
if (node.type === "LogicalExpression" || node.type === "ConditionalExpression") {
|
|
7674
|
+
return;
|
|
7675
|
+
}
|
|
7676
|
+
if (node.type === "AssignmentExpression" && (node.operator === "||=" || node.operator === "&&=" || node.operator === "??=")) {
|
|
7677
|
+
visit(node.left);
|
|
7678
|
+
return;
|
|
7679
|
+
}
|
|
7680
|
+
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)) {
|
|
7681
|
+
const methodName = node.callee.property.name;
|
|
7682
|
+
const argSrcs = (node.arguments ?? []).map(
|
|
7683
|
+
(a) => a.type === "SpreadElement" ? "$lit(undefined)" : isExpression(a) ? transpileExpression(a, opts) : "$lit(undefined)"
|
|
7684
|
+
).join(", ");
|
|
7685
|
+
const objNode = node.callee.object;
|
|
7686
|
+
if (objNode.type === "Identifier") {
|
|
7687
|
+
const name = objNode.name;
|
|
7688
|
+
lines.push(
|
|
7689
|
+
`${pad}${name} = $arrMutContainer(${name}, ${JSON.stringify(methodName)}, [${argSrcs}]);`
|
|
7690
|
+
);
|
|
7691
|
+
} else if (objNode.type === "MemberExpression" || objNode.type === "ThisExpression") {
|
|
7692
|
+
const path = objNode.type === "MemberExpression" ? memberPathOf(
|
|
7693
|
+
objNode,
|
|
7694
|
+
opts
|
|
7695
|
+
) : null;
|
|
7696
|
+
if (path) {
|
|
7697
|
+
const recvSrc = readPathSrc(path);
|
|
7698
|
+
const mutSrc = `$arrMutContainer(${recvSrc}, ${JSON.stringify(methodName)}, [${argSrcs}])`;
|
|
7699
|
+
lines.push(`${pad}${path.rootSrc} = ${setPathSrc(path, mutSrc)};`);
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
}
|
|
7703
|
+
for (const key of Object.keys(node)) {
|
|
7704
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7705
|
+
if (key === "callee" || key === "property") continue;
|
|
7706
|
+
const child = node[key];
|
|
7707
|
+
if (Array.isArray(child)) child.forEach(visit);
|
|
7708
|
+
else if (child && typeof child === "object") visit(child);
|
|
7709
|
+
}
|
|
7710
|
+
};
|
|
7711
|
+
visit(expr);
|
|
7712
|
+
return lines;
|
|
7713
|
+
}
|
|
5924
7714
|
function transpileSource(source, opts = {}) {
|
|
5925
7715
|
const file = parseSource(source);
|
|
5926
7716
|
return transpileFile(file, { ...opts, source: opts.source ?? source });
|
|
@@ -5929,7 +7719,7 @@ function transpileFile(file, opts = {}) {
|
|
|
5929
7719
|
const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
|
|
5930
7720
|
const lines = [
|
|
5931
7721
|
`// 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)};`,
|
|
7722
|
+
`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
7723
|
``
|
|
5934
7724
|
];
|
|
5935
7725
|
for (const stmt of file.program.body) {
|
|
@@ -5940,12 +7730,226 @@ function transpileFile(file, opts = {}) {
|
|
|
5940
7730
|
function indent(n) {
|
|
5941
7731
|
return " ".repeat(n);
|
|
5942
7732
|
}
|
|
7733
|
+
function collectAssignedIds(node, acc) {
|
|
7734
|
+
if (!node || typeof node !== "object") return;
|
|
7735
|
+
const n = node;
|
|
7736
|
+
if (n.type === "AssignmentExpression" && n.left?.type === "Identifier" && n.left.name) {
|
|
7737
|
+
acc.add(n.left.name);
|
|
7738
|
+
}
|
|
7739
|
+
if (n.type === "AssignmentExpression" && n.left?.type === "MemberExpression") {
|
|
7740
|
+
let cur = n.left;
|
|
7741
|
+
while (cur?.type === "MemberExpression") cur = cur.object;
|
|
7742
|
+
if (cur?.type === "Identifier" && cur.name) acc.add(cur.name);
|
|
7743
|
+
}
|
|
7744
|
+
if (n.type === "UpdateExpression" && n.argument?.type === "Identifier" && n.argument.name) {
|
|
7745
|
+
acc.add(n.argument.name);
|
|
7746
|
+
}
|
|
7747
|
+
for (const key of Object.keys(n)) {
|
|
7748
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7749
|
+
const child = n[key];
|
|
7750
|
+
if (Array.isArray(child)) child.forEach((c) => collectAssignedIds(c, acc));
|
|
7751
|
+
else if (child && typeof child === "object") collectAssignedIds(child, acc);
|
|
7752
|
+
}
|
|
7753
|
+
}
|
|
7754
|
+
var FUNCTION_SCOPE_TYPES = /* @__PURE__ */ new Set([
|
|
7755
|
+
"FunctionDeclaration",
|
|
7756
|
+
"FunctionExpression",
|
|
7757
|
+
"ArrowFunctionExpression",
|
|
7758
|
+
"ObjectMethod",
|
|
7759
|
+
"ClassMethod",
|
|
7760
|
+
"ClassPrivateMethod"
|
|
7761
|
+
]);
|
|
7762
|
+
var BINDING_SCOPE_TYPES = /* @__PURE__ */ new Set([
|
|
7763
|
+
...FUNCTION_SCOPE_TYPES,
|
|
7764
|
+
"CatchClause",
|
|
7765
|
+
"ForOfStatement",
|
|
7766
|
+
"ForInStatement"
|
|
7767
|
+
]);
|
|
7768
|
+
function collectPatternNames(id, acc) {
|
|
7769
|
+
if (!id || typeof id !== "object") return;
|
|
7770
|
+
const n = id;
|
|
7771
|
+
if (n.type === "Identifier" && n.name) acc.add(n.name);
|
|
7772
|
+
else if (n.type === "RestElement") collectPatternNames(n.argument, acc);
|
|
7773
|
+
else if (n.type === "AssignmentPattern") collectPatternNames(n.left, acc);
|
|
7774
|
+
else if (n.type === "ObjectPattern") {
|
|
7775
|
+
for (const p of n.properties ?? []) {
|
|
7776
|
+
const prop = p;
|
|
7777
|
+
if (prop?.type === "RestElement") collectPatternNames(prop.argument, acc);
|
|
7778
|
+
else collectPatternNames(prop?.value, acc);
|
|
7779
|
+
}
|
|
7780
|
+
} else if (n.type === "ArrayPattern") {
|
|
7781
|
+
for (const el of n.elements ?? []) collectPatternNames(el, acc);
|
|
7782
|
+
}
|
|
7783
|
+
}
|
|
7784
|
+
var freeAssignedCache = /* @__PURE__ */ new WeakMap();
|
|
7785
|
+
var mutatorRecvCache = /* @__PURE__ */ new WeakMap();
|
|
7786
|
+
function collectFreeAssignedNames(...nodes) {
|
|
7787
|
+
const cachedParts = [];
|
|
7788
|
+
const pending = [];
|
|
7789
|
+
for (const node of nodes) {
|
|
7790
|
+
if (node && typeof node === "object") {
|
|
7791
|
+
const hit = freeAssignedCache.get(node);
|
|
7792
|
+
if (hit) {
|
|
7793
|
+
cachedParts.push(hit);
|
|
7794
|
+
continue;
|
|
7795
|
+
}
|
|
7796
|
+
pending.push(node);
|
|
7797
|
+
}
|
|
7798
|
+
}
|
|
7799
|
+
if (pending.length === 0) {
|
|
7800
|
+
const merged2 = /* @__PURE__ */ new Set();
|
|
7801
|
+
for (const p of cachedParts) for (const n of p) merged2.add(n);
|
|
7802
|
+
return [...merged2];
|
|
7803
|
+
}
|
|
7804
|
+
const free = /* @__PURE__ */ new Set();
|
|
7805
|
+
const markFree = (name, shadowed) => {
|
|
7806
|
+
if (name && name !== "undefined" && !shadowed.has(name)) free.add(name);
|
|
7807
|
+
};
|
|
7808
|
+
const walk = (node, shadowed) => {
|
|
7809
|
+
if (!node || typeof node !== "object") return;
|
|
7810
|
+
const n = node;
|
|
7811
|
+
let nextShadowed = shadowed;
|
|
7812
|
+
const pushShadow = (names) => {
|
|
7813
|
+
const add2 = [];
|
|
7814
|
+
for (const name of names) {
|
|
7815
|
+
if (name && !nextShadowed.has(name)) add2.push(name);
|
|
7816
|
+
}
|
|
7817
|
+
if (add2.length === 0) return;
|
|
7818
|
+
nextShadowed = new Set(nextShadowed);
|
|
7819
|
+
for (const name of add2) nextShadowed.add(name);
|
|
7820
|
+
};
|
|
7821
|
+
if (FUNCTION_SCOPE_TYPES.has(n.type)) {
|
|
7822
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7823
|
+
collectPatternNames(n.id, bound);
|
|
7824
|
+
for (const p of n.params ?? []) collectPatternNames(p, bound);
|
|
7825
|
+
pushShadow(bound);
|
|
7826
|
+
} else if (n.type === "CatchClause") {
|
|
7827
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7828
|
+
collectPatternNames(n.param, bound);
|
|
7829
|
+
pushShadow(bound);
|
|
7830
|
+
} else if (n.type === "ForOfStatement" || n.type === "ForInStatement") {
|
|
7831
|
+
const bound = /* @__PURE__ */ new Set();
|
|
7832
|
+
const left = n.left;
|
|
7833
|
+
if (left?.type === "VariableDeclaration") {
|
|
7834
|
+
for (const d of left.declarations ?? []) collectPatternNames(d.id, bound);
|
|
7835
|
+
} else {
|
|
7836
|
+
collectPatternNames(left, bound);
|
|
7837
|
+
}
|
|
7838
|
+
pushShadow(bound);
|
|
7839
|
+
}
|
|
7840
|
+
if (n.type === "AssignmentExpression") {
|
|
7841
|
+
const left = n.left;
|
|
7842
|
+
if (left?.type === "Identifier") markFree(left.name, nextShadowed);
|
|
7843
|
+
else if (left?.type === "MemberExpression") {
|
|
7844
|
+
let cur = left;
|
|
7845
|
+
while (cur?.type === "MemberExpression") {
|
|
7846
|
+
cur = cur.object;
|
|
7847
|
+
}
|
|
7848
|
+
if (cur?.type === "Identifier") markFree(cur.name, nextShadowed);
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
if (n.type === "UpdateExpression") {
|
|
7852
|
+
const arg = n.argument;
|
|
7853
|
+
if (arg?.type === "Identifier") markFree(arg.name, nextShadowed);
|
|
7854
|
+
}
|
|
7855
|
+
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)) {
|
|
7856
|
+
const obj2 = n.callee.object;
|
|
7857
|
+
if (obj2?.type === "Identifier") markFree(obj2.name, nextShadowed);
|
|
7858
|
+
else if (obj2?.type === "MemberExpression" || obj2?.type === "ThisExpression") {
|
|
7859
|
+
let cur = obj2;
|
|
7860
|
+
while (cur?.type === "MemberExpression") {
|
|
7861
|
+
cur = cur.object;
|
|
7862
|
+
}
|
|
7863
|
+
if (cur?.type === "Identifier") markFree(cur.name, nextShadowed);
|
|
7864
|
+
}
|
|
7865
|
+
}
|
|
7866
|
+
for (const key of Object.keys(n)) {
|
|
7867
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
7868
|
+
if (key === "callee" || key === "property" || key === "param" || key === "params") continue;
|
|
7869
|
+
const child = n[key];
|
|
7870
|
+
if (Array.isArray(child)) {
|
|
7871
|
+
if (n.type === "BlockStatement" || n.type === "Program" || n.type === "StaticBlock" || n.type === "SwitchCase") {
|
|
7872
|
+
let blockShadow = nextShadowed;
|
|
7873
|
+
for (const stmt of child) {
|
|
7874
|
+
walk(stmt, blockShadow);
|
|
7875
|
+
const stmtNode = stmt;
|
|
7876
|
+
if (!stmtNode) continue;
|
|
7877
|
+
const declared = /* @__PURE__ */ new Set();
|
|
7878
|
+
if (stmtNode.type === "VariableDeclaration") {
|
|
7879
|
+
for (const d of stmtNode.declarations ?? []) collectPatternNames(d.id, declared);
|
|
7880
|
+
} else if (stmtNode.type === "FunctionDeclaration" || stmtNode.type === "ClassDeclaration") {
|
|
7881
|
+
collectPatternNames(stmtNode.id, declared);
|
|
7882
|
+
}
|
|
7883
|
+
if (declared.size > 0) {
|
|
7884
|
+
if (blockShadow === nextShadowed) blockShadow = new Set(blockShadow);
|
|
7885
|
+
for (const name of declared) blockShadow.add(name);
|
|
7886
|
+
}
|
|
7887
|
+
}
|
|
7888
|
+
continue;
|
|
7889
|
+
}
|
|
7890
|
+
for (const item of child) walk(item, nextShadowed);
|
|
7891
|
+
} else if (child && typeof child === "object") {
|
|
7892
|
+
walk(child, nextShadowed);
|
|
7893
|
+
}
|
|
7894
|
+
}
|
|
7895
|
+
if (FUNCTION_SCOPE_TYPES.has(n.type) && n.body) {
|
|
7896
|
+
walk(n.body, nextShadowed);
|
|
7897
|
+
}
|
|
7898
|
+
};
|
|
7899
|
+
for (const node of pending) {
|
|
7900
|
+
walk(node, /* @__PURE__ */ new Set());
|
|
7901
|
+
}
|
|
7902
|
+
const computed = [...free];
|
|
7903
|
+
for (const node of pending) freeAssignedCache.set(node, computed);
|
|
7904
|
+
const merged = new Set(computed);
|
|
7905
|
+
for (const p of cachedParts) for (const n of p) merged.add(n);
|
|
7906
|
+
return [...merged];
|
|
7907
|
+
}
|
|
7908
|
+
function collectForkBindingNames(...nodes) {
|
|
7909
|
+
return collectFreeAssignedNames(...nodes);
|
|
7910
|
+
}
|
|
7911
|
+
function stmtCompletesControl(stmt) {
|
|
7912
|
+
if (!stmt) return false;
|
|
7913
|
+
switch (stmt.type) {
|
|
7914
|
+
case "BreakStatement":
|
|
7915
|
+
case "ReturnStatement":
|
|
7916
|
+
case "ThrowStatement":
|
|
7917
|
+
case "ContinueStatement":
|
|
7918
|
+
return true;
|
|
7919
|
+
case "BlockStatement":
|
|
7920
|
+
return stmtCompletesControl(stmt.body[stmt.body.length - 1]);
|
|
7921
|
+
case "IfStatement":
|
|
7922
|
+
return stmt.alternate != null && stmtCompletesControl(stmt.consequent) && stmtCompletesControl(stmt.alternate);
|
|
7923
|
+
default:
|
|
7924
|
+
return false;
|
|
7925
|
+
}
|
|
7926
|
+
}
|
|
5943
7927
|
function stmtReturns(stmt) {
|
|
5944
7928
|
if (stmt.type === "ReturnStatement" || stmt.type === "ThrowStatement") return true;
|
|
5945
7929
|
if (stmt.type === "BlockStatement") return stmt.body.some(stmtReturns);
|
|
5946
7930
|
if (stmt.type === "IfStatement") {
|
|
5947
7931
|
return stmtReturns(stmt.consequent) && stmt.alternate != null && stmtReturns(stmt.alternate);
|
|
5948
7932
|
}
|
|
7933
|
+
if (stmt.type === "SwitchStatement") {
|
|
7934
|
+
const arms = [];
|
|
7935
|
+
for (const c of stmt.cases) {
|
|
7936
|
+
const testIsDefault = c.test === null || c.test === void 0;
|
|
7937
|
+
const last = arms[arms.length - 1];
|
|
7938
|
+
if (last && !last.isDefault && last.stmts.length === 0 && !testIsDefault) {
|
|
7939
|
+
last.stmts = c.consequent;
|
|
7940
|
+
continue;
|
|
7941
|
+
}
|
|
7942
|
+
if (last && !last.isDefault && !testIsDefault && last.stmts.length > 0 && c.consequent.length === 0) {
|
|
7943
|
+
continue;
|
|
7944
|
+
}
|
|
7945
|
+
arms.push({ stmts: c.consequent, isDefault: testIsDefault });
|
|
7946
|
+
}
|
|
7947
|
+
const armOk = (a) => a.stmts.length > 0 && a.stmts.every(stmtReturns);
|
|
7948
|
+
const nonDefault = arms.filter((a) => !a.isDefault);
|
|
7949
|
+
const dflt = arms.find((a) => a.isDefault);
|
|
7950
|
+
if (dflt === void 0) return false;
|
|
7951
|
+
return nonDefault.length > 0 && nonDefault.every(armOk) && armOk(dflt);
|
|
7952
|
+
}
|
|
5949
7953
|
return false;
|
|
5950
7954
|
}
|
|
5951
7955
|
function transpileFnBodyStmts(stmts, depth, opts) {
|
|
@@ -5957,11 +7961,61 @@ function transpileFnBodyStmts(stmts, depth, opts) {
|
|
|
5957
7961
|
if (rest.length === 0) continue;
|
|
5958
7962
|
const head = stmts.slice(0, i).map((s) => transpileStatement(s, depth, opts)).join("\n");
|
|
5959
7963
|
const test = transpileExpression(stmt.test, opts);
|
|
5960
|
-
const
|
|
5961
|
-
|
|
5962
|
-
|
|
7964
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
7965
|
+
...collectForkBindingNames(stmt.consequent),
|
|
7966
|
+
...collectForkBindingNames(stmt.test),
|
|
7967
|
+
...rest.flatMap((r) => collectForkBindingNames(r))
|
|
7968
|
+
]);
|
|
7969
|
+
const names = [...recvSet];
|
|
7970
|
+
const pad = indent(depth);
|
|
7971
|
+
const padIn = indent(depth + 1);
|
|
7972
|
+
const wrapArm = (thunk, outPrefix) => {
|
|
7973
|
+
if (names.length === 0) return thunk;
|
|
7974
|
+
return [
|
|
7975
|
+
`() => {`,
|
|
7976
|
+
...names.map((n) => `${padIn}${n} = __fk0_${n};`),
|
|
7977
|
+
`${padIn}let __cont = true;`,
|
|
7978
|
+
`${padIn}try {`,
|
|
7979
|
+
`${padIn} return (${thunk})();`,
|
|
7980
|
+
`${padIn}} catch (e) {`,
|
|
7981
|
+
`${padIn} if ($isForkExit(e)) __cont = false;`,
|
|
7982
|
+
`${padIn} throw e;`,
|
|
7983
|
+
`${padIn}} finally {`,
|
|
7984
|
+
`${padIn} if (__cont) {`,
|
|
7985
|
+
...names.map((n) => `${padIn} __${outPrefix}${n} = ${n};`),
|
|
7986
|
+
...names.map((n) => `${padIn} __${outPrefix}set_${n} = true;`),
|
|
7987
|
+
`${padIn} }`,
|
|
7988
|
+
`${padIn}}`,
|
|
7989
|
+
`}`
|
|
7990
|
+
].join("\n");
|
|
7991
|
+
};
|
|
7992
|
+
const testRecvs = collectArrMutatorReceivers(stmt.test);
|
|
7993
|
+
const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, opts, pad) : [];
|
|
7994
|
+
const cons = wrapArm(transpileBlockAsThunk(stmt.consequent, depth, opts), "fk1_");
|
|
7995
|
+
const altBody = transpileFnBodyStmts(rest, depth + 1, { ...opts, inLoop: opts.inLoop });
|
|
7996
|
+
const altThunk = `() => {
|
|
5963
7997
|
${altBody}
|
|
5964
|
-
${
|
|
7998
|
+
${pad}}`;
|
|
7999
|
+
const alt = wrapArm(altThunk, "fk2_");
|
|
8000
|
+
const inCtrl = (opts.inLoop ?? 0) > 0 || (opts.inTry ?? 0) > 0;
|
|
8001
|
+
const applyJoin = names.length ? forkJoinBindings(names, pad).join("\n") : "";
|
|
8002
|
+
if (names.length === 0) {
|
|
8003
|
+
const promoted2 = [
|
|
8004
|
+
...testRebinds,
|
|
8005
|
+
inCtrl ? `${pad}$loopReturn($fork(${test}, ${cons}, ${alt}));` : `${pad}return $fork(${test}, ${cons}, ${alt});`
|
|
8006
|
+
].join("\n");
|
|
8007
|
+
return head ? `${head}
|
|
8008
|
+
${promoted2}` : promoted2;
|
|
8009
|
+
}
|
|
8010
|
+
const promoted = [
|
|
8011
|
+
`${pad}{`,
|
|
8012
|
+
...testRebinds,
|
|
8013
|
+
...forkBindingDecls(names, padIn),
|
|
8014
|
+
`${padIn}const __fkR = $fork(${test}, ${cons}, ${alt});`,
|
|
8015
|
+
applyJoin.split("\n").map((l) => l.replace(/^\s*/, padIn)).join("\n"),
|
|
8016
|
+
inCtrl ? `${padIn}$loopReturn(__fkR);` : `${padIn}return __fkR;`,
|
|
8017
|
+
`${pad}}`
|
|
8018
|
+
].join("\n");
|
|
5965
8019
|
return head ? `${head}
|
|
5966
8020
|
${promoted}` : promoted;
|
|
5967
8021
|
}
|
|
@@ -5973,11 +8027,18 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
5973
8027
|
return;
|
|
5974
8028
|
}
|
|
5975
8029
|
if (pattern.type === "ObjectPattern") {
|
|
8030
|
+
const namedKeys = [];
|
|
8031
|
+
let restName;
|
|
5976
8032
|
for (const prop of pattern.properties) {
|
|
8033
|
+
if (prop.type === "RestElement") {
|
|
8034
|
+
if (prop.argument.type === "Identifier") restName = prop.argument.name;
|
|
8035
|
+
continue;
|
|
8036
|
+
}
|
|
5977
8037
|
if (prop.type !== "ObjectProperty") continue;
|
|
5978
8038
|
if (prop.key.type !== "Identifier" && prop.key.type !== "StringLiteral") continue;
|
|
5979
8039
|
const key = prop.key.type === "Identifier" ? prop.key.name : String(prop.key.value);
|
|
5980
8040
|
const keyLit = JSON.stringify(key);
|
|
8041
|
+
namedKeys.push(key);
|
|
5981
8042
|
if (prop.value.type === "AssignmentPattern") {
|
|
5982
8043
|
const def = transpileExpression(prop.value.right, opts);
|
|
5983
8044
|
const left = prop.value.left;
|
|
@@ -6002,11 +8063,25 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
6002
8063
|
out.push(`${pad}${kw} ${prop.value.name} = $get(${fromSrc}, ${keyLit});`);
|
|
6003
8064
|
}
|
|
6004
8065
|
}
|
|
8066
|
+
if (restName) {
|
|
8067
|
+
out.push(
|
|
8068
|
+
`${pad}${kw} ${restName} = $objRest(${fromSrc}, ${JSON.stringify(namedKeys)});`
|
|
8069
|
+
);
|
|
8070
|
+
}
|
|
6005
8071
|
return;
|
|
6006
8072
|
}
|
|
6007
8073
|
if (pattern.type === "ArrayPattern") {
|
|
8074
|
+
let restName;
|
|
8075
|
+
let restAt = 0;
|
|
6008
8076
|
pattern.elements.forEach((el, i) => {
|
|
6009
8077
|
if (!el) return;
|
|
8078
|
+
if (el.type === "RestElement") {
|
|
8079
|
+
if (el.argument.type === "Identifier") {
|
|
8080
|
+
restName = el.argument.name;
|
|
8081
|
+
restAt = i;
|
|
8082
|
+
}
|
|
8083
|
+
return;
|
|
8084
|
+
}
|
|
6010
8085
|
if (el.type === "AssignmentPattern") {
|
|
6011
8086
|
const def = transpileExpression(el.right, opts);
|
|
6012
8087
|
const idx = `$idx(${fromSrc}, $lit(${i}))`;
|
|
@@ -6029,6 +8104,9 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
|
|
|
6029
8104
|
out.push(`${pad}${kw} ${el.name} = $idx(${fromSrc}, $lit(${i}));`);
|
|
6030
8105
|
}
|
|
6031
8106
|
});
|
|
8107
|
+
if (restName) {
|
|
8108
|
+
out.push(`${pad}${kw} ${restName} = $arrRest(${fromSrc}, ${restAt});`);
|
|
8109
|
+
}
|
|
6032
8110
|
}
|
|
6033
8111
|
}
|
|
6034
8112
|
function emitParamBinding(params, pad, opts) {
|
|
@@ -6069,6 +8147,122 @@ function emitParamBinding(params, pad, opts) {
|
|
|
6069
8147
|
});
|
|
6070
8148
|
return { sig, rest, prologue };
|
|
6071
8149
|
}
|
|
8150
|
+
function collectArrMutatorReceivers(node, acc = /* @__PURE__ */ new Set()) {
|
|
8151
|
+
if (!node || typeof node !== "object") return acc;
|
|
8152
|
+
const hit = mutatorRecvCache.get(node);
|
|
8153
|
+
if (hit) {
|
|
8154
|
+
for (const n of hit) acc.add(n);
|
|
8155
|
+
return acc;
|
|
8156
|
+
}
|
|
8157
|
+
const local = /* @__PURE__ */ new Set();
|
|
8158
|
+
collectArrMutatorReceiversUncached(node, local);
|
|
8159
|
+
mutatorRecvCache.set(node, local);
|
|
8160
|
+
for (const n of local) acc.add(n);
|
|
8161
|
+
return acc;
|
|
8162
|
+
}
|
|
8163
|
+
function collectArrMutatorReceiversUncached(node, acc = /* @__PURE__ */ new Set()) {
|
|
8164
|
+
if (!node || typeof node !== "object") return acc;
|
|
8165
|
+
const n = node;
|
|
8166
|
+
if (n.type === "FunctionExpression" || n.type === "ArrowFunctionExpression" || n.type === "ObjectMethod" || n.type === "ClassMethod" || n.type === "FunctionDeclaration") {
|
|
8167
|
+
return acc;
|
|
8168
|
+
}
|
|
8169
|
+
if (n.type === "CallExpression" && n.callee?.type === "MemberExpression") {
|
|
8170
|
+
const callee = n.callee;
|
|
8171
|
+
const propName = !callee.computed && callee.property?.type === "Identifier" ? callee.property.name : void 0;
|
|
8172
|
+
if (propName && ARR_MUTATOR_NAMES.has(propName)) {
|
|
8173
|
+
const obj2 = callee.object;
|
|
8174
|
+
if (obj2?.type === "Identifier") {
|
|
8175
|
+
acc.add(obj2.name);
|
|
8176
|
+
} else if (obj2?.type === "MemberExpression") {
|
|
8177
|
+
let cur = obj2;
|
|
8178
|
+
while (cur?.type === "MemberExpression") {
|
|
8179
|
+
cur = cur.object;
|
|
8180
|
+
}
|
|
8181
|
+
if (cur?.type === "Identifier") {
|
|
8182
|
+
acc.add(cur.name);
|
|
8183
|
+
}
|
|
8184
|
+
}
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
for (const key of Object.keys(n)) {
|
|
8188
|
+
if (key === "loc" || key === "start" || key === "end" || key === "range") continue;
|
|
8189
|
+
const child = n[key];
|
|
8190
|
+
if (Array.isArray(child)) child.forEach((c) => collectArrMutatorReceiversUncached(c, acc));
|
|
8191
|
+
else if (child && typeof child === "object") collectArrMutatorReceiversUncached(child, acc);
|
|
8192
|
+
}
|
|
8193
|
+
return acc;
|
|
8194
|
+
}
|
|
8195
|
+
function forkArmThunk(bodyLines, outPrefix, names) {
|
|
8196
|
+
return [
|
|
8197
|
+
`() => {`,
|
|
8198
|
+
...names.map((n) => ` ${n} = __fk0_${n};`),
|
|
8199
|
+
` let __cont = true;`,
|
|
8200
|
+
` try {`,
|
|
8201
|
+
...bodyLines.map((l) => ` ${l}`),
|
|
8202
|
+
` } catch (e) {`,
|
|
8203
|
+
` if ($isForkExit(e)) __cont = false;`,
|
|
8204
|
+
` throw e;`,
|
|
8205
|
+
` } finally {`,
|
|
8206
|
+
` if (__cont) {`,
|
|
8207
|
+
...names.map((n) => ` __${outPrefix}${n} = ${n};`),
|
|
8208
|
+
...names.map((n) => ` __${outPrefix}set_${n} = true;`),
|
|
8209
|
+
` }`,
|
|
8210
|
+
` }`,
|
|
8211
|
+
`}`
|
|
8212
|
+
].join("\n");
|
|
8213
|
+
}
|
|
8214
|
+
function forkBindingDecls(names, pad = "") {
|
|
8215
|
+
return names.flatMap((n) => [
|
|
8216
|
+
`${pad}const __fk0_${n} = ${n};`,
|
|
8217
|
+
`${pad}let __fk1_${n}; let __fk2_${n};`,
|
|
8218
|
+
`${pad}let __fk1_set_${n} = false; let __fk2_set_${n} = false;`
|
|
8219
|
+
]);
|
|
8220
|
+
}
|
|
8221
|
+
function forkJoinBindings(names, pad = "") {
|
|
8222
|
+
return names.map(
|
|
8223
|
+
(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}));`
|
|
8224
|
+
);
|
|
8225
|
+
}
|
|
8226
|
+
function transpileShortCircuitExpr(opts, parts) {
|
|
8227
|
+
const alwaysNames = new Set(collectForkBindingNames(...parts.alwaysNodes));
|
|
8228
|
+
const branchNames = new Set(alwaysNames);
|
|
8229
|
+
for (const n of parts.consNodes) for (const id of collectForkBindingNames(n)) branchNames.add(id);
|
|
8230
|
+
for (const n of parts.altNodes) for (const id of collectForkBindingNames(n)) branchNames.add(id);
|
|
8231
|
+
const names = [...branchNames];
|
|
8232
|
+
const alwaysRebinds = [];
|
|
8233
|
+
for (const n of parts.alwaysNodes) {
|
|
8234
|
+
alwaysRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8235
|
+
}
|
|
8236
|
+
const consRebinds = [];
|
|
8237
|
+
for (const n of parts.consNodes) {
|
|
8238
|
+
if (parts.alwaysNodes.includes(n)) continue;
|
|
8239
|
+
consRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8240
|
+
}
|
|
8241
|
+
const altRebinds = [];
|
|
8242
|
+
for (const n of parts.altNodes) {
|
|
8243
|
+
if (parts.alwaysNodes.includes(n)) continue;
|
|
8244
|
+
altRebinds.push(...emitArrMutatorRebinds(n, opts, ""));
|
|
8245
|
+
}
|
|
8246
|
+
if (alwaysNames.size === 0 && branchNames.size === 0) {
|
|
8247
|
+
const forkTest2 = parts.testSrc ?? parts.alwaysSrc;
|
|
8248
|
+
const consExpr = parts.consSrc === "__test" ? parts.alwaysSrc : parts.consSrc;
|
|
8249
|
+
const altExpr = parts.altSrc === "__test" ? parts.alwaysSrc : parts.altSrc;
|
|
8250
|
+
return `$fork(${forkTest2}, () => ${consExpr}, () => ${altExpr})`;
|
|
8251
|
+
}
|
|
8252
|
+
const consLines = parts.consSrc === "__test" ? [`return __test;`] : consRebinds.length === 0 ? [`return (${parts.consSrc});`] : [`const __v = (${parts.consSrc});`, ...consRebinds, `return __v;`];
|
|
8253
|
+
const altLines = parts.altSrc === "__test" ? [`return __test;`] : altRebinds.length === 0 ? [`return (${parts.altSrc});`] : [`const __v = (${parts.altSrc});`, ...altRebinds, `return __v;`];
|
|
8254
|
+
const forkTest = parts.testSrc ?? "__test";
|
|
8255
|
+
return [
|
|
8256
|
+
`(() => {`,
|
|
8257
|
+
` const __test = (${parts.alwaysSrc});`,
|
|
8258
|
+
...alwaysRebinds.map((l) => ` ${l}`),
|
|
8259
|
+
...names.length ? forkBindingDecls(names, " ") : [],
|
|
8260
|
+
` const __r = $fork(${forkTest}, ${forkArmThunk(consLines, "fk1_", names)}, ${forkArmThunk(altLines, "fk2_", names)});`,
|
|
8261
|
+
...forkJoinBindings(names, " "),
|
|
8262
|
+
` return __r;`,
|
|
8263
|
+
`})()`
|
|
8264
|
+
].join("\n");
|
|
8265
|
+
}
|
|
6072
8266
|
function transpileStatement(stmt, depth, opts) {
|
|
6073
8267
|
const pad = indent(depth);
|
|
6074
8268
|
switch (stmt.type) {
|
|
@@ -6106,20 +8300,22 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6106
8300
|
}
|
|
6107
8301
|
case "FunctionDeclaration": {
|
|
6108
8302
|
if (!stmt.id) return `${pad}// <anonymous fn skipped>`;
|
|
8303
|
+
const exportKw = depth === 0 ? "export " : "";
|
|
8304
|
+
const fnOpts = { ...opts, inLoop: 0 };
|
|
6109
8305
|
const { sig, rest, prologue } = emitParamBinding(
|
|
6110
8306
|
stmt.params,
|
|
6111
8307
|
indent(depth + 2),
|
|
6112
|
-
|
|
8308
|
+
fnOpts
|
|
6113
8309
|
);
|
|
6114
8310
|
const named = sig;
|
|
6115
8311
|
const paramsSig = rest ? [...named, `...${rest}`] : named;
|
|
6116
8312
|
const params = paramsSig.join(", ");
|
|
6117
|
-
const bodyStmts = stmt.body.type === "BlockStatement" ? [...prologue, transpileFnBodyStmts(stmt.body.body, depth + 2,
|
|
8313
|
+
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
8314
|
const restBind = rest ? `${indent(depth + 1)}const ${rest} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
|
|
6119
8315
|
` : "";
|
|
6120
8316
|
if (stmt.generator) {
|
|
6121
8317
|
return [
|
|
6122
|
-
`${pad}
|
|
8318
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6123
8319
|
restBind,
|
|
6124
8320
|
`${indent(depth + 1)}return $gen(() => {`,
|
|
6125
8321
|
bodyStmts,
|
|
@@ -6129,7 +8325,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6129
8325
|
}
|
|
6130
8326
|
if (stmt.async) {
|
|
6131
8327
|
return [
|
|
6132
|
-
`${pad}
|
|
8328
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6133
8329
|
restBind,
|
|
6134
8330
|
`${indent(depth + 1)}return $async(() => {`,
|
|
6135
8331
|
bodyStmts,
|
|
@@ -6138,7 +8334,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6138
8334
|
].join("\n");
|
|
6139
8335
|
}
|
|
6140
8336
|
return [
|
|
6141
|
-
`${pad}
|
|
8337
|
+
`${pad}${exportKw}function ${stmt.id.name}(${named.join(", ")}) {`,
|
|
6142
8338
|
restBind,
|
|
6143
8339
|
bodyStmts,
|
|
6144
8340
|
`${pad}}`
|
|
@@ -6146,16 +8342,73 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6146
8342
|
}
|
|
6147
8343
|
case "ReturnStatement": {
|
|
6148
8344
|
const asVar = matchAsOverride(stmt, opts);
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
8345
|
+
const prefix = (opts.inLoop ?? 0) > 0 ? "$loopReturn" : "return";
|
|
8346
|
+
const markExpr = opts.tryMarkName ?? "$tryCurrentMark()";
|
|
8347
|
+
const emitRet = (src, mutNodes) => {
|
|
8348
|
+
const retRebinds = mutNodes ? emitArrMutatorRebinds(mutNodes, opts, pad) : [];
|
|
8349
|
+
if ((opts.inTry ?? 0) > 0) {
|
|
8350
|
+
return [
|
|
8351
|
+
`${pad}const __nudoRet = ${src};`,
|
|
8352
|
+
...retRebinds,
|
|
8353
|
+
`${pad}{`,
|
|
8354
|
+
`${indent(depth + 1)}const __xs = $tryTakeSince(${markExpr});`,
|
|
8355
|
+
`${indent(depth + 1)}if (__xs.length) {`,
|
|
8356
|
+
`${indent(depth + 2)}$pushLoopExit(__nudoRet);`,
|
|
8357
|
+
`${indent(depth + 2)}$throw(__xs.reduce((a, b) => $join(a, b)));`,
|
|
8358
|
+
`${indent(depth + 1)}}`,
|
|
8359
|
+
`${pad}}`,
|
|
8360
|
+
`${pad}${prefix}(__nudoRet);`
|
|
8361
|
+
].join("\n");
|
|
8362
|
+
}
|
|
8363
|
+
if (retRebinds.length === 0) return `${pad}${prefix}(${src});`;
|
|
8364
|
+
return [
|
|
8365
|
+
`${pad}let __mutRet = ${src};`,
|
|
8366
|
+
...retRebinds,
|
|
8367
|
+
`${pad}${prefix}(__mutRet);`
|
|
8368
|
+
].join("\n");
|
|
8369
|
+
};
|
|
8370
|
+
if (asVar) return emitRet(asVar);
|
|
8371
|
+
if (!stmt.argument) return emitRet(`$lit(undefined)`);
|
|
8372
|
+
const retSrc = transpileExpression(stmt.argument, opts);
|
|
8373
|
+
return emitRet(retSrc, stmt.argument);
|
|
6152
8374
|
}
|
|
6153
8375
|
case "ThrowStatement": {
|
|
6154
8376
|
const arg = stmt.argument ? transpileExpression(stmt.argument, opts) : "$lit(undefined)";
|
|
6155
8377
|
return `${pad}$throw(${arg});`;
|
|
6156
8378
|
}
|
|
6157
|
-
case "ExpressionStatement":
|
|
8379
|
+
case "ExpressionStatement": {
|
|
8380
|
+
const expr = stmt.expression;
|
|
8381
|
+
const exprRebinds = emitArrMutatorRebinds(expr, opts, pad);
|
|
8382
|
+
if (expr.type === "CallExpression" && expr.callee.type === "MemberExpression" && !expr.callee.computed && expr.callee.property.type === "Identifier") {
|
|
8383
|
+
const methodName = expr.callee.property.name;
|
|
8384
|
+
if (["push", "unshift", "splice", "pop", "shift", "reverse", "sort"].includes(methodName)) {
|
|
8385
|
+
const argSrcs = expr.arguments.map(
|
|
8386
|
+
(a) => a.type === "SpreadElement" ? "$lit(undefined)" : transpileExpression(a, opts)
|
|
8387
|
+
).join(", ");
|
|
8388
|
+
const objNode = expr.callee.object;
|
|
8389
|
+
if (objNode.type === "Identifier") {
|
|
8390
|
+
const name = objNode.name;
|
|
8391
|
+
return `${pad}${name} = $arrMutContainer(${name}, ${JSON.stringify(methodName)}, [${argSrcs}]);`;
|
|
8392
|
+
}
|
|
8393
|
+
if (objNode.type === "MemberExpression" || objNode.type === "ThisExpression") {
|
|
8394
|
+
const path = objNode.type === "MemberExpression" ? memberPathOf(objNode, opts) : null;
|
|
8395
|
+
if (path) {
|
|
8396
|
+
const recvSrc = readPathSrc(path);
|
|
8397
|
+
const mutSrc = `$arrMutContainer(${recvSrc}, ${JSON.stringify(methodName)}, [${argSrcs}])`;
|
|
8398
|
+
return `${pad}${path.rootSrc} = ${setPathSrc(path, mutSrc)};`;
|
|
8399
|
+
}
|
|
8400
|
+
return `${pad}${transpileExpression(stmt.expression, opts)};`;
|
|
8401
|
+
}
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
if (exprRebinds.length > 0) {
|
|
8405
|
+
return [
|
|
8406
|
+
`${pad}${transpileExpression(expr, opts)};`,
|
|
8407
|
+
...exprRebinds
|
|
8408
|
+
].join("\n");
|
|
8409
|
+
}
|
|
6158
8410
|
return `${pad}${transpileExpression(stmt.expression, opts)};`;
|
|
8411
|
+
}
|
|
6159
8412
|
case "VariableDeclaration": {
|
|
6160
8413
|
const kw = "let";
|
|
6161
8414
|
const asVar = matchAsOverride(stmt, opts);
|
|
@@ -6165,6 +8418,9 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6165
8418
|
if (d.id.type === "Identifier") {
|
|
6166
8419
|
const init = asVar ? asVar : d.init ? transpileExpression(d.init, opts) : "$lit(undefined)";
|
|
6167
8420
|
lines.push(`${pad}${kw} ${d.id.name} = ${init};`);
|
|
8421
|
+
if (d.init && !asVar) {
|
|
8422
|
+
lines.push(...emitArrMutatorRebinds(d.init, opts, pad));
|
|
8423
|
+
}
|
|
6168
8424
|
continue;
|
|
6169
8425
|
}
|
|
6170
8426
|
if (!d.init) {
|
|
@@ -6174,18 +8430,74 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6174
8430
|
const initSrc = transpileExpression(d.init, opts);
|
|
6175
8431
|
const tmp = `_d${tmpSeq++}_${stmt.loc?.start.line ?? 0}`;
|
|
6176
8432
|
lines.push(`${pad}const ${tmp} = ${initSrc};`);
|
|
8433
|
+
lines.push(...emitArrMutatorRebinds(d.init, opts, pad));
|
|
6177
8434
|
emitDestructure(d.id, tmp, kw, pad, opts, lines, { n: 0 });
|
|
6178
8435
|
}
|
|
6179
8436
|
return lines.join("\n");
|
|
6180
8437
|
}
|
|
6181
8438
|
case "IfStatement": {
|
|
6182
8439
|
const test = transpileExpression(stmt.test, opts);
|
|
6183
|
-
const
|
|
6184
|
-
|
|
8440
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
8441
|
+
...collectForkBindingNames(stmt.consequent),
|
|
8442
|
+
...collectForkBindingNames(stmt.alternate)
|
|
8443
|
+
]);
|
|
8444
|
+
const testRecvs = collectArrMutatorReceivers(stmt.test);
|
|
8445
|
+
const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, opts, pad) : [];
|
|
8446
|
+
const names = [...recvSet];
|
|
8447
|
+
const padIn = indent(depth + 1);
|
|
8448
|
+
const padDecl = names.length > 0 ? padIn : pad;
|
|
8449
|
+
const wrapArm = (thunk, outPrefix) => {
|
|
8450
|
+
if (names.length === 0) return thunk;
|
|
8451
|
+
return [
|
|
8452
|
+
`() => {`,
|
|
8453
|
+
...names.map((n) => `${padIn}${n} = __fk0_${n};`),
|
|
8454
|
+
`${padIn}let __cont = true;`,
|
|
8455
|
+
`${padIn}try {`,
|
|
8456
|
+
`${padIn} return (${thunk})();`,
|
|
8457
|
+
`${padIn}} catch (e) {`,
|
|
8458
|
+
`${padIn} if ($isForkExit(e)) __cont = false;`,
|
|
8459
|
+
`${padIn} throw e;`,
|
|
8460
|
+
`${padIn}} finally {`,
|
|
8461
|
+
`${padIn} if (__cont) {`,
|
|
8462
|
+
...names.map((n) => `${padIn} __${outPrefix}${n} = ${n};`),
|
|
8463
|
+
...names.map((n) => `${padIn} __${outPrefix}set_${n} = true;`),
|
|
8464
|
+
`${padIn} }`,
|
|
8465
|
+
`${padIn}}`,
|
|
8466
|
+
`}`
|
|
8467
|
+
].join("\n");
|
|
8468
|
+
};
|
|
8469
|
+
const consRaw = transpileBlockAsThunk(stmt.consequent, depth, opts);
|
|
8470
|
+
const altRaw = stmt.alternate ? transpileBlockAsThunk(stmt.alternate, depth, opts) : "undefined";
|
|
8471
|
+
const cons = wrapArm(consRaw, "fk1_");
|
|
8472
|
+
const alt = names.length ? wrapArm(altRaw === "undefined" ? "() => $lit(undefined)" : altRaw, "fk2_") : altRaw;
|
|
8473
|
+
const joinLines = names.length ? [...testRebinds, ...forkBindingDecls(names, padDecl)] : testRebinds;
|
|
8474
|
+
const applyJoin = names.length ? forkJoinBindings(names, padDecl).join("\n") : "";
|
|
8475
|
+
const inCtrl = (opts.inLoop ?? 0) > 0;
|
|
8476
|
+
const openBlock = names.length > 0 ? `${pad}{` : null;
|
|
8477
|
+
const closeBlock = names.length > 0 ? `${pad}}` : null;
|
|
6185
8478
|
if (stmtReturns(stmt.consequent) && stmt.alternate !== void 0 && stmt.alternate !== null && stmtReturns(stmt.alternate)) {
|
|
6186
|
-
|
|
8479
|
+
if (names.length === 0) {
|
|
8480
|
+
return [
|
|
8481
|
+
...joinLines,
|
|
8482
|
+
inCtrl ? `${pad}$loopReturn($fork(${test}, ${cons}, ${alt}));` : `${pad}return $fork(${test}, ${cons}, ${alt});`
|
|
8483
|
+
].join("\n");
|
|
8484
|
+
}
|
|
8485
|
+
return [
|
|
8486
|
+
openBlock,
|
|
8487
|
+
...joinLines,
|
|
8488
|
+
`${padDecl}const __fkR = $fork(${test}, ${cons}, ${alt});`,
|
|
8489
|
+
applyJoin,
|
|
8490
|
+
inCtrl ? `${padDecl}$loopReturn(__fkR);` : `${padDecl}return __fkR;`,
|
|
8491
|
+
closeBlock
|
|
8492
|
+
].join("\n");
|
|
6187
8493
|
}
|
|
6188
|
-
return
|
|
8494
|
+
return [
|
|
8495
|
+
openBlock,
|
|
8496
|
+
...joinLines,
|
|
8497
|
+
`${padDecl}$fork(${test}, ${cons}, ${alt});`,
|
|
8498
|
+
applyJoin,
|
|
8499
|
+
closeBlock
|
|
8500
|
+
].filter((l) => l !== null && l !== "").join("\n");
|
|
6189
8501
|
}
|
|
6190
8502
|
case "ForStatement": {
|
|
6191
8503
|
const initName = extractForInitName(stmt.init);
|
|
@@ -6193,8 +8505,21 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6193
8505
|
const initExpr = stmt.init && stmt.init.type === "VariableDeclaration" && stmt.init.declarations[0]?.init ? transpileExpression(stmt.init.declarations[0].init, opts) : "$lit(undefined)";
|
|
6194
8506
|
const testSrc = stmt.test ? transpileExpression(stmt.test, opts) : "$lit(true)";
|
|
6195
8507
|
const updateSrc = stmt.update ? transpileExpression(stmt.update, opts) : `$lit(undefined)`;
|
|
6196
|
-
const
|
|
8508
|
+
const forBodyOpts = {
|
|
8509
|
+
...opts,
|
|
8510
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8511
|
+
};
|
|
8512
|
+
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
8513
|
const max = opts.maxLoopIters ?? 8;
|
|
8514
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8515
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8516
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8517
|
+
collectAssignedIds(stmt.update, assigned);
|
|
8518
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8519
|
+
const names = [...assigned].filter((n) => n !== initName && n !== "undefined");
|
|
8520
|
+
const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8521
|
+
const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
8522
|
+
const optsSrc = packSrc && unpackSrc ? `, { pack: () => ${packSrc}, unpack: ${unpackSrc} }` : "";
|
|
6198
8523
|
return [
|
|
6199
8524
|
`${pad}// for \u2192 $for (bounded unroll, max=${max})`,
|
|
6200
8525
|
`${pad}$for(`,
|
|
@@ -6205,7 +8530,7 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6205
8530
|
bodyStmts,
|
|
6206
8531
|
`${indent(depth + 1)} return ${initName};`,
|
|
6207
8532
|
`${indent(depth + 1)}},`,
|
|
6208
|
-
`${indent(depth + 1)}${max}`,
|
|
8533
|
+
`${indent(depth + 1)}${max}${optsSrc}`,
|
|
6209
8534
|
`${pad});`
|
|
6210
8535
|
].join("\n");
|
|
6211
8536
|
}
|
|
@@ -6213,58 +8538,172 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
6213
8538
|
return transpileFnBodyStmts(stmt.body, depth, opts);
|
|
6214
8539
|
case "SwitchStatement": {
|
|
6215
8540
|
const disc = transpileExpression(stmt.discriminant, opts);
|
|
6216
|
-
const
|
|
8541
|
+
const pre = [];
|
|
8542
|
+
let pendingTests = [];
|
|
6217
8543
|
for (const c of stmt.cases) {
|
|
6218
8544
|
const testSrc = c.test ? transpileExpression(c.test, opts) : null;
|
|
6219
8545
|
if (testSrc === null) {
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
arms.push({ tests: [testSrc], stmts: c.consequent, isDefault: false });
|
|
8546
|
+
if (pendingTests.length > 0 && c.consequent.length > 0) {
|
|
8547
|
+
pre.push({ tests: pendingTests, stmts: c.consequent, isDefault: false });
|
|
8548
|
+
pendingTests = [];
|
|
8549
|
+
}
|
|
8550
|
+
pre.push({ tests: [], stmts: c.consequent, isDefault: true });
|
|
8551
|
+
continue;
|
|
6227
8552
|
}
|
|
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] });
|
|
8553
|
+
if (c.consequent.length === 0) {
|
|
8554
|
+
pendingTests.push(testSrc);
|
|
8555
|
+
continue;
|
|
6235
8556
|
}
|
|
8557
|
+
pre.push({ tests: [...pendingTests, testSrc], stmts: c.consequent, isDefault: false });
|
|
8558
|
+
pendingTests = [];
|
|
8559
|
+
}
|
|
8560
|
+
if (pendingTests.length > 0) {
|
|
8561
|
+
pre.push({ tests: pendingTests, stmts: [], isDefault: false });
|
|
8562
|
+
}
|
|
8563
|
+
const merged = pre.map((arm) => ({ ...arm, tests: [...arm.tests], stmts: [...arm.stmts] }));
|
|
8564
|
+
for (let i = 0; i < merged.length; i++) {
|
|
8565
|
+
const arm = merged[i];
|
|
8566
|
+
const body = [...arm.stmts];
|
|
8567
|
+
let j = i + 1;
|
|
8568
|
+
while (j < merged.length && !stmtCompletesControl(body[body.length - 1])) {
|
|
8569
|
+
body.push(...merged[j].stmts);
|
|
8570
|
+
if (stmtCompletesControl(body[body.length - 1])) break;
|
|
8571
|
+
j++;
|
|
8572
|
+
}
|
|
8573
|
+
arm.stmts = body;
|
|
6236
8574
|
}
|
|
8575
|
+
const armReturns = (arm) => arm.stmts.length > 0 && arm.stmts.every(stmtReturns);
|
|
8576
|
+
const nonDefaultArms = merged.filter((a) => !a.isDefault);
|
|
8577
|
+
const defaultArm = merged.find((a) => a.isDefault);
|
|
8578
|
+
const allReturn = defaultArm !== void 0 && nonDefaultArms.length > 0 && nonDefaultArms.every(armReturns) && armReturns(defaultArm);
|
|
6237
8579
|
const caseLines = [];
|
|
8580
|
+
const sharedBodyDecls = [];
|
|
6238
8581
|
let defaultSrc = null;
|
|
8582
|
+
const bodyIdxBase = switchBodySeq;
|
|
8583
|
+
let bodyIdx = 0;
|
|
8584
|
+
const armOpts = {
|
|
8585
|
+
...opts,
|
|
8586
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8587
|
+
};
|
|
8588
|
+
const recvSet = /* @__PURE__ */ new Set([
|
|
8589
|
+
...merged.flatMap((a) => collectForkBindingNames(...a.stmts)),
|
|
8590
|
+
...collectForkBindingNames(stmt.discriminant)
|
|
8591
|
+
]);
|
|
8592
|
+
const names = [...recvSet];
|
|
8593
|
+
const nArms = merged.filter((a) => !a.isDefault).length + (defaultArm ? 1 : 0) + (defaultArm ? 0 : 1);
|
|
8594
|
+
const wrapArmThunk = (thunk, outIdx) => {
|
|
8595
|
+
if (names.length === 0) return thunk;
|
|
8596
|
+
return [
|
|
8597
|
+
`() => {`,
|
|
8598
|
+
...names.map((n) => `${indent(depth + 1)}${n} = __sw0_${n};`),
|
|
8599
|
+
`${indent(depth + 1)}let __cont = true;`,
|
|
8600
|
+
`${indent(depth + 1)}try {`,
|
|
8601
|
+
`${indent(depth + 2)}return (${thunk})();`,
|
|
8602
|
+
`${indent(depth + 1)}} catch (e) {`,
|
|
8603
|
+
`${indent(depth + 2)}if ($isForkExit(e)) __cont = false;`,
|
|
8604
|
+
`${indent(depth + 2)}throw e;`,
|
|
8605
|
+
`${indent(depth + 1)}} finally {`,
|
|
8606
|
+
`${indent(depth + 2)}if (__cont) {`,
|
|
8607
|
+
...names.map((n) => `${indent(depth + 3)}__sw${outIdx + 1}_${n} = ${n};`),
|
|
8608
|
+
...names.map((n) => `${indent(depth + 3)}__sw${outIdx + 1}set_${n} = true;`),
|
|
8609
|
+
`${indent(depth + 2)}}`,
|
|
8610
|
+
`${indent(depth + 1)}}`,
|
|
8611
|
+
`}`
|
|
8612
|
+
].join("\n");
|
|
8613
|
+
};
|
|
8614
|
+
let armSeq = 0;
|
|
6239
8615
|
for (const arm of merged) {
|
|
6240
|
-
const body = arm.stmts.map((s) => transpileStatement(s, depth + 2,
|
|
6241
|
-
const
|
|
8616
|
+
const body = arm.stmts.length === 0 ? "" : arm.stmts.map((s) => transpileStatement(s, depth + 2, armOpts)).join("\n");
|
|
8617
|
+
const rawThunk = `() => {
|
|
6242
8618
|
${body}
|
|
6243
8619
|
${indent(depth + 1)}}`;
|
|
8620
|
+
const thunk = wrapArmThunk(rawThunk, armSeq);
|
|
8621
|
+
armSeq++;
|
|
8622
|
+
const shared = arm.tests.length > 1 && !arm.isDefault;
|
|
8623
|
+
const runRef = shared ? `__swBody${bodyIdxBase + bodyIdx++}` : thunk;
|
|
8624
|
+
if (shared) {
|
|
8625
|
+
sharedBodyDecls.push(`${pad}const ${runRef} = ${thunk};`);
|
|
8626
|
+
}
|
|
6244
8627
|
if (arm.isDefault) {
|
|
6245
8628
|
defaultSrc = thunk;
|
|
6246
8629
|
} else {
|
|
6247
8630
|
for (const t of arm.tests) {
|
|
6248
|
-
caseLines.push(`{ test: ${t}, run: ${
|
|
8631
|
+
caseLines.push(`{ test: ${t}, run: ${runRef} },`);
|
|
6249
8632
|
}
|
|
6250
8633
|
}
|
|
6251
8634
|
}
|
|
8635
|
+
if (!defaultArm && names.length > 0) {
|
|
8636
|
+
defaultSrc = wrapArmThunk(`() => {
|
|
8637
|
+
${indent(depth + 2)}return $lit(undefined);
|
|
8638
|
+
${indent(depth + 1)}}`, armSeq);
|
|
8639
|
+
}
|
|
8640
|
+
switchBodySeq += Math.max(bodyIdx, 1);
|
|
6252
8641
|
const dflt = defaultSrc ? `, ${defaultSrc}` : "";
|
|
8642
|
+
const discRebinds = collectArrMutatorReceivers(stmt.discriminant).size ? emitArrMutatorRebinds(stmt.discriminant, opts, pad) : [];
|
|
8643
|
+
const switchCall = `$switch(${disc}, [
|
|
8644
|
+
${caseLines.map((l) => indent(depth + 1) + l).join("\n")}
|
|
8645
|
+
${indent(depth + 1)}]${dflt})`;
|
|
8646
|
+
if (names.length === 0) {
|
|
8647
|
+
return [
|
|
8648
|
+
...discRebinds,
|
|
8649
|
+
...sharedBodyDecls,
|
|
8650
|
+
allReturn ? `${pad}return ${switchCall};` : `${pad}${switchCall};`
|
|
8651
|
+
].join("\n");
|
|
8652
|
+
}
|
|
8653
|
+
const decls = names.flatMap((n) => [
|
|
8654
|
+
`${pad}const __sw0_${n} = ${n};`,
|
|
8655
|
+
...Array.from(
|
|
8656
|
+
{ length: Math.max(nArms, armSeq + (defaultArm ? 0 : 1)) },
|
|
8657
|
+
(_, i) => `${pad}let __sw${i + 1}_${n}; let __sw${i + 1}set_${n} = false;`
|
|
8658
|
+
)
|
|
8659
|
+
]);
|
|
8660
|
+
const slotCount = Math.max(nArms, armSeq + (defaultArm ? 0 : 1));
|
|
8661
|
+
const joins = names.map((n) => {
|
|
8662
|
+
const slots = Array.from(
|
|
8663
|
+
{ length: slotCount },
|
|
8664
|
+
(_, i) => `(__sw${i + 1}set_${n} ? __sw${i + 1}_${n} : null)`
|
|
8665
|
+
);
|
|
8666
|
+
return `${pad}${n} = (() => { const __p = [${slots.join(",")}].filter((x) => x !== null); return __p.length === 0 ? ${n} : __p.reduce((a, b) => $join(a, b)); })();`;
|
|
8667
|
+
});
|
|
6253
8668
|
return [
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
8669
|
+
...discRebinds,
|
|
8670
|
+
`${pad}{`,
|
|
8671
|
+
...decls.map((l) => l.replace(new RegExp(`^${pad}`), `${pad}`)),
|
|
8672
|
+
...sharedBodyDecls.map(
|
|
8673
|
+
(l) => l.startsWith(pad) ? `${pad}${l.slice(pad.length)}` : `${pad}${l}`
|
|
8674
|
+
),
|
|
8675
|
+
`${pad}const __swR = ${switchCall};`,
|
|
8676
|
+
...joins,
|
|
8677
|
+
allReturn ? `${pad}return __swR;` : null,
|
|
8678
|
+
`${pad}}`
|
|
8679
|
+
].filter((l) => l !== null).join("\n");
|
|
6258
8680
|
}
|
|
6259
8681
|
case "TryStatement": {
|
|
6260
|
-
const
|
|
6261
|
-
const
|
|
8682
|
+
const markName = `__nudoTm_${stmt.loc?.start.line ?? 0}`;
|
|
8683
|
+
const tryOpts = {
|
|
8684
|
+
...opts,
|
|
8685
|
+
inTry: (opts.inTry ?? 0) + 1,
|
|
8686
|
+
tryMarkName: markName
|
|
8687
|
+
};
|
|
8688
|
+
const tryBody = stmt.block.type === "BlockStatement" ? stmt.block.body.map((s) => transpileStatement(s, depth + 1, tryOpts)).join("\n") : transpileStatement(stmt.block, depth + 1, tryOpts);
|
|
8689
|
+
const lines = [
|
|
8690
|
+
`${pad}const ${markName} = $tryMark();`,
|
|
8691
|
+
`${pad}try {`,
|
|
8692
|
+
tryBody,
|
|
8693
|
+
`${pad}}`
|
|
8694
|
+
];
|
|
8695
|
+
const catchParam = stmt.handler?.param?.type === "Identifier" ? stmt.handler.param.name : "e";
|
|
8696
|
+
const catchTmp = `__nudoE_${stmt.loc?.start.line ?? 0}`;
|
|
8697
|
+
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
8698
|
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);
|
|
8699
|
+
const catchBody = transpileCatchBody(depth + 1, opts);
|
|
6266
8700
|
lines.push(`${pad}catch (${catchTmp}) {`);
|
|
6267
|
-
lines.push(`${indent(depth + 1)}
|
|
8701
|
+
lines.push(`${indent(depth + 1)}$rethrowIfNudoReturn(${catchTmp});`);
|
|
8702
|
+
lines.push(`${indent(depth + 1)}const __xs_${markName} = $tryTakeSince(${markName});`);
|
|
8703
|
+
lines.push(`${indent(depth + 1)}__xs_${markName}.push($catchVal(${catchTmp}));`);
|
|
8704
|
+
lines.push(
|
|
8705
|
+
`${indent(depth + 1)}const ${catchParam} = __xs_${markName}.reduce((a, b) => $join(a, b));`
|
|
8706
|
+
);
|
|
6268
8707
|
lines.push(catchBody);
|
|
6269
8708
|
lines.push(`${pad}}`);
|
|
6270
8709
|
}
|
|
@@ -6272,6 +8711,30 @@ ${indent(depth + 1)}}`;
|
|
|
6272
8711
|
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
8712
|
lines.push(`${pad}finally {`);
|
|
6274
8713
|
lines.push(finBody);
|
|
8714
|
+
lines.push(`${pad}$tryPopMark();`);
|
|
8715
|
+
lines.push(`${pad}}`);
|
|
8716
|
+
} else {
|
|
8717
|
+
lines.push(`${pad}$tryPopMark();`);
|
|
8718
|
+
}
|
|
8719
|
+
if (stmt.handler) {
|
|
8720
|
+
const catchBody = transpileCatchBody(depth + 2, opts);
|
|
8721
|
+
lines.push(`${pad}{`);
|
|
8722
|
+
lines.push(`${indent(depth + 1)}const __post_${markName} = $tryTakeSince(${markName});`);
|
|
8723
|
+
lines.push(`${indent(depth + 1)}if (__post_${markName}.length) {`);
|
|
8724
|
+
lines.push(
|
|
8725
|
+
`${indent(depth + 2)}const ${catchParam} = __post_${markName}.reduce((a, b) => $join(a, b));`
|
|
8726
|
+
);
|
|
8727
|
+
lines.push(
|
|
8728
|
+
catchBody.split("\n").map((l) => l ? `${indent(depth + 2)}${l.trimStart()}` : l).join("\n")
|
|
8729
|
+
);
|
|
8730
|
+
lines.push(`${indent(depth + 1)}}`);
|
|
8731
|
+
lines.push(`${pad}}`);
|
|
8732
|
+
} else {
|
|
8733
|
+
lines.push(`${pad}{`);
|
|
8734
|
+
lines.push(`${indent(depth + 1)}const __post_${markName} = $tryTakeSince(${markName});`);
|
|
8735
|
+
lines.push(`${indent(depth + 1)}if (__post_${markName}.length) {`);
|
|
8736
|
+
lines.push(`${indent(depth + 2)}$throw(__post_${markName}.reduce((a, b) => $join(a, b)));`);
|
|
8737
|
+
lines.push(`${indent(depth + 1)}}`);
|
|
6275
8738
|
lines.push(`${pad}}`);
|
|
6276
8739
|
}
|
|
6277
8740
|
return lines.join("\n");
|
|
@@ -6300,24 +8763,77 @@ ${indent(depth + 1)}}`;
|
|
|
6300
8763
|
{ n: 0 }
|
|
6301
8764
|
);
|
|
6302
8765
|
}
|
|
6303
|
-
const
|
|
8766
|
+
const bodyOpts = {
|
|
8767
|
+
...opts,
|
|
8768
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8769
|
+
};
|
|
8770
|
+
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
8771
|
const max = opts.maxLoopIters ?? 8;
|
|
8772
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8773
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8774
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8775
|
+
const names = [...assigned].filter((n) => n !== bindName && n !== "undefined");
|
|
8776
|
+
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
8777
|
return [
|
|
6306
8778
|
`${pad}$forOf(${iter}, (${bindName}, _i) => {`,
|
|
6307
8779
|
...bodyLines,
|
|
6308
8780
|
bodyStmts,
|
|
6309
|
-
`${pad}}, ${max});`
|
|
8781
|
+
`${pad}}, ${max}${optsSrc});`
|
|
6310
8782
|
].join("\n");
|
|
6311
8783
|
}
|
|
6312
8784
|
case "WhileStatement": {
|
|
6313
8785
|
const test = transpileExpression(stmt.test, opts);
|
|
6314
|
-
const
|
|
8786
|
+
const bodyOpts = {
|
|
8787
|
+
...opts,
|
|
8788
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8789
|
+
};
|
|
8790
|
+
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
8791
|
const max = opts.maxLoopIters ?? 8;
|
|
8792
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8793
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8794
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8795
|
+
const names = [...assigned].filter((n) => n !== "undefined");
|
|
8796
|
+
if (names.length === 0) {
|
|
8797
|
+
return [
|
|
8798
|
+
`${pad}// while \u2192 $whileSeq (bounded, max=${max})`,
|
|
8799
|
+
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
8800
|
+
body,
|
|
8801
|
+
`${pad}}, ${max});`
|
|
8802
|
+
].join("\n");
|
|
8803
|
+
}
|
|
8804
|
+
const packSrc = `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8805
|
+
const unpackSrc = `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
6316
8806
|
return [
|
|
6317
|
-
`${pad}// while \u2192 $whileSeq (
|
|
8807
|
+
`${pad}// while \u2192 $whileSeq (instrumented bindings: ${names.join(", ")})`,
|
|
6318
8808
|
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
6319
8809
|
body,
|
|
6320
|
-
`${pad}}, ${max});`
|
|
8810
|
+
`${pad}}, ${max}, { pack: () => ${packSrc}, unpack: ${unpackSrc} });`
|
|
8811
|
+
].join("\n");
|
|
8812
|
+
}
|
|
8813
|
+
case "DoWhileStatement": {
|
|
8814
|
+
const test = transpileExpression(stmt.test, opts);
|
|
8815
|
+
const bodyOpts = {
|
|
8816
|
+
...opts,
|
|
8817
|
+
inLoop: (opts.inLoop ?? 0) + 1
|
|
8818
|
+
};
|
|
8819
|
+
const bodyStmts = stmt.body.type === "BlockStatement" ? stmt.body.body.map((s) => transpileStatement(s, depth + 1, bodyOpts)).join("\n") : transpileStatement(stmt.body, depth + 1, bodyOpts);
|
|
8820
|
+
const max = opts.maxLoopIters ?? 8;
|
|
8821
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
8822
|
+
collectAssignedIds(stmt.body, assigned);
|
|
8823
|
+
collectAssignedIds(stmt.test, assigned);
|
|
8824
|
+
collectArrMutatorReceivers(stmt.body, assigned);
|
|
8825
|
+
const names = [...assigned].filter((n) => n !== "undefined");
|
|
8826
|
+
const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: ${n}`).join(", ")} })`;
|
|
8827
|
+
const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
8828
|
+
const optsSrc = packSrc && unpackSrc ? `, { pack: () => ${packSrc}, unpack: ${unpackSrc} }` : "";
|
|
8829
|
+
return [
|
|
8830
|
+
`${pad}// do-while \u2192 body + $whileSeq (bounded, max=${max})`,
|
|
8831
|
+
`{`,
|
|
8832
|
+
bodyStmts,
|
|
8833
|
+
`${indent(depth + 1)}$whileSeq(() => ${test}, () => {`,
|
|
8834
|
+
bodyStmts,
|
|
8835
|
+
`${indent(depth + 1)}}, ${max}${optsSrc});`,
|
|
8836
|
+
`${pad}}`
|
|
6321
8837
|
].join("\n");
|
|
6322
8838
|
}
|
|
6323
8839
|
case "ClassDeclaration": {
|
|
@@ -6342,6 +8858,8 @@ function transpileClass(stmt, depth, opts) {
|
|
|
6342
8858
|
});
|
|
6343
8859
|
const methodOpts = {
|
|
6344
8860
|
...opts,
|
|
8861
|
+
inLoop: 0,
|
|
8862
|
+
inTry: 0,
|
|
6345
8863
|
thisParam: "__this",
|
|
6346
8864
|
className: name
|
|
6347
8865
|
};
|
|
@@ -6425,6 +8943,9 @@ ${indent(depth)}}`;
|
|
|
6425
8943
|
}
|
|
6426
8944
|
if (stmt.type === "ReturnStatement") {
|
|
6427
8945
|
const v2 = stmt.argument ? transpileExpression(stmt.argument, opts) : "$lit(undefined)";
|
|
8946
|
+
if ((opts.inLoop ?? 0) > 0) {
|
|
8947
|
+
return `() => { $loopReturn(${v2}); }`;
|
|
8948
|
+
}
|
|
6428
8949
|
return `() => ${v2}`;
|
|
6429
8950
|
}
|
|
6430
8951
|
const one = transpileStatement(stmt, depth + 1, opts);
|
|
@@ -6466,15 +8987,53 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6466
8987
|
}
|
|
6467
8988
|
case "LogicalExpression": {
|
|
6468
8989
|
const op = expr.operator;
|
|
8990
|
+
const lNode = expr.left;
|
|
8991
|
+
const rNode = expr.right;
|
|
6469
8992
|
const l = transpileExpression(expr.left, opts);
|
|
6470
8993
|
const r = transpileExpression(expr.right, opts);
|
|
6471
|
-
|
|
8994
|
+
if (op === "??") {
|
|
8995
|
+
return transpileShortCircuitExpr(opts, {
|
|
8996
|
+
alwaysNodes: [lNode],
|
|
8997
|
+
alwaysSrc: l,
|
|
8998
|
+
// 测试用 nullish;返回侧:nullish → right,否则 → left
|
|
8999
|
+
consSrc: r,
|
|
9000
|
+
consNodes: [rNode],
|
|
9001
|
+
altSrc: l,
|
|
9002
|
+
altNodes: [lNode],
|
|
9003
|
+
testSrc: `$nullishTest(${l})`
|
|
9004
|
+
});
|
|
9005
|
+
}
|
|
9006
|
+
return op === "&&" ? transpileShortCircuitExpr(opts, {
|
|
9007
|
+
alwaysNodes: [lNode],
|
|
9008
|
+
alwaysSrc: l,
|
|
9009
|
+
consSrc: r,
|
|
9010
|
+
consNodes: [rNode],
|
|
9011
|
+
altSrc: "__test",
|
|
9012
|
+
altNodes: []
|
|
9013
|
+
}) : transpileShortCircuitExpr(opts, {
|
|
9014
|
+
alwaysNodes: [lNode],
|
|
9015
|
+
alwaysSrc: l,
|
|
9016
|
+
consSrc: "__test",
|
|
9017
|
+
consNodes: [],
|
|
9018
|
+
altSrc: r,
|
|
9019
|
+
altNodes: [rNode]
|
|
9020
|
+
});
|
|
6472
9021
|
}
|
|
6473
9022
|
case "ConditionalExpression": {
|
|
9023
|
+
const testNode = expr.test;
|
|
9024
|
+
const consNode = expr.consequent;
|
|
9025
|
+
const altNode = expr.alternate;
|
|
6474
9026
|
const test = transpileExpression(expr.test, opts);
|
|
6475
9027
|
const c = transpileExpression(expr.consequent, opts);
|
|
6476
9028
|
const a = transpileExpression(expr.alternate, opts);
|
|
6477
|
-
return
|
|
9029
|
+
return transpileShortCircuitExpr(opts, {
|
|
9030
|
+
alwaysNodes: [testNode],
|
|
9031
|
+
alwaysSrc: test,
|
|
9032
|
+
consSrc: c,
|
|
9033
|
+
consNodes: [consNode],
|
|
9034
|
+
altSrc: a,
|
|
9035
|
+
altNodes: [altNode]
|
|
9036
|
+
});
|
|
6478
9037
|
}
|
|
6479
9038
|
case "RegExpLiteral": {
|
|
6480
9039
|
return `$regex(${JSON.stringify(expr.pattern)}${expr.flags ? `, ${JSON.stringify(expr.flags)}` : ""})`;
|
|
@@ -6543,6 +9102,22 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6543
9102
|
acc = acc === null ? arg : `$spread(${acc}, ${arg})`;
|
|
6544
9103
|
continue;
|
|
6545
9104
|
}
|
|
9105
|
+
if (prop.type === "ObjectMethod") {
|
|
9106
|
+
flushProps();
|
|
9107
|
+
const mkey = prop.key.type === "Identifier" ? JSON.stringify(prop.key.name) : prop.key.type === "StringLiteral" ? JSON.stringify(prop.key.value) : null;
|
|
9108
|
+
if (mkey === null) continue;
|
|
9109
|
+
const paramNames = prop.params.map(
|
|
9110
|
+
(p) => p.type === "Identifier" && p.name ? p.name : "_a"
|
|
9111
|
+
);
|
|
9112
|
+
const methodOpts = { ...opts, inLoop: 0, inTry: 0, thisParam: "__this" };
|
|
9113
|
+
const bodySrc = prop.body.type === "BlockStatement" ? `{
|
|
9114
|
+
${prop.body.body.map((s) => transpileStatement(s, 1, methodOpts)).join("\n")}
|
|
9115
|
+
}` : transpileExpression(prop.body, methodOpts);
|
|
9116
|
+
const bindParams = ["__this", ...paramNames];
|
|
9117
|
+
const fnValSrc = `$fnVal([${paramNames.map((p) => JSON.stringify(p)).join(", ")}], (${bindParams.join(", ")}) => ${bodySrc}, { bindThis: true })`;
|
|
9118
|
+
props.push(`${mkey}: ${fnValSrc}`);
|
|
9119
|
+
continue;
|
|
9120
|
+
}
|
|
6546
9121
|
if (prop.type !== "ObjectProperty") continue;
|
|
6547
9122
|
if (prop.computed) {
|
|
6548
9123
|
flushProps();
|
|
@@ -6554,6 +9129,23 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6554
9129
|
}
|
|
6555
9130
|
const key = prop.key.type === "Identifier" ? JSON.stringify(prop.key.name) : prop.key.type === "StringLiteral" ? JSON.stringify(prop.key.value) : null;
|
|
6556
9131
|
if (key === null) continue;
|
|
9132
|
+
if (prop.value.type === "FunctionExpression" && !prop.value.async) {
|
|
9133
|
+
const fn = prop.value;
|
|
9134
|
+
if (!fn.generator) {
|
|
9135
|
+
const paramNames = fn.params.map(
|
|
9136
|
+
(p) => p.type === "Identifier" && p.name ? p.name : "_a"
|
|
9137
|
+
);
|
|
9138
|
+
const methodOpts = { ...opts, inLoop: 0, thisParam: "__this" };
|
|
9139
|
+
const bodySrc = fn.body.type === "BlockStatement" ? `{
|
|
9140
|
+
${fn.body.body.map((s) => transpileStatement(s, 1, methodOpts)).join("\n")}
|
|
9141
|
+
}` : transpileExpression(fn.body, methodOpts);
|
|
9142
|
+
const bindParams = ["__this", ...paramNames];
|
|
9143
|
+
props.push(
|
|
9144
|
+
`${key}: $fnVal([${paramNames.map((p) => JSON.stringify(p)).join(", ")}], (${bindParams.join(", ")}) => ${bodySrc}, { bindThis: true })`
|
|
9145
|
+
);
|
|
9146
|
+
continue;
|
|
9147
|
+
}
|
|
9148
|
+
}
|
|
6557
9149
|
const valSrc = transpileExpression(prop.value, opts);
|
|
6558
9150
|
props.push(`${key}: ${valSrc}`);
|
|
6559
9151
|
}
|
|
@@ -6605,6 +9197,58 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6605
9197
|
case "AssignmentExpression": {
|
|
6606
9198
|
const compoundFn = COMPOUND_OPS[expr.operator];
|
|
6607
9199
|
const right = transpileExpression(expr.right, opts);
|
|
9200
|
+
const op = expr.operator;
|
|
9201
|
+
if (op === "||=" || op === "&&=" || op === "??=") {
|
|
9202
|
+
const rNode = expr.right;
|
|
9203
|
+
const emitLogicalAssign = (targetSrc, setSrc) => {
|
|
9204
|
+
if (op === "||=") {
|
|
9205
|
+
const sc2 = transpileShortCircuitExpr(opts, {
|
|
9206
|
+
alwaysNodes: [],
|
|
9207
|
+
alwaysSrc: targetSrc,
|
|
9208
|
+
consSrc: "__test",
|
|
9209
|
+
consNodes: [],
|
|
9210
|
+
altSrc: right,
|
|
9211
|
+
altNodes: [rNode]
|
|
9212
|
+
});
|
|
9213
|
+
return setSrc(sc2);
|
|
9214
|
+
}
|
|
9215
|
+
if (op === "&&=") {
|
|
9216
|
+
const sc2 = transpileShortCircuitExpr(opts, {
|
|
9217
|
+
alwaysNodes: [],
|
|
9218
|
+
alwaysSrc: targetSrc,
|
|
9219
|
+
consSrc: right,
|
|
9220
|
+
consNodes: [rNode],
|
|
9221
|
+
altSrc: "__test",
|
|
9222
|
+
altNodes: []
|
|
9223
|
+
});
|
|
9224
|
+
return setSrc(sc2);
|
|
9225
|
+
}
|
|
9226
|
+
const sc = transpileShortCircuitExpr(opts, {
|
|
9227
|
+
alwaysNodes: [],
|
|
9228
|
+
alwaysSrc: targetSrc,
|
|
9229
|
+
consSrc: right,
|
|
9230
|
+
consNodes: [rNode],
|
|
9231
|
+
altSrc: targetSrc,
|
|
9232
|
+
altNodes: [],
|
|
9233
|
+
testSrc: `$nullishTest(${targetSrc})`
|
|
9234
|
+
});
|
|
9235
|
+
return setSrc(sc);
|
|
9236
|
+
};
|
|
9237
|
+
if (expr.left.type === "Identifier") {
|
|
9238
|
+
return emitLogicalAssign(expr.left.name, (val) => `${expr.left.type === "Identifier" ? expr.left.name : ""} = ${val}`);
|
|
9239
|
+
}
|
|
9240
|
+
if (expr.left.type === "MemberExpression") {
|
|
9241
|
+
const m = expr.left;
|
|
9242
|
+
const path = memberPathOf(m, opts);
|
|
9243
|
+
if (path) {
|
|
9244
|
+
return emitLogicalAssign(readPathSrc(path), (val) => {
|
|
9245
|
+
const writeSrc = setPathSrc(path, val);
|
|
9246
|
+
return `${path.rootSrc} = ${writeSrc}`;
|
|
9247
|
+
});
|
|
9248
|
+
}
|
|
9249
|
+
}
|
|
9250
|
+
return `/* assign ${op} */ $lit(undefined)`;
|
|
9251
|
+
}
|
|
6608
9252
|
if (expr.left.type === "MemberExpression") {
|
|
6609
9253
|
const m = expr.left;
|
|
6610
9254
|
const path = memberPathOf(m, opts);
|
|
@@ -6694,10 +9338,11 @@ function transpileExpression(expr, opts = {}) {
|
|
|
6694
9338
|
case "FunctionExpression": {
|
|
6695
9339
|
const fn = expr;
|
|
6696
9340
|
const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
|
|
9341
|
+
const fnBodyOpts = { ...opts, inLoop: 0 };
|
|
6697
9342
|
const paramParts = rest ? [...sig, `...${rest}`] : sig;
|
|
6698
9343
|
const nameList = `[${sig.map((p) => JSON.stringify(p)).join(", ")}]`;
|
|
6699
9344
|
if (fn.body.type === "BlockStatement") {
|
|
6700
|
-
const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1,
|
|
9345
|
+
const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1, fnBodyOpts)].join("\n");
|
|
6701
9346
|
if (fn.async) {
|
|
6702
9347
|
return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => {
|
|
6703
9348
|
${inner}
|
|
@@ -6707,7 +9352,7 @@ ${inner}
|
|
|
6707
9352
|
${inner}
|
|
6708
9353
|
})`;
|
|
6709
9354
|
}
|
|
6710
|
-
const bodySrc = transpileExpression(fn.body,
|
|
9355
|
+
const bodySrc = transpileExpression(fn.body, fnBodyOpts);
|
|
6711
9356
|
if (prologue.length > 0) {
|
|
6712
9357
|
const thunk = fn.async ? `$async(() => ${bodySrc})` : bodySrc;
|
|
6713
9358
|
return `$fnVal(${nameList}, (${paramParts.join(", ")}) => {
|
|
@@ -6807,7 +9452,7 @@ function $new(cls, args) {
|
|
|
6807
9452
|
if (args.length === 1) {
|
|
6808
9453
|
const n = litValue(args[0]);
|
|
6809
9454
|
if (typeof n === "number" && Number.isInteger(n) && n >= 0 && n <= 4096) {
|
|
6810
|
-
const els = Array.from({ length: n }, () =>
|
|
9455
|
+
const els = Array.from({ length: n }, () => undefAbs2());
|
|
6811
9456
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6812
9457
|
}
|
|
6813
9458
|
return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
|
|
@@ -6818,9 +9463,14 @@ function $new(cls, args) {
|
|
|
6818
9463
|
const p = args[0] ? litValue(args[0]) : void 0;
|
|
6819
9464
|
if (typeof p === "string") return $regex(p, args[1] ? String(litValue(args[1]) ?? "") : "");
|
|
6820
9465
|
}
|
|
6821
|
-
const
|
|
9466
|
+
const clsName = cls.name || "Object";
|
|
9467
|
+
if (isErrorCtorName(clsName)) {
|
|
9468
|
+
return errorBrandAbs(clsName, args[0]);
|
|
9469
|
+
}
|
|
9470
|
+
if (clsName === "Map") return makeMapAbs(args[0]);
|
|
9471
|
+
if (clsName === "Set") return makeSetAbs(args[0]);
|
|
6822
9472
|
const shape = objOf({});
|
|
6823
|
-
return abs({ k: "brand", name, shape }, void 0, void 0, "path");
|
|
9473
|
+
return abs({ k: "brand", name: clsName, shape }, void 0, void 0, "path");
|
|
6824
9474
|
}
|
|
6825
9475
|
const spec = specOf(cls);
|
|
6826
9476
|
if (!spec) {
|
|
@@ -6884,7 +9534,7 @@ function execRegexBrand(re, method, args) {
|
|
|
6884
9534
|
if (!m) {
|
|
6885
9535
|
return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
6886
9536
|
}
|
|
6887
|
-
const els = m.map((g) => g === void 0 ?
|
|
9537
|
+
const els = m.map((g) => g === void 0 ? undefAbs2() : strLit(g));
|
|
6888
9538
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6889
9539
|
}
|
|
6890
9540
|
function stringRegexMethod(recv, method, args) {
|
|
@@ -6917,10 +9567,69 @@ function stringRegexMethod(recv, method, args) {
|
|
|
6917
9567
|
if (!m) {
|
|
6918
9568
|
return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
6919
9569
|
}
|
|
6920
|
-
const els = m.map((g) => g === void 0 ?
|
|
9570
|
+
const els = m.map((g) => g === void 0 ? undefAbs2() : strLit(g));
|
|
6921
9571
|
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
6922
9572
|
}
|
|
6923
9573
|
function $invoke(thisVal, method, args, loc) {
|
|
9574
|
+
if (method === "call" || method === "apply" || method === "bind") {
|
|
9575
|
+
const expandApplyArgs = (list) => {
|
|
9576
|
+
if (list === null || list === void 0) return [];
|
|
9577
|
+
if (Array.isArray(list)) {
|
|
9578
|
+
return list.map(
|
|
9579
|
+
(x) => x && typeof x === "object" && "shape" in x ? x : unknown
|
|
9580
|
+
);
|
|
9581
|
+
}
|
|
9582
|
+
if (typeof list === "object" && "shape" in list) {
|
|
9583
|
+
const s = list.shape;
|
|
9584
|
+
if (s.k === "tuple") return [...s.elements];
|
|
9585
|
+
if (s.k === "arr") return [s.element];
|
|
9586
|
+
}
|
|
9587
|
+
return [unknown];
|
|
9588
|
+
};
|
|
9589
|
+
const boundFnParams = (fnVal, boundCount) => {
|
|
9590
|
+
if (fnVal && typeof fnVal === "object" && "shape" in fnVal) {
|
|
9591
|
+
const s = fnVal.shape;
|
|
9592
|
+
if (s.k === "fn" && Array.isArray(s.params)) {
|
|
9593
|
+
return s.params.slice(boundCount);
|
|
9594
|
+
}
|
|
9595
|
+
}
|
|
9596
|
+
if (typeof fnVal === "function") {
|
|
9597
|
+
const arity = fnVal.length ?? 0;
|
|
9598
|
+
const rem = Math.max(0, arity - boundCount);
|
|
9599
|
+
return Array.from({ length: rem }, (_, i) => `_a${boundCount + i}`);
|
|
9600
|
+
}
|
|
9601
|
+
return ["_rest"];
|
|
9602
|
+
};
|
|
9603
|
+
if (typeof thisVal === "function") {
|
|
9604
|
+
const fn = thisVal;
|
|
9605
|
+
if (method === "call") {
|
|
9606
|
+
return callAtFunctionBoundary(() => fn(...args.slice(1)));
|
|
9607
|
+
}
|
|
9608
|
+
if (method === "apply") {
|
|
9609
|
+
return callAtFunctionBoundary(() => fn(...expandApplyArgs(args[1])));
|
|
9610
|
+
}
|
|
9611
|
+
const bound = args.slice(1);
|
|
9612
|
+
return absFunction(boundFnParams(thisVal, bound.length), {
|
|
9613
|
+
apply: (callArgs) => callAtFunctionBoundary(() => fn(...bound, ...callArgs))
|
|
9614
|
+
});
|
|
9615
|
+
}
|
|
9616
|
+
if (thisVal && typeof thisVal === "object" && "shape" in thisVal) {
|
|
9617
|
+
const fnImpl = getFnImpl(thisVal);
|
|
9618
|
+
const isCallable = thisVal.shape.k === "fn" || fnImpl !== void 0;
|
|
9619
|
+
if (isCallable) {
|
|
9620
|
+
if (method === "call") {
|
|
9621
|
+
return $call(thisVal, args.slice(1));
|
|
9622
|
+
}
|
|
9623
|
+
if (method === "apply") {
|
|
9624
|
+
return $call(thisVal, expandApplyArgs(args[1]));
|
|
9625
|
+
}
|
|
9626
|
+
const bound = args.slice(1);
|
|
9627
|
+
return absFunction(boundFnParams(thisVal, bound.length), {
|
|
9628
|
+
apply: (callArgs) => callAtFunctionBoundary(() => $call(thisVal, [...bound, ...callArgs]))
|
|
9629
|
+
});
|
|
9630
|
+
}
|
|
9631
|
+
}
|
|
9632
|
+
}
|
|
6924
9633
|
if (!thisVal || typeof thisVal !== "object" || !("shape" in thisVal)) {
|
|
6925
9634
|
const ns = namespaceNameOf(thisVal);
|
|
6926
9635
|
return (ns ? evalNamespaceCall(ns, method, args) : void 0) ?? unknown;
|
|
@@ -6936,6 +9645,10 @@ function $invoke(thisVal, method, args, loc) {
|
|
|
6936
9645
|
}
|
|
6937
9646
|
const brandName = thisVal.shape.k === "brand" ? thisVal.shape.name : void 0;
|
|
6938
9647
|
if (brandName) {
|
|
9648
|
+
if (brandName === "Map" || brandName === "Set") {
|
|
9649
|
+
const viaCol = evalBuiltinInstanceMethod(brandName, method, thisVal, args);
|
|
9650
|
+
if (viaCol !== void 0) return viaCol;
|
|
9651
|
+
}
|
|
6939
9652
|
const m = findMethod(brandName, method);
|
|
6940
9653
|
if (m) return m(thisVal, ...args);
|
|
6941
9654
|
const spec = getBClass(brandName);
|
|
@@ -6957,6 +9670,7 @@ function $invoke(thisVal, method, args, loc) {
|
|
|
6957
9670
|
const prop = $get(thisVal, method, { silent: true });
|
|
6958
9671
|
const impl = prop && typeof prop === "object" && "shape" in prop ? getFnImpl(prop) : void 0;
|
|
6959
9672
|
if (impl) {
|
|
9673
|
+
if (impl.bindThis) return $call(prop, [thisVal, ...args]);
|
|
6960
9674
|
return $call(prop, args);
|
|
6961
9675
|
}
|
|
6962
9676
|
if (notePrimMemberMissing(thisVal, method, "method", loc)) return unknown;
|
|
@@ -6974,8 +9688,21 @@ function memberLikelyHasMethod(m, method) {
|
|
|
6974
9688
|
function invokeArrMethod(arr, method, args) {
|
|
6975
9689
|
const shape = arr.shape;
|
|
6976
9690
|
const callFn = (fn, ...fnArgs) => {
|
|
9691
|
+
const sumIdx = fnArgs.findIndex(
|
|
9692
|
+
(a) => a && typeof a === "object" && "shape" in a && a.shape.k === "sum"
|
|
9693
|
+
);
|
|
9694
|
+
if (sumIdx >= 0) {
|
|
9695
|
+
const members = fnArgs[sumIdx].shape.members;
|
|
9696
|
+
let acc;
|
|
9697
|
+
for (const m of members) {
|
|
9698
|
+
const next = fnArgs.map((a, i) => i === sumIdx ? m : a);
|
|
9699
|
+
const r = callFn(fn, ...next);
|
|
9700
|
+
acc = acc === void 0 ? r : joinAbs(acc, r);
|
|
9701
|
+
}
|
|
9702
|
+
return acc ?? unknown;
|
|
9703
|
+
}
|
|
6977
9704
|
if (typeof fn === "function") {
|
|
6978
|
-
const r = fn(...fnArgs);
|
|
9705
|
+
const r = callAtFunctionBoundary(() => fn(...fnArgs));
|
|
6979
9706
|
if (r && typeof r === "object" && "shape" in r) return r;
|
|
6980
9707
|
return unknown;
|
|
6981
9708
|
}
|
|
@@ -7033,7 +9760,7 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7033
9760
|
if (method === "forEach" && args[0]) {
|
|
7034
9761
|
const list = shape.k === "tuple" ? shape.elements : [shape.element];
|
|
7035
9762
|
for (const el of list) callFn(args[0], el);
|
|
7036
|
-
return
|
|
9763
|
+
return undefAbs2();
|
|
7037
9764
|
}
|
|
7038
9765
|
if ((method === "some" || method === "every") && args[0]) {
|
|
7039
9766
|
const list = shape.k === "tuple" ? shape.elements : [shape.element];
|
|
@@ -7043,7 +9770,7 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7043
9770
|
if (method === "find" && args[0]) {
|
|
7044
9771
|
const el = shape.k === "tuple" ? shape.elements[0] ?? unknown : shape.element;
|
|
7045
9772
|
callFn(args[0], el);
|
|
7046
|
-
return joinAbs(el,
|
|
9773
|
+
return joinAbs(el, undefAbs2());
|
|
7047
9774
|
}
|
|
7048
9775
|
if (method === "join") {
|
|
7049
9776
|
return abs({ k: "prim", type: "string" }, void 0, void 0, "path");
|
|
@@ -7063,11 +9790,35 @@ function invokeArrMethod(arr, method, args) {
|
|
|
7063
9790
|
if (method === "includes") {
|
|
7064
9791
|
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
7065
9792
|
}
|
|
7066
|
-
if (method === "
|
|
9793
|
+
if (method === "push" || method === "unshift") {
|
|
9794
|
+
return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
|
|
9795
|
+
}
|
|
9796
|
+
if (method === "pop") {
|
|
9797
|
+
if (shape.k === "tuple") {
|
|
9798
|
+
return shape.elements.length > 0 ? shape.elements[shape.elements.length - 1] ?? unknown : undefAbs2();
|
|
9799
|
+
}
|
|
9800
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
9801
|
+
}
|
|
9802
|
+
if (method === "shift") {
|
|
7067
9803
|
if (shape.k === "tuple" && shape.elements.length > 0) {
|
|
7068
9804
|
return shape.elements[0] ?? unknown;
|
|
7069
9805
|
}
|
|
7070
|
-
if (shape.k === "arr") return shape.element;
|
|
9806
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
9807
|
+
}
|
|
9808
|
+
if (method === "at") {
|
|
9809
|
+
const raw = args[0] !== void 0 ? litValue(args[0]) : void 0;
|
|
9810
|
+
const iv = typeof raw === "number" && Number.isInteger(raw) ? raw : void 0;
|
|
9811
|
+
if (shape.k === "tuple") {
|
|
9812
|
+
const els = shape.elements;
|
|
9813
|
+
if (iv === void 0) {
|
|
9814
|
+
if (els.length === 0) return undefAbs2();
|
|
9815
|
+
return joinAbs(els.reduce((a, b) => joinAbs(a, b)), undefAbs2());
|
|
9816
|
+
}
|
|
9817
|
+
const idx = iv < 0 ? els.length + iv : iv;
|
|
9818
|
+
if (idx >= 0 && idx < els.length) return els[idx] ?? unknown;
|
|
9819
|
+
return undefAbs2();
|
|
9820
|
+
}
|
|
9821
|
+
if (shape.k === "arr") return joinAbs(shape.element, undefAbs2());
|
|
7071
9822
|
}
|
|
7072
9823
|
return void 0;
|
|
7073
9824
|
}
|
|
@@ -7109,13 +9860,32 @@ function $thisSet(thisVal, key, value) {
|
|
|
7109
9860
|
}
|
|
7110
9861
|
function $orDefault(v2, dflt) {
|
|
7111
9862
|
if (v2 === void 0) return asAbsVal(dflt());
|
|
7112
|
-
if (
|
|
7113
|
-
|
|
7114
|
-
|
|
9863
|
+
if (isDefinitelyUndefinedAbs(v2)) return asAbsVal(dflt());
|
|
9864
|
+
if (v2.shape.k === "sum") {
|
|
9865
|
+
const d = asAbsVal(dflt());
|
|
9866
|
+
const parts = [];
|
|
9867
|
+
let sawUndef = false;
|
|
9868
|
+
for (const m of v2.shape.members) {
|
|
9869
|
+
if (isDefinitelyUndefinedAbs(m)) {
|
|
9870
|
+
sawUndef = true;
|
|
9871
|
+
continue;
|
|
9872
|
+
}
|
|
9873
|
+
parts.push(m);
|
|
9874
|
+
}
|
|
9875
|
+
if (!sawUndef) return v2;
|
|
9876
|
+
if (parts.length === 0) return d;
|
|
9877
|
+
let joined = parts[0];
|
|
9878
|
+
for (let i = 1; i < parts.length; i++) joined = joinAbs(joined, parts[i]);
|
|
9879
|
+
return joinAbs(joined, d);
|
|
7115
9880
|
}
|
|
7116
|
-
if (v2.term?.op === "lit" && v2.term.value === void 0) return asAbsVal(dflt());
|
|
7117
9881
|
return v2;
|
|
7118
9882
|
}
|
|
9883
|
+
function isDefinitelyUndefinedAbs(v2) {
|
|
9884
|
+
if (!v2) return false;
|
|
9885
|
+
if (v2.term?.op === "lit" && v2.term.value === void 0) return true;
|
|
9886
|
+
if (v2.shape.k === "unknown" && v2.term?.op === "lit" && litValue(v2) === void 0) return true;
|
|
9887
|
+
return false;
|
|
9888
|
+
}
|
|
7119
9889
|
function isNullishAbs(v2) {
|
|
7120
9890
|
if (!v2 || v2.term?.op !== "lit") return false;
|
|
7121
9891
|
const lv = v2.term.value;
|
|
@@ -7154,11 +9924,47 @@ function $setKey(o, key, value) {
|
|
|
7154
9924
|
if (typeof k === "string" || typeof k === "number") {
|
|
7155
9925
|
return $set(o, String(k), value);
|
|
7156
9926
|
}
|
|
7157
|
-
|
|
9927
|
+
const val = asAbsVal(value);
|
|
9928
|
+
if (o.shape.k === "brand") {
|
|
9929
|
+
const inner = $setKey(o.shape.shape, key, value);
|
|
9930
|
+
return abs(
|
|
9931
|
+
{ k: "brand", name: o.shape.name, shape: inner },
|
|
9932
|
+
o.term,
|
|
9933
|
+
o.pred,
|
|
9934
|
+
confJoin(o.conf, value.conf)
|
|
9935
|
+
);
|
|
9936
|
+
}
|
|
9937
|
+
if (o.shape.k !== "obj") {
|
|
9938
|
+
return abs(
|
|
9939
|
+
{
|
|
9940
|
+
k: "obj",
|
|
9941
|
+
slots: {},
|
|
9942
|
+
index: { key: unknown, value: val },
|
|
9943
|
+
open: true
|
|
9944
|
+
},
|
|
9945
|
+
void 0,
|
|
9946
|
+
void 0,
|
|
9947
|
+
confJoin("path", value.conf)
|
|
9948
|
+
);
|
|
9949
|
+
}
|
|
9950
|
+
const shape = o.shape;
|
|
9951
|
+
const prevIndex = shape.index?.value;
|
|
9952
|
+
const indexVal = prevIndex ? joinAbs(prevIndex, val) : val;
|
|
9953
|
+
const next = objOf({ ...shape.slots }, {
|
|
9954
|
+
index: { key: shape.index?.key ?? unknown, value: indexVal },
|
|
9955
|
+
open: true
|
|
9956
|
+
});
|
|
9957
|
+
next.conf = confJoin(o.conf, value.conf);
|
|
9958
|
+
return next;
|
|
7158
9959
|
}
|
|
7159
9960
|
|
|
7160
9961
|
// src/algebra/exec/run.ts
|
|
7161
9962
|
var rtAll = { ...runtime_exports, ...class_exports, ...calls_exports };
|
|
9963
|
+
rtAll.isNudoReturn = isNudoReturn;
|
|
9964
|
+
rtAll.isNudoThrow = isNudoThrow;
|
|
9965
|
+
rtAll.$isForkExit = $isForkExit;
|
|
9966
|
+
rtAll.runWithLoopExits = runWithLoopExits;
|
|
9967
|
+
rtAll.takeLoopExits = takeLoopExits;
|
|
7162
9968
|
var RUNTIME_IMPORT_RE = /^import\s*\{[^}]+\}\s*from\s*"[^"]+";\s*$/m;
|
|
7163
9969
|
function rewriteUserImports(js) {
|
|
7164
9970
|
js = js.replace(
|
|
@@ -7364,33 +10170,59 @@ function isAbsVal(v2) {
|
|
|
7364
10170
|
function callTranspiledExportFull(exports, name, args) {
|
|
7365
10171
|
const fn = exports[name];
|
|
7366
10172
|
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") {
|
|
10173
|
+
return runWithLoopExits(() => {
|
|
7380
10174
|
try {
|
|
7381
|
-
const r =
|
|
7382
|
-
|
|
10175
|
+
const r = fn(...args);
|
|
10176
|
+
if (!isAbsVal(r)) return joinControlExits(unknown);
|
|
10177
|
+
return joinControlExits(r);
|
|
7383
10178
|
} catch (e) {
|
|
10179
|
+
if (isNudoReturn(e)) {
|
|
10180
|
+
return joinControlExits(e.absValue);
|
|
10181
|
+
}
|
|
7384
10182
|
if (isNudoThrow(e)) {
|
|
7385
|
-
|
|
10183
|
+
const result = joinLoopExits(never);
|
|
10184
|
+
const throws = joinThrowExits(e.absValue);
|
|
10185
|
+
return { result, throws };
|
|
7386
10186
|
}
|
|
7387
|
-
return
|
|
10187
|
+
return joinControlExits(unknown);
|
|
7388
10188
|
}
|
|
10189
|
+
});
|
|
10190
|
+
}
|
|
10191
|
+
if (isAbsVal(fn)) {
|
|
10192
|
+
if (fn.shape.k === "fn") {
|
|
10193
|
+
return runWithLoopExits(() => {
|
|
10194
|
+
try {
|
|
10195
|
+
const r = $call(fn, args);
|
|
10196
|
+
return joinControlExits(r);
|
|
10197
|
+
} catch (e) {
|
|
10198
|
+
if (isNudoReturn(e)) {
|
|
10199
|
+
return joinControlExits(e.absValue);
|
|
10200
|
+
}
|
|
10201
|
+
if (isNudoThrow(e)) {
|
|
10202
|
+
return { result: joinLoopExits(never), throws: joinThrowExits(e.absValue) };
|
|
10203
|
+
}
|
|
10204
|
+
return joinControlExits(unknown);
|
|
10205
|
+
}
|
|
10206
|
+
});
|
|
7389
10207
|
}
|
|
7390
10208
|
return { result: fn, throws: never };
|
|
7391
10209
|
}
|
|
7392
10210
|
return { result: unknown, throws: never };
|
|
7393
10211
|
}
|
|
10212
|
+
function joinLoopExits(normal) {
|
|
10213
|
+
const exits = takeLoopExits();
|
|
10214
|
+
if (exits.length === 0) return normal;
|
|
10215
|
+
return exits.reduce((acc, x) => joinAbs(acc, x), normal);
|
|
10216
|
+
}
|
|
10217
|
+
function joinThrowExits(base) {
|
|
10218
|
+
const exits = takeThrowExits();
|
|
10219
|
+
let t = base;
|
|
10220
|
+
for (const x of exits) t = t ? joinAbs(t, x) : x;
|
|
10221
|
+
return t ?? never;
|
|
10222
|
+
}
|
|
10223
|
+
function joinControlExits(normal) {
|
|
10224
|
+
return { result: joinLoopExits(normal), throws: joinThrowExits(void 0) };
|
|
10225
|
+
}
|
|
7394
10226
|
function callTranspiledExport(exports, name, args) {
|
|
7395
10227
|
return callTranspiledExportFull(exports, name, args).result;
|
|
7396
10228
|
}
|
|
@@ -7494,7 +10326,7 @@ export {
|
|
|
7494
10326
|
instantiateReturn,
|
|
7495
10327
|
setApplyCallbackHost,
|
|
7496
10328
|
applyCallbackAbs,
|
|
7497
|
-
undefAbs,
|
|
10329
|
+
undefAbs2 as undefAbs,
|
|
7498
10330
|
mapElementFallback,
|
|
7499
10331
|
projectFlatMapResult,
|
|
7500
10332
|
asAbs,
|
|
@@ -7530,6 +10362,34 @@ export {
|
|
|
7530
10362
|
definitelyNotNullishShape,
|
|
7531
10363
|
isNullishLitAbs,
|
|
7532
10364
|
strictEqAbs,
|
|
10365
|
+
looseEqAbs,
|
|
10366
|
+
pushCollectionArm,
|
|
10367
|
+
popCollectionArm,
|
|
10368
|
+
mergeCollectionArms,
|
|
10369
|
+
beginCollectionFork,
|
|
10370
|
+
noteCollectionWrite,
|
|
10371
|
+
endCollectionFork,
|
|
10372
|
+
isMapAbs,
|
|
10373
|
+
isSetAbs,
|
|
10374
|
+
makeMapAbs,
|
|
10375
|
+
makeSetAbs,
|
|
10376
|
+
mapSetEntry,
|
|
10377
|
+
mapDeleteEntry,
|
|
10378
|
+
mapClearEntries,
|
|
10379
|
+
mapGetEntry,
|
|
10380
|
+
mapHasEntry,
|
|
10381
|
+
mapSizeAbs,
|
|
10382
|
+
mapValuesAbs,
|
|
10383
|
+
mapEntriesAbs,
|
|
10384
|
+
setAddEntry,
|
|
10385
|
+
setDeleteEntry,
|
|
10386
|
+
setClearEntries,
|
|
10387
|
+
setHasEntry,
|
|
10388
|
+
setSizeAbs,
|
|
10389
|
+
setElementsAbs,
|
|
10390
|
+
collectionExactLen,
|
|
10391
|
+
collectionElementJoin,
|
|
10392
|
+
clearCollectionTables,
|
|
7533
10393
|
evalMathMethod,
|
|
7534
10394
|
evalObjectMethod,
|
|
7535
10395
|
evalJsonMethod,
|
|
@@ -7544,6 +10404,8 @@ export {
|
|
|
7544
10404
|
evalPromiseCtor,
|
|
7545
10405
|
evalPromiseStatic,
|
|
7546
10406
|
evalNamespaceCall,
|
|
10407
|
+
isErrorCtorName,
|
|
10408
|
+
errorBrandAbs,
|
|
7547
10409
|
evalBuiltinNew,
|
|
7548
10410
|
evalBuiltinInstanceMethod,
|
|
7549
10411
|
callAbsMethod,
|
|
@@ -7569,6 +10431,7 @@ export {
|
|
|
7569
10431
|
awaitAbs,
|
|
7570
10432
|
coerceAsyncReturn,
|
|
7571
10433
|
classFromMethods,
|
|
10434
|
+
requiredFnArity,
|
|
7572
10435
|
leqAbs,
|
|
7573
10436
|
tagAbsOrigin,
|
|
7574
10437
|
getAbsOrigin,
|
|
@@ -7577,6 +10440,10 @@ export {
|
|
|
7577
10440
|
notePrimMemberMissing,
|
|
7578
10441
|
noteUnknownMemberMissing,
|
|
7579
10442
|
noteMemberDispatchMiss,
|
|
10443
|
+
setEvalMissingSlotEnabled,
|
|
10444
|
+
isEvalMissingSlotEnabled,
|
|
10445
|
+
runWithEvalMissingSlot,
|
|
10446
|
+
noteObjSlotMissing,
|
|
7580
10447
|
registerBClass,
|
|
7581
10448
|
getBClass,
|
|
7582
10449
|
clearBClasses,
|
|
@@ -7618,27 +10485,44 @@ export {
|
|
|
7618
10485
|
$not,
|
|
7619
10486
|
$eq,
|
|
7620
10487
|
$ne,
|
|
10488
|
+
$eqLoose,
|
|
10489
|
+
$neLoose,
|
|
7621
10490
|
$lt,
|
|
7622
10491
|
$le,
|
|
7623
10492
|
$gt,
|
|
7624
10493
|
$ge,
|
|
7625
10494
|
$join,
|
|
7626
10495
|
asAbsVal,
|
|
10496
|
+
callAtFunctionBoundary,
|
|
7627
10497
|
$fnVal,
|
|
7628
10498
|
$lit,
|
|
7629
10499
|
litTruth,
|
|
7630
10500
|
isDefinitelyTrue,
|
|
7631
10501
|
isDefinitelyFalse,
|
|
10502
|
+
runWithLoopExits,
|
|
10503
|
+
takeLoopExits,
|
|
10504
|
+
takeThrowExits,
|
|
10505
|
+
pushLoopExit,
|
|
10506
|
+
pushThrowExit,
|
|
10507
|
+
$pushLoopExit,
|
|
10508
|
+
$tryMark,
|
|
10509
|
+
$tryCurrentMark,
|
|
10510
|
+
$tryPopMark,
|
|
10511
|
+
$tryTakeSince,
|
|
7632
10512
|
$fork,
|
|
7633
10513
|
DEFAULT_MAX_LOOP_ITERS,
|
|
7634
10514
|
$forIter,
|
|
7635
10515
|
$for,
|
|
7636
10516
|
$arr,
|
|
10517
|
+
isArrMutator,
|
|
10518
|
+
$arrMutContainer,
|
|
7637
10519
|
$idx,
|
|
7638
10520
|
$idxSet,
|
|
7639
10521
|
$len,
|
|
7640
10522
|
$obj,
|
|
7641
10523
|
$spread,
|
|
10524
|
+
$objRest,
|
|
10525
|
+
$arrRest,
|
|
7642
10526
|
$concat,
|
|
7643
10527
|
$elems,
|
|
7644
10528
|
$forOf,
|
|
@@ -7648,9 +10532,14 @@ export {
|
|
|
7648
10532
|
$set,
|
|
7649
10533
|
$while,
|
|
7650
10534
|
$whileSeq,
|
|
10535
|
+
NudoReturn,
|
|
10536
|
+
$loopReturn,
|
|
10537
|
+
isNudoReturn,
|
|
10538
|
+
$rethrowIfNudoReturn,
|
|
7651
10539
|
NudoThrow,
|
|
7652
10540
|
$throw,
|
|
7653
10541
|
isNudoThrow,
|
|
10542
|
+
$isForkExit,
|
|
7654
10543
|
$catchVal,
|
|
7655
10544
|
$async,
|
|
7656
10545
|
$await,
|
|
@@ -7658,6 +10547,7 @@ export {
|
|
|
7658
10547
|
$gen,
|
|
7659
10548
|
$yield,
|
|
7660
10549
|
$switch,
|
|
10550
|
+
$nullishTest,
|
|
7661
10551
|
transpileSource,
|
|
7662
10552
|
transpileFile,
|
|
7663
10553
|
transpileExpression,
|