@nudojs/core 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,10 +28,14 @@ function termEquals(a, b) {
28
28
  }
29
29
  return false;
30
30
  }
31
+ function litKeyString(v2) {
32
+ if (typeof v2 === "number" && Object.is(v2, -0)) return "-0";
33
+ return String(v2);
34
+ }
31
35
  function termToString(t) {
32
36
  if (t.op === "lit") {
33
37
  if (typeof t.value === "string") return JSON.stringify(t.value);
34
- if (typeof t.value === "number" && Object.is(t.value, -0)) return "-0";
38
+ if (typeof t.value === "number") return litKeyString(t.value);
35
39
  return String(t.value);
36
40
  }
37
41
  if (t.op === "var") return t.id;
@@ -961,6 +965,42 @@ function leNum(term, n) {
961
965
  return le(term, lit(n));
962
966
  }
963
967
 
968
+ // src/algebra/projection-budget.ts
969
+ var PROJECTION_MAX_DEPTH = 64;
970
+ var ProjectionBudget = class {
971
+ #maxDepth;
972
+ #path = [];
973
+ #onPath = /* @__PURE__ */ new Set();
974
+ /** 粘性:本次投影是否发生过截断("cycle" / "depth"),供台账记录 */
975
+ truncated;
976
+ constructor(maxDepth = PROJECTION_MAX_DEPTH) {
977
+ this.#maxDepth = maxDepth;
978
+ }
979
+ /**
980
+ * 进入一个 Abs(或 Shape)子树。返回 null → 继续递归,之后必须配对
981
+ * `exit()`;返回 "cycle" | "depth" → 不得递归,按出口各自的约定渲染
982
+ * 截断标记(不调用 exit——本次 enter 没有入栈)。
983
+ */
984
+ enter(a) {
985
+ if (this.#onPath.has(a)) {
986
+ this.truncated = "cycle";
987
+ return "cycle";
988
+ }
989
+ if (this.#path.length >= this.#maxDepth) {
990
+ this.truncated = "depth";
991
+ return "depth";
992
+ }
993
+ this.#path.push(a);
994
+ this.#onPath.add(a);
995
+ return null;
996
+ }
997
+ /** 离开子树(与返回 null 的 enter 严格配对)。 */
998
+ exit() {
999
+ const a = this.#path.pop();
1000
+ if (a !== void 0) this.#onPath.delete(a);
1001
+ }
1002
+ };
1003
+
964
1004
  // src/algebra/abs.ts
965
1005
  var never = { shape: { k: "never" }, conf: "exact" };
966
1006
  var unknown = { shape: { k: "unknown" }, conf: "partial" };
@@ -1027,13 +1067,34 @@ function confJoin(a, b) {
1027
1067
  return rank[Math.max(ia < 0 ? 5 : ia, ib < 0 ? 5 : ib)];
1028
1068
  }
1029
1069
  function absToString(a) {
1030
- const parts = [shapeToString(a.shape)];
1031
- if (a.term) parts.push(`term=${termToString(a.term)}`);
1032
- if (a.pred && a.pred.op !== "true") parts.push(predToString(a.pred));
1033
- parts.push(`#${a.conf}`);
1034
- return parts.join(" ");
1070
+ return absToStringB(a, new ProjectionBudget());
1071
+ }
1072
+ function absToStringB(a, budget) {
1073
+ const stop = budget.enter(a);
1074
+ if (stop) return stop === "cycle" ? "\u2026cycle" : "\u2026";
1075
+ try {
1076
+ const parts = [shapeToStringB(a.shape, budget)];
1077
+ if (a.term) parts.push(`term=${termToString(a.term)}`);
1078
+ if (a.pred && a.pred.op !== "true") parts.push(predToString(a.pred));
1079
+ parts.push(`#${a.conf}`);
1080
+ return parts.join(" ");
1081
+ } finally {
1082
+ budget.exit();
1083
+ }
1035
1084
  }
1036
1085
  function shapeToString(s) {
1086
+ return shapeToStringB(s, new ProjectionBudget());
1087
+ }
1088
+ function shapeToStringB(s, budget) {
1089
+ const stop = budget.enter(s);
1090
+ if (stop) return stop === "cycle" ? "\u2026cycle" : "\u2026";
1091
+ try {
1092
+ return shapeToStringInner(s, budget);
1093
+ } finally {
1094
+ budget.exit();
1095
+ }
1096
+ }
1097
+ function shapeToStringInner(s, budget) {
1037
1098
  switch (s.k) {
1038
1099
  case "never":
1039
1100
  return "never";
@@ -1045,22 +1106,22 @@ function shapeToString(s) {
1045
1106
  return s.type;
1046
1107
  case "obj": {
1047
1108
  const entries = Object.entries(s.slots).map(
1048
- ([k, slot]) => `${k}${slot.optional ? "?" : ""}: ${absToString(slot.value)}`
1109
+ ([k, slot]) => `${k}${slot.optional ? "?" : ""}: ${absToStringB(slot.value, budget)}`
1049
1110
  );
1050
1111
  return `{ ${entries.join(", ")} }`;
1051
1112
  }
1052
1113
  case "arr":
1053
- return `${shapeToString(s.element.shape)}[]`;
1114
+ return `${shapeToStringB(s.element.shape, budget)}[]`;
1054
1115
  case "tuple":
1055
- return `[${s.elements.map((e) => shapeToString(e.shape)).join(", ")}]`;
1116
+ return `[${s.elements.map((e) => shapeToStringB(e.shape, budget)).join(", ")}]`;
1056
1117
  case "fn":
1057
1118
  return `fn(${s.params.join(", ")})${s.name ? ` ${s.name}` : ""}`;
1058
1119
  case "brand":
1059
1120
  return s.name;
1060
1121
  case "eff":
1061
- return `${s.eff}<${shapeToString(s.inner.shape)}>`;
1122
+ return `${s.eff}<${shapeToStringB(s.inner.shape, budget)}>`;
1062
1123
  case "sum":
1063
- return s.members.map(absToString).join(" | ");
1124
+ return s.members.map((m) => absToStringB(m, budget)).join(" | ");
1064
1125
  default:
1065
1126
  return "\xB7";
1066
1127
  }
@@ -1352,7 +1413,7 @@ function absFunction(params, impl, opts) {
1352
1413
  return a;
1353
1414
  }
1354
1415
  function termKey2(t) {
1355
- if (t.op === "lit") return `L:${typeof t.value}:${String(t.value)}`;
1416
+ if (t.op === "lit") return `L:${typeof t.value}:${litKeyString(t.value)}`;
1356
1417
  if (t.op === "var") return `V:${t.id}`;
1357
1418
  return `A:${t.fn}(${t.args.map(termKey2).join(",")})`;
1358
1419
  }
@@ -1757,6 +1818,10 @@ function joinValues(a, b) {
1757
1818
  }
1758
1819
  return makeSum(a, b);
1759
1820
  }
1821
+ const hasPred = (x) => !!x.pred && x.pred.op !== "true";
1822
+ if (hasPred(a) || hasPred(b)) {
1823
+ return makeSum(a, b);
1824
+ }
1760
1825
  return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
1761
1826
  }
1762
1827
  return makeSum(a, b);
@@ -1802,7 +1867,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
1802
1867
  try {
1803
1868
  const s = a.shape;
1804
1869
  if (s.k === "prim") {
1805
- if (a.term?.op === "lit") return `prim:${s.type}:${String(a.term.value)}`;
1870
+ if (a.term?.op === "lit") return `prim:${s.type}:${litKeyString(a.term.value)}`;
1806
1871
  const t = a.term ? termToString(a.term) : "";
1807
1872
  const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
1808
1873
  return `prim:${s.type}:${t}:${p}`;
@@ -1814,7 +1879,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
1814
1879
  const v2 = a.term.value;
1815
1880
  if (v2 === void 0) return "unknown:undefined";
1816
1881
  if (v2 === null) return "unknown:null";
1817
- return `unknown:lit:${typeof v2}:${String(v2)}`;
1882
+ return `unknown:lit:${typeof v2}:${litKeyString(v2)}`;
1818
1883
  }
1819
1884
  if (a.term) return `unknown:${termToString(a.term)}`;
1820
1885
  return "unknown";
@@ -2487,7 +2552,7 @@ function bindTypeVars(pattern, arg, map, depth = 0) {
2487
2552
  }
2488
2553
  if (ps.k === "obj" && as.k === "obj") {
2489
2554
  for (const [key, slot] of Object.entries(ps.slots)) {
2490
- const aSlot = as.slots[key];
2555
+ const aSlot = getSlot(as.slots, key);
2491
2556
  if (aSlot) bindTypeVars(slot.value, aSlot.value, map, depth + 1);
2492
2557
  }
2493
2558
  return;
@@ -3734,1017 +3799,1517 @@ function migrateInvariants(from, to) {
3734
3799
  if (f) propFlagsTable.set(to, new Map(f));
3735
3800
  }
3736
3801
 
3737
- // src/algebra/builtins/shared.ts
3738
- var noBody = { type: "BlockStatement", body: [], directives: [] };
3739
- function numPrim(conf = "path") {
3740
- return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
3741
- }
3742
- function str2(conf = "path") {
3743
- return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
3802
+ // src/algebra/exec/runtime/state.ts
3803
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
3804
+
3805
+ // src/algebra/containers.ts
3806
+ var TUPLE_LITERAL_CAP = 8;
3807
+ function shouldWidenArrayLiteral(n) {
3808
+ return n > TUPLE_LITERAL_CAP;
3744
3809
  }
3745
- function boolPrim(conf = "partial") {
3746
- return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
3810
+ var TUPLE_MATERIALIZE_CAP = 4096;
3811
+ function widenedArrayConf() {
3812
+ return "path";
3747
3813
  }
3748
- function peelBrand(shape) {
3749
- let s = shape;
3750
- while (s.k === "brand") s = s.shape.shape;
3751
- return s;
3814
+
3815
+ // src/algebra/exec/runtime/state.ts
3816
+ function writeInPlace(target, next) {
3817
+ target.shape = next.shape;
3818
+ target.conf = next.conf;
3819
+ target.term = void 0;
3820
+ target.pred = void 0;
3821
+ return target;
3752
3822
  }
3753
- function isPrimLike(a) {
3754
- if (!a) return true;
3755
- if (a.shape.k === "prim" || a.shape.k === "never") return true;
3756
- if (a.term?.op === "lit" && (a.term.value === null || a.term.value === void 0)) {
3757
- return true;
3758
- }
3759
- return false;
3823
+ function clearStaleTermPred(v2) {
3824
+ v2.term = void 0;
3825
+ v2.pred = void 0;
3760
3826
  }
3761
-
3762
- // src/algebra/builtins/math.ts
3763
- function coerceMathArg(a) {
3764
- if (!a || a.term?.op !== "lit") return void 0;
3765
- const v2 = a.term.value;
3766
- if (typeof v2 === "number") return v2;
3767
- if (typeof v2 === "string") return Number(v2);
3768
- if (typeof v2 === "boolean") return v2 ? 1 : 0;
3769
- if (v2 === null) return 0;
3770
- if (v2 === void 0) return void 0;
3771
- return "throw";
3827
+ var phi = pTrue;
3828
+ function currentExecPhi() {
3829
+ return phi;
3772
3830
  }
3773
- function mathMethod(name) {
3774
- if (!Object.hasOwn(Math, name)) return void 0;
3775
- const impl = Math[name];
3776
- return typeof impl === "function" ? impl : void 0;
3831
+ function withExecPhi(p, body) {
3832
+ const prev = phi;
3833
+ phi = p;
3834
+ try {
3835
+ return body();
3836
+ } finally {
3837
+ phi = prev;
3838
+ }
3777
3839
  }
3778
- function evalMathMethod(name, args) {
3779
- if (name === "random") return numPrim("path");
3780
- const impl = mathMethod(name);
3781
- if (!impl) return void 0;
3782
- const nums = [];
3783
- for (const a of args) {
3784
- const n = coerceMathArg(a);
3785
- if (n === void 0) return numPrim();
3786
- if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
3787
- nums.push(n);
3840
+ var noBody = { type: "BlockStatement", body: [], directives: [] };
3841
+ function asAbsVal(v2) {
3842
+ if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
3843
+ if (typeof v2 === "function") {
3844
+ const n = Math.max(0, v2.length);
3845
+ const params = Array.from({ length: n }, (_, i) => `arg${i}`);
3846
+ return absFunction(params, {
3847
+ body: noBody,
3848
+ // 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
3849
+ apply: (args) => callAtFunctionBoundary(() => v2(...args))
3850
+ });
3788
3851
  }
3852
+ return $lit(v2);
3853
+ }
3854
+ function callAtFunctionBoundary(body) {
3855
+ let forwarded = [];
3789
3856
  try {
3790
- return numLit(impl(...nums));
3791
- } catch {
3792
- return numPrim();
3857
+ return runWithLoopExits(() => {
3858
+ try {
3859
+ const r = body();
3860
+ forwarded = takeThrowExits();
3861
+ return r;
3862
+ } catch (e) {
3863
+ forwarded = takeThrowExits();
3864
+ if (isNudoReturn(e)) return e.absValue;
3865
+ throw e;
3866
+ }
3867
+ });
3868
+ } finally {
3869
+ for (const x of forwarded) pushThrowExit(x);
3793
3870
  }
3794
3871
  }
3795
-
3796
- // src/algebra/class-mark.ts
3797
- var classValues = /* @__PURE__ */ new WeakMap();
3798
- function markClassValue(v2, name) {
3799
- classValues.set(v2, name);
3872
+ function $fnVal(params, impl, opts) {
3873
+ return absFunction(params, {
3874
+ body: noBody,
3875
+ // bindThis(对象方法):receiver 走首参注入,无宿主 this;
3876
+ // 非方法 fn:宿主 this 传递(call/apply/bind 的 thisArg 经 $rawThis 进入函数体)
3877
+ apply: opts?.bindThis ? (args) => callAtFunctionBoundary(() => impl(...args)) : (args, thisVal) => callAtFunctionBoundary(() => impl.apply(thisVal, args)),
3878
+ ...opts?.bindThis ? { bindThis: true } : {}
3879
+ });
3800
3880
  }
3801
- function classNameOfValue(v2) {
3802
- return classValues.get(v2);
3881
+ function $rawThis(v2) {
3882
+ if (v2 === void 0 || v2 === globalThis) return $lit(void 0);
3883
+ if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
3884
+ return $lit(v2);
3803
3885
  }
3804
-
3805
- // src/algebra/builtins/ctor.ts
3806
- var builtinCtorByName = /* @__PURE__ */ new Map();
3807
- var builtinCtorByAbs = /* @__PURE__ */ new WeakMap();
3808
- function builtinCtorAbs(name) {
3809
- let a = builtinCtorByName.get(name);
3810
- if (!a) {
3811
- a = abs(
3812
- { k: "brand", name, shape: objOf({ name: { value: strLit(name) } }) },
3813
- void 0,
3814
- void 0,
3815
- "exact"
3816
- );
3817
- markClassValue(a, name);
3818
- builtinCtorByName.set(name, a);
3819
- builtinCtorByAbs.set(a, name);
3820
- }
3821
- return a;
3886
+ function throwStrictWrite() {
3887
+ throw new NudoThrow(errorTypeAbs("TypeError"));
3822
3888
  }
3823
- function builtinCtorNameOf(v2) {
3824
- if (!v2 || typeof v2 !== "object") return void 0;
3825
- return builtinCtorByAbs.get(v2);
3889
+ function $throwConstAssign() {
3890
+ throw new NudoThrow(errorTypeAbs("TypeError"));
3826
3891
  }
3827
- function hostBuiltinCtorName(v2) {
3828
- if (typeof v2 !== "function") return void 0;
3829
- if (v2 === Number) return "Number";
3830
- if (v2 === String) return "String";
3831
- if (v2 === Boolean) return "Boolean";
3832
- if (v2 === BigInt) return "BigInt";
3833
- if (v2 === Symbol) return "Symbol";
3834
- if (v2 === Array) return "Array";
3835
- if (v2 === Object) return "Object";
3836
- if (v2 === Function) return "Function";
3837
- if (v2 === Promise) return "Promise";
3838
- if (v2 === Date) return "Date";
3839
- if (v2 === RegExp) return "RegExp";
3840
- if (v2 === Map) return "Map";
3841
- if (v2 === Set) return "Set";
3842
- if (v2 === WeakMap) return "WeakMap";
3843
- if (v2 === WeakSet) return "WeakSet";
3844
- if (v2 === Error) return "Error";
3845
- if (v2 === TypeError) return "TypeError";
3846
- if (v2 === RangeError) return "RangeError";
3847
- if (v2 === ReferenceError) return "ReferenceError";
3848
- if (v2 === SyntaxError) return "SyntaxError";
3849
- if (v2 === URIError) return "URIError";
3850
- if (v2 === EvalError) return "EvalError";
3851
- if (v2 === AggregateError) return "AggregateError";
3852
- return void 0;
3892
+ function $litTruth(a) {
3893
+ return litTruth(a);
3853
3894
  }
3854
- function ctorNameOfRecv(recv) {
3855
- const s = recv.shape;
3856
- switch (s.k) {
3857
- case "prim":
3858
- return s.type === "number" ? "Number" : s.type === "string" ? "String" : s.type === "boolean" ? "Boolean" : s.type === "bigint" ? "BigInt" : s.type === "symbol" ? "Symbol" : void 0;
3859
- case "tuple":
3860
- case "arr":
3861
- return "Array";
3862
- case "obj":
3863
- return isNullProtoObj(recv) ? void 0 : "Object";
3864
- case "fn":
3865
- return "Function";
3866
- case "eff":
3867
- return s.eff === "promise" ? "Promise" : "Generator";
3868
- case "brand": {
3869
- if (s.name === "Object.prototype") return "Object";
3870
- if (s.name.endsWith(".prototype")) return s.name.slice(0, -".prototype".length);
3871
- return s.name;
3872
- }
3873
- case "sum": {
3874
- let first;
3875
- for (const m of s.members) {
3876
- const n = ctorNameOfRecv(m);
3877
- if (n === void 0) return void 0;
3878
- if (first === void 0) first = n;
3879
- else if (first !== n) return void 0;
3880
- }
3881
- return first;
3882
- }
3883
- default:
3884
- return void 0;
3895
+ function $lit(v2) {
3896
+ if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
3897
+ return v2;
3885
3898
  }
3899
+ return litAbsFromJs(v2);
3886
3900
  }
3887
- function protoBrandAbs(ctorName) {
3888
- return abs(
3889
- {
3890
- k: "brand",
3891
- name: `${ctorName}.prototype`,
3892
- shape: objOf({ constructor: { value: builtinCtorAbs(ctorName) } })
3893
- },
3894
- void 0,
3895
- void 0,
3896
- "exact"
3897
- );
3898
- }
3899
- function protoOfRecv(a) {
3900
- const s = a.shape;
3901
- const nullProtoLit = abs(
3902
- { k: "unknown" },
3903
- { op: "lit", value: null },
3904
- pTrue,
3905
- "exact"
3906
- );
3907
- if (s.k === "tuple" || s.k === "arr") return protoBrandAbs("Array");
3908
- if (s.k === "prim") {
3909
- const ctor = s.type === "number" ? "Number" : s.type === "string" ? "String" : s.type === "boolean" ? "Boolean" : s.type === "bigint" ? "BigInt" : s.type === "symbol" ? "Symbol" : void 0;
3910
- return ctor ? protoBrandAbs(ctor) : unknown;
3901
+ function litAbsFromJs(v2, depth = 0) {
3902
+ if (v2 === null || v2 === void 0) {
3903
+ return abs({ k: "unknown" }, { op: "lit", value: v2 }, pTrue, "exact");
3911
3904
  }
3912
- if (s.k === "fn") return protoBrandAbs("Function");
3913
- if (s.k === "eff" && s.eff === "promise") return protoBrandAbs("Promise");
3914
- if (s.k === "brand") {
3915
- if (s.name === "Object.prototype") return nullProtoLit;
3916
- if (s.name.endsWith(".prototype")) return objectProtoBrand();
3917
- return protoBrandAbs(s.name);
3905
+ const t = typeof v2;
3906
+ if (t === "number" || t === "string" || t === "boolean" || t === "bigint") {
3907
+ return abs(
3908
+ { k: "prim", type: t },
3909
+ { op: "lit", value: v2 },
3910
+ pTrue,
3911
+ "exact"
3912
+ );
3918
3913
  }
3919
- if (s.k === "obj") {
3920
- if (isNullProtoObj(a)) return nullProtoLit;
3921
- return objectProtoBrand();
3914
+ if (depth < 8) {
3915
+ if (Array.isArray(v2)) {
3916
+ const els = v2.map((x) => litAbsFromJs(x, depth + 1));
3917
+ if (shouldWidenArrayLiteral(els.length)) {
3918
+ return abs(
3919
+ { k: "arr", element: els.reduce((x, y) => joinAbs(x, y)) },
3920
+ void 0,
3921
+ void 0,
3922
+ widenedArrayConf()
3923
+ );
3924
+ }
3925
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
3926
+ }
3927
+ if (t === "object") {
3928
+ const proto = Object.getPrototypeOf(v2);
3929
+ if (proto === Object.prototype || proto === null) {
3930
+ const slots = {};
3931
+ for (const [k, val] of Object.entries(v2)) {
3932
+ Object.defineProperty(slots, k, {
3933
+ value: { value: litAbsFromJs(val, depth + 1) },
3934
+ enumerable: true,
3935
+ writable: true,
3936
+ configurable: true
3937
+ });
3938
+ }
3939
+ return objOf(slots);
3940
+ }
3941
+ }
3922
3942
  }
3923
3943
  return unknown;
3924
3944
  }
3925
- var OBJECT_PROTO_METHOD_NAMES = /* @__PURE__ */ new Set([
3926
- "hasOwnProperty",
3927
- "isPrototypeOf",
3928
- "propertyIsEnumerable",
3929
- "valueOf",
3930
- "toString",
3931
- "toLocaleString"
3932
- ]);
3933
- var objectProtoSingleton;
3934
- function objectProtoBrand() {
3935
- if (!objectProtoSingleton) {
3936
- const a = abs(
3937
- {
3938
- k: "brand",
3939
- name: "Object.prototype",
3940
- shape: objOf({ constructor: { value: builtinCtorAbs("Object") } })
3941
- },
3942
- void 0,
3943
- void 0,
3944
- "exact"
3945
- );
3946
- setPropFlags(a, "constructor", { enumerable: false, writable: true, configurable: true });
3947
- objectProtoSingleton = a;
3945
+ function litTruth(a) {
3946
+ if (a.term?.op === "lit") {
3947
+ return Boolean(a.term.value);
3948
+ }
3949
+ switch (a.shape.k) {
3950
+ case "obj":
3951
+ case "arr":
3952
+ case "tuple":
3953
+ case "fn":
3954
+ case "brand":
3955
+ case "eff":
3956
+ return true;
3957
+ case "prim":
3958
+ return a.shape.type === "symbol" ? true : void 0;
3959
+ case "never":
3960
+ return false;
3961
+ default:
3962
+ return void 0;
3948
3963
  }
3949
- return objectProtoSingleton;
3950
3964
  }
3951
- function isObjectProtoBrand(a) {
3952
- return !!a && a.shape.k === "brand" && a.shape.name === "Object.prototype";
3965
+ function isDefinitelyTrue(a) {
3966
+ return litTruth(a) === true;
3953
3967
  }
3954
-
3955
- // src/algebra/containers.ts
3956
- var TUPLE_LITERAL_CAP = 8;
3957
- function shouldWidenArrayLiteral(n) {
3958
- return n > TUPLE_LITERAL_CAP;
3968
+ function isDefinitelyFalse(a) {
3969
+ const t = litTruth(a);
3970
+ if (t === false) return true;
3971
+ if (a.shape.k === "never") return true;
3972
+ return false;
3959
3973
  }
3960
- var TUPLE_MATERIALIZE_CAP = 4096;
3961
- function widenedArrayConf() {
3962
- return "path";
3974
+ function undef() {
3975
+ return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
3963
3976
  }
3964
-
3965
- // src/algebra/builtins/object.ts
3966
- function assignSourceSlots(src) {
3967
- const s = src.shape;
3968
- if (s.k === "tuple") {
3969
- const holes = s.holes ?? [];
3970
- const slots = {};
3971
- for (let i = 0; i < s.elements.length; i++) {
3972
- if (!holes.includes(i)) slots[String(i)] = { value: s.elements[i] };
3973
- }
3974
- return slots;
3977
+ var loopExitsAls = new AsyncLocalStorage2();
3978
+ var throwExitsAls = new AsyncLocalStorage2();
3979
+ var tryMarksAls = new AsyncLocalStorage2();
3980
+ var softFrameActiveAls = new AsyncLocalStorage2();
3981
+ function runWithLoopExits(body) {
3982
+ return loopExitsAls.run(
3983
+ [],
3984
+ () => throwExitsAls.run(
3985
+ [],
3986
+ () => tryMarksAls.run([], () => softFrameActiveAls.run([], body))
3987
+ )
3988
+ );
3989
+ }
3990
+ function takeLoopExits() {
3991
+ return loopExitsAls.getStore() ?? [];
3992
+ }
3993
+ function takeThrowExits() {
3994
+ return throwExitsAls.getStore() ?? [];
3995
+ }
3996
+ function pushLoopExit(v2) {
3997
+ loopExitsAls.getStore()?.push(v2);
3998
+ }
3999
+ function pushThrowExit(v2) {
4000
+ throwExitsAls.getStore()?.push(v2);
4001
+ }
4002
+ function $pushLoopExit(v2) {
4003
+ pushLoopExit(v2);
4004
+ }
4005
+ function $tryMark() {
4006
+ $tryMarkSoft();
4007
+ softFrameActiveAls.getStore()?.push(true);
4008
+ const store = throwExitsAls.getStore();
4009
+ const m = store?.length ?? 0;
4010
+ tryMarksAls.getStore()?.push(m);
4011
+ return m;
4012
+ }
4013
+ function $tryCurrentMark() {
4014
+ const stack = tryMarksAls.getStore();
4015
+ return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
4016
+ }
4017
+ function $tryPopMark() {
4018
+ tryMarksAls.getStore()?.pop();
4019
+ const soft = softFrameActiveAls.getStore();
4020
+ if (soft && soft.length > 0) {
4021
+ if (soft[soft.length - 1]) $tryReleaseSoftOut();
4022
+ soft.pop();
3975
4023
  }
3976
- if (src.term?.op === "lit" && typeof src.term.value === "string") {
3977
- const v2 = src.term.value;
3978
- const slots = {};
3979
- for (let i = 0; i < v2.length; i++) slots[String(i)] = { value: strLit(v2[i]) };
3980
- return slots;
4024
+ }
4025
+ function $tryTakeSince(mark) {
4026
+ const store = throwExitsAls.getStore();
4027
+ if (!store) return [];
4028
+ return store.splice(Math.min(mark, store.length));
4029
+ }
4030
+ function peekThrowExitsSince(mark) {
4031
+ const store = throwExitsAls.getStore();
4032
+ if (!store) return [];
4033
+ return store.slice(Math.min(mark, store.length));
4034
+ }
4035
+ function throwExitsMark() {
4036
+ return throwExitsAls.getStore()?.length ?? 0;
4037
+ }
4038
+ function $tryDigestSoftCatch() {
4039
+ const soft = softFrameActiveAls.getStore();
4040
+ if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
4041
+ $tryDigestSoft();
4042
+ soft[soft.length - 1] = false;
4043
+ }
4044
+ function $tryReleaseSoftCatch() {
4045
+ const soft = softFrameActiveAls.getStore();
4046
+ if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
4047
+ $tryReleaseSoft();
4048
+ soft[soft.length - 1] = false;
4049
+ }
4050
+ function $tryDetachSoftCatch() {
4051
+ const soft = softFrameActiveAls.getStore();
4052
+ if (!soft || soft.length === 0 || !soft[soft.length - 1]) return [];
4053
+ const effects = popMayThrowFrame(false);
4054
+ soft[soft.length - 1] = false;
4055
+ return effects;
4056
+ }
4057
+ function $tryDiscardSoft(_effects) {
4058
+ }
4059
+ function $tryOrphanSoft(effects) {
4060
+ orphanMayThrowEffects(effects);
4061
+ }
4062
+ function $tryReleaseSoftOut() {
4063
+ const soft = softFrameActiveAls.getStore();
4064
+ if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
4065
+ $tryReleaseSoft();
4066
+ soft[soft.length - 1] = false;
4067
+ }
4068
+ var NudoReturn = class extends Error {
4069
+ absValue;
4070
+ constructor(absValue) {
4071
+ super("nudo:return");
4072
+ this.name = "NudoReturn";
4073
+ this.absValue = absValue;
3981
4074
  }
3982
- if (s.k === "brand" && s.name === "String") {
3983
- const inner = s.shape;
3984
- if (inner.shape.k === "obj") {
3985
- const slots = {};
3986
- for (const [k, v2] of Object.entries(inner.shape.slots)) {
3987
- if (k === "length") continue;
3988
- setSlot(slots, k, v2);
3989
- }
3990
- if (Object.keys(slots).length > 0 || !inner.shape.open) return slots;
3991
- }
3992
- return void 0;
4075
+ };
4076
+ function isNudoReturn(e) {
4077
+ return e instanceof NudoReturn;
4078
+ }
4079
+ function $loopReturn(v2) {
4080
+ throw new NudoReturn(v2);
4081
+ }
4082
+ var NudoLoopSignal = class extends Error {
4083
+ kind;
4084
+ label;
4085
+ constructor(kind, label) {
4086
+ super("nudo:loop");
4087
+ this.name = "NudoLoopSignal";
4088
+ this.kind = kind;
4089
+ this.label = label;
3993
4090
  }
3994
- if (s.k === "prim") return s.type === "string" ? void 0 : {};
3995
- if (s.k === "eff" || s.k === "never") return {};
3996
- return void 0;
4091
+ };
4092
+ function $loopBreak(label) {
4093
+ throw new NudoLoopSignal("break", label || void 0);
3997
4094
  }
3998
- function evalObjectMethod(name, args) {
3999
- const a0 = args[0];
4000
- const enumKeys = (slots, target) => {
4001
- const flags = getPropFlags(target);
4002
- return Object.keys(slots).filter(
4003
- (k) => flags?.get(k)?.enumerable !== false
4004
- );
4005
- };
4006
- switch (name) {
4007
- case "create": {
4008
- if (a0 === void 0 || a0.term?.op === "lit" && a0.term.value === void 0) {
4009
- throw new NudoThrow(errorTypeAbs("TypeError"));
4010
- }
4011
- const protoVR = litValue(a0);
4012
- const protoV = protoVR.ok ? protoVR.value : void 0;
4013
- if (protoV === null) return markNullProtoObj(abs({ k: "obj", slots: {} }, void 0, void 0, "exact"));
4014
- if (typeof protoV === "object") {
4015
- return abs({ k: "obj", slots: {} }, void 0, void 0, "path");
4016
- }
4017
- if (a0.term?.op === "lit") {
4018
- throw new NudoThrow(errorTypeAbs("TypeError"));
4019
- }
4020
- return void 0;
4095
+ function $loopContinue(label) {
4096
+ throw new NudoLoopSignal("continue", label || void 0);
4097
+ }
4098
+ function loopSignalMatches(e, label) {
4099
+ return e.label === void 0 || e.label === label;
4100
+ }
4101
+ function isNudoBreak(e, label) {
4102
+ return e instanceof NudoLoopSignal && e.kind === "break" && loopSignalMatches(e, label);
4103
+ }
4104
+ function isNudoContinue(e, label) {
4105
+ return e instanceof NudoLoopSignal && e.kind === "continue" && loopSignalMatches(e, label);
4106
+ }
4107
+ function $isBreakTo(e, label) {
4108
+ return e instanceof NudoLoopSignal && e.kind === "break" && e.label === label;
4109
+ }
4110
+ function $rethrowIfNudoReturn(e) {
4111
+ if (isNudoReturn(e)) throw e;
4112
+ }
4113
+
4114
+ // src/algebra/builtins/shared.ts
4115
+ var noBody2 = { type: "BlockStatement", body: [], directives: [] };
4116
+ function numPrim(conf = "path") {
4117
+ return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
4118
+ }
4119
+ function str2(conf = "path") {
4120
+ return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
4121
+ }
4122
+ function boolPrim(conf = "partial") {
4123
+ return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
4124
+ }
4125
+ function peelBrand(shape) {
4126
+ let s = shape;
4127
+ while (s.k === "brand") s = s.shape.shape;
4128
+ return s;
4129
+ }
4130
+ function isPrimLike(a) {
4131
+ if (!a) return true;
4132
+ if (a.shape.k === "prim" || a.shape.k === "never") return true;
4133
+ if (a.term?.op === "lit" && (a.term.value === null || a.term.value === void 0)) {
4134
+ return true;
4135
+ }
4136
+ return false;
4137
+ }
4138
+
4139
+ // src/algebra/builtins/math.ts
4140
+ function coerceMathArg(a) {
4141
+ if (!a || a.term?.op !== "lit") return void 0;
4142
+ const v2 = a.term.value;
4143
+ if (typeof v2 === "number") return v2;
4144
+ if (typeof v2 === "string") return Number(v2);
4145
+ if (typeof v2 === "boolean") return v2 ? 1 : 0;
4146
+ if (v2 === null) return 0;
4147
+ if (v2 === void 0) return void 0;
4148
+ return "throw";
4149
+ }
4150
+ function mathMethod(name) {
4151
+ if (!Object.hasOwn(Math, name)) return void 0;
4152
+ const impl = Math[name];
4153
+ return typeof impl === "function" ? impl : void 0;
4154
+ }
4155
+ function isNonNaN(a, phi2) {
4156
+ if (a.term?.op === "lit") {
4157
+ return typeof a.term.value === "number" && !Number.isNaN(a.term.value);
4158
+ }
4159
+ const hasNonNaNFact = (p) => {
4160
+ if (!p) return false;
4161
+ if (p.op === "and") return p.args.some(hasNonNaNFact);
4162
+ if (p.op === "assumeFinite") {
4163
+ return !!a.term && termEquals(p.t, a.term);
4021
4164
  }
4022
- case "keys": {
4023
- if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4024
- throw new NudoThrow(errorTypeAbs("TypeError"));
4025
- }
4026
- if (a0?.shape.k === "obj") {
4027
- const keys = enumKeys(
4028
- a0.shape.slots,
4029
- a0
4030
- ).map((k) => strLit(k));
4031
- return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
4032
- }
4033
- if (a0?.shape.k === "tuple") {
4034
- const holes = a0.shape.holes ?? [];
4035
- const keys = a0.shape.elements.map((_, i) => i).filter((i) => !holes.includes(i)).map((i) => strLit(String(i)));
4036
- return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
4037
- }
4038
- if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4039
- const s = a0.term.value;
4040
- return abs(
4041
- { k: "tuple", elements: Array.from({ length: s.length }, (_, i) => strLit(String(i))) },
4042
- void 0,
4043
- void 0,
4044
- "exact"
4045
- );
4046
- }
4047
- if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4048
- return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4165
+ if (p.op === "ne") {
4166
+ if (p.b.op === "lit" && typeof p.b.value === "number" && Number.isNaN(p.b.value) && a.term && termEquals(p.a, a.term)) {
4167
+ return true;
4049
4168
  }
4050
- return abs({ k: "arr", element: str2("path") }, void 0, void 0, "partial");
4051
4169
  }
4052
- case "values": {
4053
- if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4054
- throw new NudoThrow(errorTypeAbs("TypeError"));
4055
- }
4056
- if (a0?.shape.k === "obj") {
4057
- const slots = a0.shape.slots;
4058
- const vals = enumKeys(slots, a0).map((k) => slots[k].value);
4059
- return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
4060
- }
4061
- if (a0?.shape.k === "tuple") {
4062
- const holes = a0.shape.holes ?? [];
4063
- return abs(
4064
- {
4065
- k: "tuple",
4066
- elements: a0.shape.elements.filter((_, i) => !holes.includes(i))
4067
- },
4068
- void 0,
4069
- void 0,
4070
- a0.conf
4071
- );
4072
- }
4073
- if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4074
- const s = a0.term.value;
4075
- return abs(
4076
- {
4077
- k: "tuple",
4078
- elements: Array.from({ length: s.length }, (_, i) => strLit(s[i]))
4079
- },
4080
- void 0,
4081
- void 0,
4082
- "exact"
4083
- );
4084
- }
4085
- if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4086
- return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4087
- }
4088
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4170
+ if (p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") {
4171
+ if (a.term && (termEquals(p.a, a.term) || termEquals(p.b, a.term))) return true;
4089
4172
  }
4090
- case "entries": {
4091
- if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4092
- throw new NudoThrow(errorTypeAbs("TypeError"));
4093
- }
4094
- if (a0?.shape.k === "obj") {
4095
- const slots = a0.shape.slots;
4096
- const entries = enumKeys(slots, a0).map(
4097
- (k) => abs({ k: "tuple", elements: [strLit(k), slots[k].value] }, void 0, void 0, "exact")
4098
- );
4099
- return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
4100
- }
4101
- if (a0?.shape.k === "tuple") {
4102
- const holes = a0.shape.holes ?? [];
4103
- const entries = a0.shape.elements.map((el, i) => ({ el, i })).filter(({ i }) => !holes.includes(i)).map(
4104
- ({ el, i }) => abs({ k: "tuple", elements: [strLit(String(i)), el] }, void 0, void 0, "exact")
4105
- );
4106
- return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
4173
+ return false;
4174
+ };
4175
+ if (hasNonNaNFact(a.pred)) return true;
4176
+ if (a.term?.op === "var") {
4177
+ const id = a.term.id;
4178
+ const conjs = phi2.op === "and" ? phi2.args : [phi2];
4179
+ for (const p of conjs) {
4180
+ if (p.op === "assumeFinite" && p.t.op === "var" && p.t.id === id) {
4181
+ return true;
4107
4182
  }
4108
- if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4109
- const s = a0.term.value;
4110
- return abs(
4111
- {
4112
- k: "tuple",
4113
- elements: Array.from(
4114
- { length: s.length },
4115
- (_, i) => abs({ k: "tuple", elements: [strLit(String(i)), strLit(s[i])] }, void 0, void 0, "exact")
4116
- )
4117
- },
4118
- void 0,
4119
- void 0,
4120
- "exact"
4121
- );
4183
+ if (p.op === "ne") {
4184
+ const b = p.b;
4185
+ if (b.op === "lit" && typeof b.value === "number" && Number.isNaN(b.value) && p.a.op === "var" && p.a.id === id) {
4186
+ return true;
4187
+ }
4122
4188
  }
4123
- if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4124
- return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4189
+ if (p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") {
4190
+ const sides = [p.a, p.b];
4191
+ if (sides.some((t) => t.op === "var" && t.id === id) && sides.some((t) => t.op === "lit" && typeof t.value === "number")) {
4192
+ return true;
4193
+ }
4125
4194
  }
4126
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4127
4195
  }
4128
- case "hasOwn": {
4129
- if (!a0) return boolPrim();
4130
- if (a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4131
- throw new NudoThrow(errorTypeAbs("TypeError"));
4132
- }
4133
- const keyR = args[1] ? litValue(args[1]) : void 0;
4134
- const key = keyR?.ok ? keyR.value : void 0;
4135
- if (typeof key !== "string") return boolPrim();
4136
- if (a0.shape.k === "obj") {
4137
- const shape = a0.shape;
4138
- if (Object.prototype.hasOwnProperty.call(shape.slots, key)) return boolLit(true);
4139
- if (!shape.open && a0.conf === "exact") return boolLit(false);
4140
- return boolPrim();
4141
- }
4142
- return boolPrim();
4196
+ }
4197
+ return false;
4198
+ }
4199
+ function ieeeBoundNum(n) {
4200
+ return Number.isFinite(n) || n === Infinity || n === -Infinity ? n : void 0;
4201
+ }
4202
+ function loMin(a, b) {
4203
+ if (a.lo === void 0 || b.lo === void 0) return void 0;
4204
+ if (b.lo.value < a.lo.value) return b.lo;
4205
+ if (b.lo.value === a.lo.value && b.lo.strict && !a.lo.strict) return b.lo;
4206
+ return a.lo;
4207
+ }
4208
+ function loMax(a, b) {
4209
+ if (a.lo === void 0) return b.lo;
4210
+ if (b.lo === void 0) return a.lo;
4211
+ if (b.lo.value > a.lo.value) return b.lo;
4212
+ if (b.lo.value === a.lo.value && b.lo.strict && !a.lo.strict) return b.lo;
4213
+ return a.lo;
4214
+ }
4215
+ function hiMin(a, b) {
4216
+ if (a.hi === void 0) return b.hi;
4217
+ if (b.hi === void 0) return a.hi;
4218
+ if (b.hi.value < a.hi.value) return b.hi;
4219
+ if (b.hi.value === a.hi.value && b.hi.strict && !a.hi.strict) return b.hi;
4220
+ return a.hi;
4221
+ }
4222
+ function hiMax(a, b) {
4223
+ if (a.hi === void 0 || b.hi === void 0) return void 0;
4224
+ if (b.hi.value > a.hi.value) return b.hi;
4225
+ if (b.hi.value === a.hi.value && b.hi.strict && !a.hi.strict) return b.hi;
4226
+ return a.hi;
4227
+ }
4228
+ function boundsToPred(t, b) {
4229
+ const facts = [];
4230
+ if (b.lo !== void 0) {
4231
+ const v2 = ieeeBoundNum(b.lo.value);
4232
+ if (v2 !== void 0) {
4233
+ facts.push(b.lo.strict ? { op: "gt", a: t, b: lit(v2) } : { op: "ge", a: t, b: lit(v2) });
4143
4234
  }
4144
- case "getPrototypeOf": {
4145
- if (!a0) return unknown;
4146
- if (a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4147
- throw new NudoThrow(errorTypeAbs("TypeError"));
4148
- }
4149
- return protoOfRecv(a0);
4235
+ }
4236
+ if (b.hi !== void 0) {
4237
+ const v2 = ieeeBoundNum(b.hi.value);
4238
+ if (v2 !== void 0) {
4239
+ facts.push(b.hi.strict ? { op: "lt", a: t, b: lit(v2) } : { op: "le", a: t, b: lit(v2) });
4150
4240
  }
4151
- case "setPrototypeOf": {
4152
- if (!args.length) {
4153
- throw new NudoThrow(errorTypeAbs("TypeError"));
4154
- }
4155
- const t0 = args[0];
4156
- const p0 = args[1];
4157
- if (!t0 || !p0) {
4158
- throw new NudoThrow(errorTypeAbs("TypeError"));
4241
+ }
4242
+ if (facts.length === 0) return void 0;
4243
+ return facts.length === 1 ? facts[0] : and(...facts);
4244
+ }
4245
+ function minMaxAbs(name, args) {
4246
+ const phi2 = currentExecPhi();
4247
+ const empty = {};
4248
+ let acc = empty;
4249
+ const termArgs = args.map(
4250
+ (a, i) => a.term ?? app(`arg${i}`, [])
4251
+ );
4252
+ const term = simplifyTerm(app(`Math.${name}`, termArgs));
4253
+ let first = true;
4254
+ let mayNaN = false;
4255
+ for (const a of args) {
4256
+ if (!isNonNaN(a, phi2)) mayNaN = true;
4257
+ const b = numericBounds(a, phi2) ?? {};
4258
+ if (first) {
4259
+ acc = { lo: b.lo, hi: b.hi };
4260
+ first = false;
4261
+ continue;
4262
+ }
4263
+ if (name === "min") {
4264
+ acc = { lo: loMin(acc, b), hi: hiMin(acc, b) };
4265
+ } else {
4266
+ acc = { lo: loMax(acc, b), hi: hiMax(acc, b) };
4267
+ }
4268
+ }
4269
+ const pred = boundsToPred(term, acc);
4270
+ const bounded = abs({ k: "prim", type: "number" }, term, pred, "path");
4271
+ if (!mayNaN) return bounded;
4272
+ const nanArm = numLit(NaN);
4273
+ return makeSum(nanArm, bounded);
4274
+ }
4275
+ function roundingAbs(name, arg) {
4276
+ const phi2 = currentExecPhi();
4277
+ const impl = name === "round" ? Math.round : name === "floor" ? Math.floor : name === "ceil" ? Math.ceil : Math.trunc;
4278
+ const b = numericBounds(arg, phi2);
4279
+ const mayNaN = !isNonNaN(arg, phi2);
4280
+ const term = arg.term ? simplifyTerm(app(`Math.${name}`, [arg.term])) : void 0;
4281
+ let out = {};
4282
+ if (b) {
4283
+ if (b.lo !== void 0) {
4284
+ const v2 = impl(b.lo.value);
4285
+ out.lo = Number.isNaN(v2) ? void 0 : { value: v2, strict: false };
4286
+ }
4287
+ if (b.hi !== void 0) {
4288
+ const v2 = impl(b.hi.value);
4289
+ out.hi = Number.isNaN(v2) ? void 0 : { value: v2, strict: false };
4290
+ }
4291
+ }
4292
+ const pred = term ? boundsToPred(term, out) : void 0;
4293
+ const bounded = abs({ k: "prim", type: "number" }, term, pred, "path");
4294
+ if (!mayNaN) return bounded;
4295
+ return makeSum(numLit(NaN), bounded);
4296
+ }
4297
+ function evalMathMethod(name, args) {
4298
+ if (name === "random") return numPrim("path");
4299
+ if (name === "min" || name === "max") {
4300
+ const nums2 = [];
4301
+ let allLit = true;
4302
+ for (const a of args) {
4303
+ const n = coerceMathArg(a);
4304
+ if (n === void 0) {
4305
+ allLit = false;
4306
+ break;
4159
4307
  }
4160
- const pvR = litValue(p0);
4161
- const pv = pvR.ok ? pvR.value : void 0;
4162
- if (p0.term?.op === "lit" && (pv === void 0 || pv !== null && typeof pv !== "object")) {
4163
- throw new NudoThrow(errorTypeAbs("TypeError"));
4308
+ if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
4309
+ nums2.push(n);
4310
+ }
4311
+ if (allLit) {
4312
+ try {
4313
+ return numLit((name === "min" ? Math.min : Math.max)(...nums2));
4314
+ } catch {
4315
+ return numPrim();
4164
4316
  }
4165
- return setProtoAbs(t0, p0);
4166
4317
  }
4167
- case "assign": {
4168
- if (!args.length) return unknown;
4169
- const t0 = args[0];
4170
- if (t0 && t0.term?.op === "lit") {
4171
- if (t0.term.value === null || t0.term.value === void 0) {
4172
- throw new NudoThrow(errorTypeAbs("TypeError"));
4173
- }
4174
- return unknown;
4175
- }
4176
- let acc = args[0];
4177
- for (let i = 1; i < args.length; i++) {
4178
- acc = { ...acc };
4179
- const src = args[i];
4180
- if (acc.shape.k === "obj" && src.shape.k === "obj") {
4181
- const base = acc.shape.slots;
4182
- const over = src.shape.slots;
4183
- const filtered = { ...base };
4184
- for (const k of enumKeys(over, src)) {
4185
- filtered[k] = over[k];
4186
- }
4187
- acc = abs({ k: "obj", slots: filtered }, void 0, void 0, confJoin(acc.conf, src.conf));
4188
- } else if (src.shape.k !== "obj") {
4189
- const srcSlots = assignSourceSlots(src);
4190
- if (srcSlots === void 0) {
4191
- if (acc.shape.k === "obj") {
4192
- const base = acc.shape.slots;
4193
- acc = abs({ k: "obj", slots: { ...base }, open: true }, void 0, void 0, acc.conf);
4194
- } else if (acc.shape.k === "tuple") {
4195
- const els = acc.shape.elements;
4196
- const joined = els.length ? els.reduce((x, y) => joinAbs(x, y)) : str2();
4197
- acc = abs(
4198
- { k: "arr", element: joinAbs(joined, str2()) },
4199
- void 0,
4200
- void 0,
4201
- "partial"
4202
- );
4203
- }
4204
- } else if (acc.shape.k === "obj") {
4205
- const base = acc.shape.slots;
4206
- acc = abs({ k: "obj", slots: { ...base, ...srcSlots } }, void 0, void 0, confJoin(acc.conf, src.conf));
4207
- } else if (acc.shape.k === "tuple") {
4208
- let elements = [...acc.shape.elements];
4209
- let holes = [...acc.shape.holes ?? []];
4210
- let len = elements.length;
4211
- for (const [k, s] of Object.entries(srcSlots)) {
4212
- const idx = canonicalArrayIndex(k);
4213
- if (idx === void 0) continue;
4214
- if (idx >= len) len = idx + 1;
4215
- if (idx >= elements.length) elements.length = idx + 1;
4216
- elements[idx] = s.value;
4217
- holes = holes.filter((h) => h !== idx);
4218
- }
4219
- elements.length = len;
4220
- acc = abs(
4221
- { k: "tuple", elements, holes: holes.length > 0 ? holes : void 0 },
4222
- void 0,
4223
- void 0,
4224
- confJoin(acc.conf, src.conf)
4225
- );
4226
- }
4227
- } else if (acc.shape.k === "tuple" && src.shape.k === "obj") {
4228
- const slots = src.shape.slots;
4229
- let elements = [...acc.shape.elements];
4230
- let holes = [...acc.shape.holes ?? []];
4231
- let len = elements.length;
4232
- for (const [k, s] of Object.entries(slots)) {
4233
- if (k === "length") {
4234
- const lv = s.value.term?.op === "lit" ? s.value.term.value : void 0;
4235
- if (typeof lv !== "number" || !Number.isInteger(lv) || lv < 0) {
4236
- throw new NudoThrow(errorTypeAbs("RangeError"));
4237
- }
4238
- if (lv > TUPLE_MATERIALIZE_CAP) {
4239
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4240
- }
4241
- if (lv < len) {
4242
- elements.length = lv;
4243
- holes = holes.filter((h) => h < lv);
4244
- } else {
4245
- for (let j = len; j < lv; j++) holes.push(j);
4246
- }
4247
- len = lv;
4248
- continue;
4249
- }
4250
- const idx = canonicalArrayIndex(k);
4251
- if (idx === void 0) continue;
4252
- if (idx >= len) len = idx + 1;
4253
- if (idx >= elements.length) elements.length = idx + 1;
4254
- elements[idx] = s.value;
4255
- holes = holes.filter((h) => h !== idx);
4256
- }
4257
- elements.length = len;
4258
- acc = abs(
4259
- { k: "tuple", elements, holes: holes.length > 0 ? holes : void 0 },
4260
- void 0,
4261
- void 0,
4262
- confJoin(acc.conf, src.conf)
4263
- );
4264
- }
4265
- }
4266
- return acc;
4318
+ for (const a of args) {
4319
+ const n = coerceMathArg(a);
4320
+ if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
4267
4321
  }
4268
- case "is": {
4269
- const a02 = args[0];
4270
- const a1 = args[1];
4271
- if (a02 && a1 && isExactLit(a02) && isExactLit(a1)) {
4272
- const va = a02.term.value;
4273
- const vb = a1.term.value;
4274
- return boolLit(Object.is(va, vb));
4322
+ return minMaxAbs(name, args);
4323
+ }
4324
+ if (name === "round" || name === "floor" || name === "ceil" || name === "trunc") {
4325
+ const n = coerceMathArg(args[0]);
4326
+ if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
4327
+ if (typeof n === "number") {
4328
+ try {
4329
+ return numLit(
4330
+ name === "round" ? Math.round(n) : name === "floor" ? Math.floor(n) : name === "ceil" ? Math.ceil(n) : Math.trunc(n)
4331
+ );
4332
+ } catch {
4333
+ return numPrim();
4275
4334
  }
4276
- return boolPrim();
4277
- }
4278
- case "freeze": {
4279
- if (a0) return markExtState(a0, "frozen");
4280
- return void 0;
4281
- }
4282
- case "seal": {
4283
- if (a0) return markExtState(a0, "sealed");
4284
- return void 0;
4285
- }
4286
- case "preventExtensions": {
4287
- if (a0) return markExtState(a0, "nonext");
4288
- return void 0;
4289
- }
4290
- case "isFrozen": {
4291
- const t = args[0];
4292
- if (isPrimLike(t)) return boolLit(true);
4293
- return boolLit(extStateOf(t) === "frozen");
4294
- }
4295
- case "isSealed": {
4296
- const t = args[0];
4297
- if (isPrimLike(t)) return boolLit(true);
4298
- const s = extStateOf(t);
4299
- return boolLit(s === "sealed" || s === "frozen");
4300
- }
4301
- case "isExtensible": {
4302
- const t = args[0];
4303
- if (isPrimLike(t)) return boolLit(false);
4304
- return boolLit(extStateOf(t) === void 0);
4305
4335
  }
4306
- case "defineProperty": {
4307
- const kvR = args[1] ? litValue(args[1]) : void 0;
4308
- const kv = kvR?.ok ? kvR.value : void 0;
4309
- if (!a0 || typeof kv !== "string" && typeof kv !== "number") return a0;
4310
- if (a0.term?.op === "lit") throw new NudoThrow(errorTypeAbs("TypeError"));
4311
- const key = String(kv);
4312
- const descAbs = args[2];
4313
- if (!descAbs || descAbs.shape.k !== "obj") return unknown;
4314
- const dslots = descAbs.shape.slots;
4315
- const field = (k) => {
4316
- const s = dslots[k]?.value;
4317
- if (!s) return { present: false, v: void 0 };
4318
- const lvR = litValue(s);
4319
- if (lvR.ok) return { present: true, v: lvR.value };
4320
- return { present: true, v: "fn-or-abstract" };
4321
- };
4322
- const getF = field("get");
4323
- const setF = field("set");
4324
- const valueF = field("value");
4325
- const invalidAccessor = (f) => f.present && f.v !== void 0 && f.v !== "fn-or-abstract";
4326
- if (invalidAccessor(getF) || invalidAccessor(setF)) return unknown;
4327
- const accessorPresent = getF.present && getF.v !== void 0 || setF.present && setF.v !== void 0;
4328
- if (accessorPresent && valueF.present && valueF.v !== void 0) return unknown;
4329
- const dv = (k) => {
4330
- const s = dslots[k]?.value;
4331
- if (!s) return void 0;
4332
- const r = litValue(s);
4333
- return r.ok ? r.value : void 0;
4334
- };
4335
- const value = dv("value");
4336
- const toBool = (k) => {
4337
- const f = field(k);
4338
- if (!f.present || f.v === void 0 || f.v === "fn-or-abstract") return void 0;
4339
- return Boolean(f.v);
4340
- };
4341
- const writable = toBool("writable");
4342
- const enumerable = toBool("enumerable");
4343
- const configurable = toBool("configurable");
4344
- const innerForExists = a0.shape.k === "brand" ? a0.shape.shape : a0;
4345
- const exists = innerForExists.shape.k === "obj" && Object.prototype.hasOwnProperty.call(innerForExists.shape.slots, key);
4346
- const flags = {};
4347
- if (exists) {
4348
- if (writable === false) flags.writable = false;
4349
- if (enumerable === false) flags.enumerable = false;
4350
- if (configurable === false) flags.configurable = false;
4351
- } else {
4352
- if (writable !== true) flags.writable = false;
4353
- if (enumerable !== true) flags.enumerable = false;
4354
- if (configurable !== true) flags.configurable = false;
4355
- }
4356
- const litOf = (v2) => {
4357
- if (v2 === void 0) return void 0;
4358
- if (typeof v2 === "number") return numLit(v2);
4359
- if (typeof v2 === "string") return strLit(v2);
4360
- if (typeof v2 === "boolean") return boolLit(v2);
4361
- if (v2 === null) return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
4362
- return void 0;
4363
- };
4364
- let out = a0;
4365
- const putSlots = (inner) => {
4366
- if (inner.shape.k !== "obj") return inner;
4367
- const lit3 = litOf(value);
4368
- const slots = lit3 ? { ...inner.shape.slots, [key]: { value: lit3 } } : { ...inner.shape.slots };
4369
- const next = abs({ k: "obj", slots }, void 0, void 0, inner.conf);
4370
- migrateInvariants(inner, next);
4371
- return next;
4372
- };
4373
- if (out.shape.k === "obj") {
4374
- out = putSlots(out);
4375
- } else if (out.shape.k === "brand") {
4376
- const inner = putSlots(out.shape.shape);
4377
- if (inner !== out.shape.shape) {
4378
- out = abs({ k: "brand", name: out.shape.name, shape: inner }, out.term, out.pred, out.conf);
4379
- }
4380
- }
4381
- setPropFlags(out, key, flags);
4382
- return out;
4336
+ if (args[0]) {
4337
+ const c2 = coerceMathArg(args[0]);
4338
+ if (c2 === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
4339
+ return roundingAbs(name, args[0]);
4383
4340
  }
4384
- default:
4385
- return void 0;
4341
+ return numPrim();
4342
+ }
4343
+ const impl = mathMethod(name);
4344
+ if (!impl) return void 0;
4345
+ const nums = [];
4346
+ for (const a of args) {
4347
+ const n = coerceMathArg(a);
4348
+ if (n === void 0) return numPrim();
4349
+ if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
4350
+ nums.push(n);
4351
+ }
4352
+ try {
4353
+ return numLit(impl(...nums));
4354
+ } catch {
4355
+ return numPrim();
4386
4356
  }
4387
4357
  }
4388
4358
 
4389
- // src/algebra/builtins/json.ts
4390
- var NOT_LITERAL = /* @__PURE__ */ Symbol("nudo:not-literal");
4391
- function absToJsonNative(a, seen) {
4392
- if (seen.has(a)) return NOT_LITERAL;
4393
- const t = a.term;
4394
- if (t?.op === "lit") return t.value;
4395
- const s = a.shape;
4396
- if (s.k === "tuple") {
4397
- seen.add(a);
4398
- const holes = a.shape.holes ?? [];
4399
- const out = [];
4400
- for (let i = 0; i < s.elements.length; i++) {
4401
- if (holes.includes(i)) {
4402
- out.push(void 0);
4403
- continue;
4404
- }
4405
- const v2 = absToJsonNative(s.elements[i], seen);
4406
- if (v2 === NOT_LITERAL) return NOT_LITERAL;
4407
- out.push(v2);
4408
- }
4409
- return out;
4410
- }
4411
- if (s.k === "obj") {
4412
- if (s.open || s.index) return NOT_LITERAL;
4413
- seen.add(a);
4414
- const out = {};
4415
- const flags = getPropFlags(a);
4416
- for (const [k, sv] of Object.entries(s.slots)) {
4417
- if (flags?.get(k)?.enumerable === false) continue;
4418
- const v2 = absToJsonNative(sv.value, seen);
4419
- if (v2 === NOT_LITERAL) return NOT_LITERAL;
4420
- out[k] = v2;
4421
- }
4422
- return out;
4423
- }
4424
- return NOT_LITERAL;
4425
- }
4426
- function jsonValueToAbs(v2) {
4427
- if (v2 === null) return abs({ k: "unknown" }, { op: "lit", value: null }, pTrue, "exact");
4428
- if (typeof v2 === "number") return numLit(v2);
4429
- if (typeof v2 === "string") return strLit(v2);
4430
- if (typeof v2 === "boolean") return boolLit(v2);
4431
- if (Array.isArray(v2)) {
4432
- return abs({ k: "tuple", elements: v2.map(jsonValueToAbs) }, void 0, void 0, "exact");
4433
- }
4434
- const slots = /* @__PURE__ */ Object.create(null);
4435
- for (const [k, sv] of Object.entries(v2)) {
4436
- setSlot(slots, k, { value: jsonValueToAbs(sv) });
4437
- }
4438
- return abs({ k: "obj", slots }, void 0, void 0, "exact");
4439
- }
4440
- function isNonJsonTopLevel(a) {
4441
- if (a.shape.k === "fn") return true;
4442
- if (a.shape.k === "prim" && a.shape.type === "symbol") return true;
4443
- return false;
4359
+ // src/algebra/class-mark.ts
4360
+ var classValues = /* @__PURE__ */ new WeakMap();
4361
+ function markClassValue(v2, name) {
4362
+ classValues.set(v2, name);
4444
4363
  }
4445
- function evalJsonMethod(name, args) {
4446
- if (name === "parse") {
4447
- const a0Abs = args[0];
4448
- if (!a0Abs) throw new NudoThrow(errorTypeAbs("SyntaxError"));
4449
- if (args[1]) return unknown;
4450
- const t = a0Abs.term;
4451
- if (t?.op !== "lit") return unknown;
4452
- const v2 = t.value;
4453
- if (v2 === void 0) throw new NudoThrow(errorTypeAbs("SyntaxError"));
4454
- if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
4455
- const src = typeof v2 === "string" ? v2 : typeof v2 === "number" || typeof v2 === "boolean" || typeof v2 === "bigint" ? String(v2) : v2 === null ? "null" : void 0;
4456
- if (src === void 0) return unknown;
4457
- try {
4458
- return jsonValueToAbs(JSON.parse(src));
4459
- } catch {
4460
- throw new NudoThrow(errorTypeAbs("SyntaxError"));
4461
- }
4462
- }
4463
- if (name === "stringify") {
4464
- const a0Abs = args[0];
4465
- if (!a0Abs) return undefAbs();
4466
- const v2 = absToJsonNative(a0Abs, /* @__PURE__ */ new Set());
4467
- if (v2 === NOT_LITERAL) {
4468
- if (isNonJsonTopLevel(a0Abs)) return undefAbs();
4469
- return str2("partial");
4470
- }
4471
- const replacerArg = args[1];
4472
- let replacer;
4473
- if (replacerArg) {
4474
- const rv = absToJsonNative(replacerArg, /* @__PURE__ */ new Set());
4475
- if (rv === NOT_LITERAL) return str2("partial");
4476
- if (Array.isArray(rv)) {
4477
- replacer = rv.filter(
4478
- (x) => typeof x === "string" || typeof x === "number"
4479
- );
4480
- } else if (typeof rv === "function") {
4481
- return str2("partial");
4482
- }
4483
- }
4484
- const spaceArg = args[2];
4485
- let space;
4486
- if (spaceArg) {
4487
- const t = spaceArg.term;
4488
- if (t?.op !== "lit") return str2("partial");
4489
- const sv = t.value;
4490
- if (typeof sv === "number" || typeof sv === "string") {
4491
- space = sv;
4492
- } else if (sv !== void 0 && sv !== null) {
4493
- return str2("partial");
4494
- }
4495
- }
4496
- try {
4497
- const s = JSON.stringify(v2, replacer, space);
4498
- return s === void 0 ? undefAbs() : strLit(s);
4499
- } catch {
4500
- throw new NudoThrow(errorTypeAbs("TypeError"));
4501
- }
4502
- }
4503
- return void 0;
4364
+ function classNameOfValue(v2) {
4365
+ return classValues.get(v2);
4504
4366
  }
4505
4367
 
4506
- // src/algebra/builtins/number.ts
4507
- function foldParseInt(s, radix) {
4508
- const str6 = String(s);
4509
- if (radix === void 0) return numLit(parseInt(str6));
4510
- const r = Number(radix) | 0;
4511
- if (r === 0) return numLit(parseInt(str6));
4512
- if (r < 2 || r > 36) return numLit(NaN);
4513
- return numLit(parseInt(str6, r));
4514
- }
4515
- function foldParseFloat(s) {
4516
- return numLit(parseFloat(String(s)));
4368
+ // src/algebra/builtins/ctor.ts
4369
+ var builtinCtorByName = /* @__PURE__ */ new Map();
4370
+ var builtinCtorByAbs = /* @__PURE__ */ new WeakMap();
4371
+ function builtinCtorAbs(name) {
4372
+ let a = builtinCtorByName.get(name);
4373
+ if (!a) {
4374
+ a = abs(
4375
+ { k: "brand", name, shape: objOf({ name: { value: strLit(name) } }) },
4376
+ void 0,
4377
+ void 0,
4378
+ "exact"
4379
+ );
4380
+ markClassValue(a, name);
4381
+ builtinCtorByName.set(name, a);
4382
+ builtinCtorByAbs.set(a, name);
4383
+ }
4384
+ return a;
4517
4385
  }
4518
- function toStringLitArg(a) {
4519
- if (!a) return { lit: true, v: void 0 };
4520
- if (a.term?.op !== "lit") return { lit: false };
4521
- const v2 = a.term.value;
4522
- if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
4523
- return { lit: true, v: v2 };
4386
+ function builtinCtorNameOf(v2) {
4387
+ if (!v2 || typeof v2 !== "object") return void 0;
4388
+ return builtinCtorByAbs.get(v2);
4524
4389
  }
4525
- function radixLitArg(a) {
4526
- if (!a) return { ok: true, v: void 0 };
4527
- if (a.term?.op !== "lit") return { ok: false };
4528
- const v2 = a.term.value;
4529
- if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
4530
- if (v2 === void 0) return { ok: true, v: void 0 };
4531
- if (typeof v2 === "number" || typeof v2 === "string" || typeof v2 === "boolean" || v2 === null) {
4532
- return { ok: true, v: v2 };
4533
- }
4534
- return { ok: false };
4390
+ function hostBuiltinCtorName(v2) {
4391
+ if (typeof v2 !== "function") return void 0;
4392
+ if (v2 === Number) return "Number";
4393
+ if (v2 === String) return "String";
4394
+ if (v2 === Boolean) return "Boolean";
4395
+ if (v2 === BigInt) return "BigInt";
4396
+ if (v2 === Symbol) return "Symbol";
4397
+ if (v2 === Array) return "Array";
4398
+ if (v2 === Object) return "Object";
4399
+ if (v2 === Function) return "Function";
4400
+ if (v2 === Promise) return "Promise";
4401
+ if (v2 === Date) return "Date";
4402
+ if (v2 === RegExp) return "RegExp";
4403
+ if (v2 === Map) return "Map";
4404
+ if (v2 === Set) return "Set";
4405
+ if (v2 === WeakMap) return "WeakMap";
4406
+ if (v2 === WeakSet) return "WeakSet";
4407
+ if (v2 === Error) return "Error";
4408
+ if (v2 === TypeError) return "TypeError";
4409
+ if (v2 === RangeError) return "RangeError";
4410
+ if (v2 === ReferenceError) return "ReferenceError";
4411
+ if (v2 === SyntaxError) return "SyntaxError";
4412
+ if (v2 === URIError) return "URIError";
4413
+ if (v2 === EvalError) return "EvalError";
4414
+ if (v2 === AggregateError) return "AggregateError";
4415
+ return void 0;
4535
4416
  }
4536
- function evalNumberStatic(name, args) {
4537
- const a0Arg = args[0];
4538
- const a0R = a0Arg ? litValue(a0Arg) : void 0;
4539
- const a0 = a0R?.ok ? a0R.value : void 0;
4540
- const foldStrictNumberPred = (pred) => {
4541
- if (!a0Arg) return boolLit(false);
4542
- if (a0Arg.term?.op !== "lit") return void 0;
4543
- const v2 = a0Arg.term.value;
4544
- return boolLit(typeof v2 === "number" && pred(v2));
4545
- };
4546
- switch (name) {
4547
- case "isInteger":
4548
- return foldStrictNumberPred(Number.isInteger) ?? boolPrim();
4549
- case "isNaN":
4550
- return foldStrictNumberPred(Number.isNaN) ?? boolPrim();
4551
- case "isFinite":
4552
- return foldStrictNumberPred(Number.isFinite) ?? boolPrim();
4553
- case "parseInt": {
4554
- const s = toStringLitArg(a0Arg);
4555
- if (!s.lit) return numPrim();
4556
- const radix = radixLitArg(args[1]);
4557
- if (!radix.ok) return numPrim();
4558
- return foldParseInt(s.v, radix.v);
4417
+ function ctorNameOfRecv(recv) {
4418
+ const s = recv.shape;
4419
+ switch (s.k) {
4420
+ case "prim":
4421
+ return s.type === "number" ? "Number" : s.type === "string" ? "String" : s.type === "boolean" ? "Boolean" : s.type === "bigint" ? "BigInt" : s.type === "symbol" ? "Symbol" : void 0;
4422
+ case "tuple":
4423
+ case "arr":
4424
+ return "Array";
4425
+ case "obj":
4426
+ return isNullProtoObj(recv) ? void 0 : "Object";
4427
+ case "fn":
4428
+ return "Function";
4429
+ case "eff":
4430
+ return s.eff === "promise" ? "Promise" : "Generator";
4431
+ case "brand": {
4432
+ if (s.name === "Object.prototype") return "Object";
4433
+ if (s.name.endsWith(".prototype")) return s.name.slice(0, -".prototype".length);
4434
+ return s.name;
4559
4435
  }
4560
- case "parseFloat": {
4561
- const s = toStringLitArg(a0Arg);
4562
- if (!s.lit) return numPrim();
4563
- return foldParseFloat(s.v);
4436
+ case "sum": {
4437
+ let first;
4438
+ for (const m of s.members) {
4439
+ const n = ctorNameOfRecv(m);
4440
+ if (n === void 0) return void 0;
4441
+ if (first === void 0) first = n;
4442
+ else if (first !== n) return void 0;
4443
+ }
4444
+ return first;
4564
4445
  }
4565
- case "MAX_SAFE_INTEGER":
4566
- return numLit(Number.MAX_SAFE_INTEGER);
4567
4446
  default:
4568
4447
  return void 0;
4569
4448
  }
4570
4449
  }
4571
-
4572
- // src/algebra/collections.ts
4573
- var NO_LIT_KEY = /* @__PURE__ */ Symbol("nudo:no-lit-key");
4574
- var mapTables = /* @__PURE__ */ new WeakMap();
4575
- var setTables = /* @__PURE__ */ new WeakMap();
4576
- var armOverlays = [];
4577
- function pushCollectionArm() {
4578
- armOverlays.push(null);
4579
- }
4580
- function popCollectionArm() {
4581
- return armOverlays.pop() ?? void 0;
4582
- }
4583
- function topArmOverlay() {
4584
- const i = armOverlays.length - 1;
4585
- let top = armOverlays[i];
4586
- if (!top) {
4587
- top = /* @__PURE__ */ new WeakMap();
4588
- armOverlays[i] = top;
4589
- }
4590
- return top;
4450
+ function protoBrandAbs(ctorName) {
4451
+ return abs(
4452
+ {
4453
+ k: "brand",
4454
+ name: `${ctorName}.prototype`,
4455
+ shape: objOf({ constructor: { value: builtinCtorAbs(ctorName) } })
4456
+ },
4457
+ void 0,
4458
+ void 0,
4459
+ "exact"
4460
+ );
4591
4461
  }
4592
- function cloneMapTable(t) {
4593
- return {
4594
- byLit: new Map(t.byLit),
4595
- shadowValues: [...t.shadowValues],
4596
- maybeAbsent: t.maybeAbsent ? new Set(t.maybeAbsent) : void 0
4597
- };
4598
- }
4599
- function cloneSetTable(t) {
4600
- return {
4601
- elements: [...t.elements],
4602
- maybeAbsent: t.maybeAbsent instanceof Set ? new Set(t.maybeAbsent) : t.maybeAbsent
4603
- };
4604
- }
4605
- function setAbsentKey(t, k) {
4606
- if (!t) return false;
4607
- if (t.maybeAbsent === true) return true;
4608
- return t.maybeAbsent instanceof Set && t.maybeAbsent.has(k);
4609
- }
4610
- function setAnyAbsent(t) {
4611
- if (!t) return false;
4612
- return t.maybeAbsent === true || t.maybeAbsent instanceof Set && t.maybeAbsent.size > 0;
4613
- }
4614
- function mergeCollectionArms(arms) {
4615
- endCollectionFork(arms);
4616
- }
4617
- var forkTouchedStack = [];
4618
- function beginCollectionFork() {
4619
- forkTouchedStack.push(null);
4462
+ function protoOfRecv(a) {
4463
+ const s = a.shape;
4464
+ const nullProtoLit = abs(
4465
+ { k: "unknown" },
4466
+ { op: "lit", value: null },
4467
+ pTrue,
4468
+ "exact"
4469
+ );
4470
+ if (s.k === "tuple" || s.k === "arr") return protoBrandAbs("Array");
4471
+ if (s.k === "prim") {
4472
+ const ctor = s.type === "number" ? "Number" : s.type === "string" ? "String" : s.type === "boolean" ? "Boolean" : s.type === "bigint" ? "BigInt" : s.type === "symbol" ? "Symbol" : void 0;
4473
+ return ctor ? protoBrandAbs(ctor) : unknown;
4474
+ }
4475
+ if (s.k === "fn") return protoBrandAbs("Function");
4476
+ if (s.k === "eff" && s.eff === "promise") return protoBrandAbs("Promise");
4477
+ if (s.k === "brand") {
4478
+ if (s.name === "Object.prototype") return nullProtoLit;
4479
+ if (s.name.endsWith(".prototype")) return objectProtoBrand();
4480
+ return protoBrandAbs(s.name);
4481
+ }
4482
+ if (s.k === "obj") {
4483
+ if (isNullProtoObj(a)) return nullProtoLit;
4484
+ return objectProtoBrand();
4485
+ }
4486
+ return unknown;
4620
4487
  }
4621
- function noteCollectionWrite(id) {
4622
- const i = forkTouchedStack.length - 1;
4623
- if (i < 0) return;
4624
- let top = forkTouchedStack[i];
4625
- if (!top) {
4626
- top = /* @__PURE__ */ new Set();
4627
- forkTouchedStack[i] = top;
4488
+ var OBJECT_PROTO_METHOD_NAMES = /* @__PURE__ */ new Set([
4489
+ "hasOwnProperty",
4490
+ "isPrototypeOf",
4491
+ "propertyIsEnumerable",
4492
+ "valueOf",
4493
+ "toString",
4494
+ "toLocaleString"
4495
+ ]);
4496
+ var objectProtoSingleton;
4497
+ function objectProtoBrand() {
4498
+ if (!objectProtoSingleton) {
4499
+ const a = abs(
4500
+ {
4501
+ k: "brand",
4502
+ name: "Object.prototype",
4503
+ shape: objOf({ constructor: { value: builtinCtorAbs("Object") } })
4504
+ },
4505
+ void 0,
4506
+ void 0,
4507
+ "exact"
4508
+ );
4509
+ setPropFlags(a, "constructor", { enumerable: false, writable: true, configurable: true });
4510
+ objectProtoSingleton = a;
4628
4511
  }
4629
- top.add(id);
4512
+ return objectProtoSingleton;
4630
4513
  }
4631
- function endCollectionFork(arms) {
4632
- const touched = forkTouchedStack.pop();
4633
- if (!touched || touched.size === 0) return;
4634
- if (arms.length === 0) return;
4635
- const nested = armOverlays.length > 0;
4636
- const outerArm = nested ? armOverlays[armOverlays.length - 1] : void 0;
4637
- const commitMap = (id, merged) => {
4638
- if (nested) {
4639
- const outer = topArmOverlay();
4640
- const e = outer.get(id) ?? {};
4641
- outer.set(id, { ...e, map: merged });
4642
- } else {
4643
- mapTables.set(id, merged);
4514
+ function isObjectProtoBrand(a) {
4515
+ return !!a && a.shape.k === "brand" && a.shape.name === "Object.prototype";
4516
+ }
4517
+
4518
+ // src/algebra/builtins/object.ts
4519
+ function assignSourceSlots(src) {
4520
+ const s = src.shape;
4521
+ if (s.k === "tuple") {
4522
+ const holes = s.holes ?? [];
4523
+ const slots = {};
4524
+ for (let i = 0; i < s.elements.length; i++) {
4525
+ if (!holes.includes(i)) slots[String(i)] = { value: s.elements[i] };
4644
4526
  }
4645
- };
4646
- const commitSet = (id, merged) => {
4647
- if (nested) {
4648
- const outer = topArmOverlay();
4649
- const e = outer.get(id) ?? {};
4650
- outer.set(id, { ...e, set: merged });
4651
- } else {
4652
- setTables.set(id, merged);
4527
+ return slots;
4528
+ }
4529
+ if (src.term?.op === "lit" && typeof src.term.value === "string") {
4530
+ const v2 = src.term.value;
4531
+ const slots = {};
4532
+ for (let i = 0; i < v2.length; i++) slots[String(i)] = { value: strLit(v2[i]) };
4533
+ return slots;
4534
+ }
4535
+ if (s.k === "brand" && s.name === "String") {
4536
+ const inner = s.shape;
4537
+ if (inner.shape.k === "obj") {
4538
+ const slots = {};
4539
+ for (const [k, v2] of Object.entries(inner.shape.slots)) {
4540
+ if (k === "length") continue;
4541
+ setSlot(slots, k, v2);
4542
+ }
4543
+ if (Object.keys(slots).length > 0 || !inner.shape.open) return slots;
4653
4544
  }
4545
+ return void 0;
4546
+ }
4547
+ if (s.k === "prim") return s.type === "string" ? void 0 : {};
4548
+ if (s.k === "eff" || s.k === "never") return {};
4549
+ return void 0;
4550
+ }
4551
+ function evalObjectMethod(name, args) {
4552
+ const a0 = args[0];
4553
+ const enumKeys = (slots, target) => {
4554
+ const flags = getPropFlags(target);
4555
+ return Object.keys(slots).filter(
4556
+ (k) => flags?.get(k)?.enumerable !== false
4557
+ );
4654
4558
  };
4655
- for (const id of touched) {
4656
- const armTables = [];
4657
- const armSetTables = [];
4658
- let anyMap = false;
4659
- let anySet = false;
4660
- for (const arm of arms) {
4661
- const e = arm?.get(id);
4662
- if (e?.map) {
4663
- anyMap = true;
4664
- armTables.push(e.map);
4665
- } else if (anyMap || armTables.length > 0) {
4666
- armTables.push(void 0);
4667
- }
4668
- if (e?.set) {
4669
- anySet = true;
4670
- armSetTables.push(e.set);
4671
- } else if (anySet || armSetTables.length > 0) {
4672
- armSetTables.push(void 0);
4559
+ switch (name) {
4560
+ case "create": {
4561
+ if (a0 === void 0 || a0.term?.op === "lit" && a0.term.value === void 0) {
4562
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4673
4563
  }
4674
- }
4675
- if (anyMap || armTables.some(Boolean)) {
4676
- const base = (nested ? mapTableForReadBase(outerArm, id) : mapTables.get(id)) ?? emptyMapTable();
4677
- const perArm = arms.map((arm) => {
4678
- const e = arm?.get(id);
4679
- return e?.map ?? cloneMapTable(base);
4680
- });
4681
- const merged = { byLit: /* @__PURE__ */ new Map(), shadowValues: [], maybeAbsent: /* @__PURE__ */ new Set() };
4682
- const keyArms = /* @__PURE__ */ new Map();
4683
- const forcedAbsent = /* @__PURE__ */ new Set();
4684
- for (const t of perArm) {
4685
- for (const [k, v2] of t.byLit) {
4686
- const prev = merged.byLit.get(k);
4687
- merged.byLit.set(k, prev ? joinAbs(prev, v2) : v2);
4688
- keyArms.set(k, (keyArms.get(k) ?? 0) + 1);
4689
- }
4690
- for (const sv of t.shadowValues) merged.shadowValues.push(sv);
4691
- if (t.maybeAbsent) {
4692
- for (const k of t.maybeAbsent) forcedAbsent.add(k);
4693
- }
4564
+ const protoVR = litValue(a0);
4565
+ const protoV = protoVR.ok ? protoVR.value : void 0;
4566
+ if (protoV === null) return markNullProtoObj(abs({ k: "obj", slots: {} }, void 0, void 0, "exact"));
4567
+ if (typeof protoV === "object") {
4568
+ return abs({ k: "obj", slots: {} }, void 0, void 0, "path");
4694
4569
  }
4695
- for (const [k, count] of keyArms) {
4696
- if (count < perArm.length) merged.maybeAbsent.add(k);
4570
+ if (a0.term?.op === "lit") {
4571
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4697
4572
  }
4698
- for (const k of forcedAbsent) merged.maybeAbsent.add(k);
4699
- if (merged.maybeAbsent.size === 0) delete merged.maybeAbsent;
4700
- commitMap(id, merged);
4573
+ return void 0;
4701
4574
  }
4702
- if (anySet || armSetTables.some(Boolean)) {
4703
- const base = (nested ? setTableForReadBase(outerArm, id) : setTables.get(id)) ?? emptySetTable();
4704
- const perArm = arms.map((arm) => {
4705
- const e = arm?.get(id);
4706
- return e?.set ?? cloneSetTable(base);
4707
- });
4708
- const seen = /* @__PURE__ */ new Set();
4709
- const mergedEls = [];
4710
- const litArmCount = /* @__PURE__ */ new Map();
4711
- const forcedAbsent = /* @__PURE__ */ new Set();
4712
- let wholeUncertain = false;
4713
- let hasNonLit = false;
4714
- for (const t of perArm) {
4715
- if (t.maybeAbsent === true) wholeUncertain = true;
4716
- if (t.maybeAbsent instanceof Set) {
4717
- for (const k of t.maybeAbsent) forcedAbsent.add(k);
4718
- }
4719
- const armLits = /* @__PURE__ */ new Set();
4720
- for (const el of t.elements) {
4721
- const lk = litKeyOf(el);
4722
- if (isLitKey(lk)) {
4723
- if (!seen.has(lk)) {
4724
- seen.add(lk);
4725
- mergedEls.push(el);
4726
- }
4727
- armLits.add(lk);
4728
- } else {
4729
- hasNonLit = true;
4730
- mergedEls.push(el);
4731
- }
4732
- }
4733
- for (const k of armLits) {
4734
- litArmCount.set(k, (litArmCount.get(k) ?? 0) + 1);
4735
- }
4575
+ case "keys": {
4576
+ if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4577
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4736
4578
  }
4737
- const maybeKeys = /* @__PURE__ */ new Set();
4738
- if (wholeUncertain || hasNonLit) {
4739
- wholeUncertain = true;
4740
- } else {
4741
- for (const [k, count] of litArmCount) {
4742
- if (count < perArm.length) maybeKeys.add(k);
4743
- }
4744
- for (const k of forcedAbsent) maybeKeys.add(k);
4579
+ if (a0?.shape.k === "obj") {
4580
+ const keys = enumKeys(
4581
+ a0.shape.slots,
4582
+ a0
4583
+ ).map((k) => strLit(k));
4584
+ return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
4745
4585
  }
4746
- commitSet(id, {
4747
- elements: mergedEls,
4586
+ if (a0?.shape.k === "tuple") {
4587
+ const holes = a0.shape.holes ?? [];
4588
+ const keys = a0.shape.elements.map((_, i) => i).filter((i) => !holes.includes(i)).map((i) => strLit(String(i)));
4589
+ return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
4590
+ }
4591
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4592
+ const s = a0.term.value;
4593
+ return abs(
4594
+ { k: "tuple", elements: Array.from({ length: s.length }, (_, i) => strLit(String(i))) },
4595
+ void 0,
4596
+ void 0,
4597
+ "exact"
4598
+ );
4599
+ }
4600
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4601
+ return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4602
+ }
4603
+ return abs({ k: "arr", element: str2("path") }, void 0, void 0, "partial");
4604
+ }
4605
+ case "values": {
4606
+ if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4607
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4608
+ }
4609
+ if (a0?.shape.k === "obj") {
4610
+ const slots = a0.shape.slots;
4611
+ const vals = enumKeys(slots, a0).map((k) => slots[k].value);
4612
+ return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
4613
+ }
4614
+ if (a0?.shape.k === "tuple") {
4615
+ const holes = a0.shape.holes ?? [];
4616
+ return abs(
4617
+ {
4618
+ k: "tuple",
4619
+ elements: a0.shape.elements.filter((_, i) => !holes.includes(i))
4620
+ },
4621
+ void 0,
4622
+ void 0,
4623
+ a0.conf
4624
+ );
4625
+ }
4626
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4627
+ const s = a0.term.value;
4628
+ return abs(
4629
+ {
4630
+ k: "tuple",
4631
+ elements: Array.from({ length: s.length }, (_, i) => strLit(s[i]))
4632
+ },
4633
+ void 0,
4634
+ void 0,
4635
+ "exact"
4636
+ );
4637
+ }
4638
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4639
+ return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4640
+ }
4641
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4642
+ }
4643
+ case "entries": {
4644
+ if (a0 && a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4645
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4646
+ }
4647
+ if (a0?.shape.k === "obj") {
4648
+ const slots = a0.shape.slots;
4649
+ const entries = enumKeys(slots, a0).map(
4650
+ (k) => abs({ k: "tuple", elements: [strLit(k), slots[k].value] }, void 0, void 0, "exact")
4651
+ );
4652
+ return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
4653
+ }
4654
+ if (a0?.shape.k === "tuple") {
4655
+ const holes = a0.shape.holes ?? [];
4656
+ const entries = a0.shape.elements.map((el, i) => ({ el, i })).filter(({ i }) => !holes.includes(i)).map(
4657
+ ({ el, i }) => abs({ k: "tuple", elements: [strLit(String(i)), el] }, void 0, void 0, "exact")
4658
+ );
4659
+ return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
4660
+ }
4661
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "string") {
4662
+ const s = a0.term.value;
4663
+ return abs(
4664
+ {
4665
+ k: "tuple",
4666
+ elements: Array.from(
4667
+ { length: s.length },
4668
+ (_, i) => abs({ k: "tuple", elements: [strLit(String(i)), strLit(s[i])] }, void 0, void 0, "exact")
4669
+ )
4670
+ },
4671
+ void 0,
4672
+ void 0,
4673
+ "exact"
4674
+ );
4675
+ }
4676
+ if (a0?.term?.op === "lit" && typeof a0.term.value === "number") {
4677
+ return abs({ k: "tuple", elements: [] }, void 0, void 0, "exact");
4678
+ }
4679
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4680
+ }
4681
+ case "hasOwn": {
4682
+ if (!a0) return boolPrim();
4683
+ if (a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4684
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4685
+ }
4686
+ const keyR = args[1] ? litValue(args[1]) : void 0;
4687
+ const key = keyR?.ok ? keyR.value : void 0;
4688
+ if (typeof key !== "string") return boolPrim();
4689
+ if (a0.shape.k === "obj") {
4690
+ const shape = a0.shape;
4691
+ if (Object.prototype.hasOwnProperty.call(shape.slots, key)) return boolLit(true);
4692
+ if (!shape.open && a0.conf === "exact") return boolLit(false);
4693
+ return boolPrim();
4694
+ }
4695
+ return boolPrim();
4696
+ }
4697
+ case "getPrototypeOf": {
4698
+ if (!a0) return unknown;
4699
+ if (a0.term?.op === "lit" && (a0.term.value === null || a0.term.value === void 0)) {
4700
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4701
+ }
4702
+ return protoOfRecv(a0);
4703
+ }
4704
+ case "setPrototypeOf": {
4705
+ if (!args.length) {
4706
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4707
+ }
4708
+ const t0 = args[0];
4709
+ const p0 = args[1];
4710
+ if (!t0 || !p0) {
4711
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4712
+ }
4713
+ const pvR = litValue(p0);
4714
+ const pv = pvR.ok ? pvR.value : void 0;
4715
+ if (p0.term?.op === "lit" && (pv === void 0 || pv !== null && typeof pv !== "object")) {
4716
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4717
+ }
4718
+ return setProtoAbs(t0, p0);
4719
+ }
4720
+ case "assign": {
4721
+ if (!args.length) return unknown;
4722
+ const t0 = args[0];
4723
+ if (t0 && t0.term?.op === "lit") {
4724
+ if (t0.term.value === null || t0.term.value === void 0) {
4725
+ throw new NudoThrow(errorTypeAbs("TypeError"));
4726
+ }
4727
+ return unknown;
4728
+ }
4729
+ let acc = args[0];
4730
+ for (let i = 1; i < args.length; i++) {
4731
+ acc = { ...acc };
4732
+ const src = args[i];
4733
+ if (acc.shape.k === "obj" && src.shape.k === "obj") {
4734
+ const base = acc.shape.slots;
4735
+ const over = src.shape.slots;
4736
+ const filtered = { ...base };
4737
+ for (const k of enumKeys(over, src)) {
4738
+ filtered[k] = over[k];
4739
+ }
4740
+ acc = abs({ k: "obj", slots: filtered }, void 0, void 0, confJoin(acc.conf, src.conf));
4741
+ } else if (src.shape.k !== "obj") {
4742
+ const srcSlots = assignSourceSlots(src);
4743
+ if (srcSlots === void 0) {
4744
+ if (acc.shape.k === "obj") {
4745
+ const base = acc.shape.slots;
4746
+ acc = abs({ k: "obj", slots: { ...base }, open: true }, void 0, void 0, acc.conf);
4747
+ } else if (acc.shape.k === "tuple") {
4748
+ const els = acc.shape.elements;
4749
+ const joined = els.length ? els.reduce((x, y) => joinAbs(x, y)) : str2();
4750
+ acc = abs(
4751
+ { k: "arr", element: joinAbs(joined, str2()) },
4752
+ void 0,
4753
+ void 0,
4754
+ "partial"
4755
+ );
4756
+ }
4757
+ } else if (acc.shape.k === "obj") {
4758
+ const base = acc.shape.slots;
4759
+ acc = abs({ k: "obj", slots: { ...base, ...srcSlots } }, void 0, void 0, confJoin(acc.conf, src.conf));
4760
+ } else if (acc.shape.k === "tuple") {
4761
+ let elements = [...acc.shape.elements];
4762
+ let holes = [...acc.shape.holes ?? []];
4763
+ let len = elements.length;
4764
+ for (const [k, s] of Object.entries(srcSlots)) {
4765
+ const idx = canonicalArrayIndex(k);
4766
+ if (idx === void 0) continue;
4767
+ if (idx >= len) len = idx + 1;
4768
+ if (idx >= elements.length) elements.length = idx + 1;
4769
+ elements[idx] = s.value;
4770
+ holes = holes.filter((h) => h !== idx);
4771
+ }
4772
+ elements.length = len;
4773
+ acc = abs(
4774
+ { k: "tuple", elements, holes: holes.length > 0 ? holes : void 0 },
4775
+ void 0,
4776
+ void 0,
4777
+ confJoin(acc.conf, src.conf)
4778
+ );
4779
+ }
4780
+ } else if (acc.shape.k === "tuple" && src.shape.k === "obj") {
4781
+ const slots = src.shape.slots;
4782
+ let elements = [...acc.shape.elements];
4783
+ let holes = [...acc.shape.holes ?? []];
4784
+ let len = elements.length;
4785
+ for (const [k, s] of Object.entries(slots)) {
4786
+ if (k === "length") {
4787
+ const lv = s.value.term?.op === "lit" ? s.value.term.value : void 0;
4788
+ if (typeof lv !== "number" || !Number.isInteger(lv) || lv < 0) {
4789
+ throw new NudoThrow(errorTypeAbs("RangeError"));
4790
+ }
4791
+ if (lv > TUPLE_MATERIALIZE_CAP) {
4792
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
4793
+ }
4794
+ if (lv < len) {
4795
+ elements.length = lv;
4796
+ holes = holes.filter((h) => h < lv);
4797
+ } else {
4798
+ for (let j = len; j < lv; j++) holes.push(j);
4799
+ }
4800
+ len = lv;
4801
+ continue;
4802
+ }
4803
+ const idx = canonicalArrayIndex(k);
4804
+ if (idx === void 0) continue;
4805
+ if (idx >= len) len = idx + 1;
4806
+ if (idx >= elements.length) elements.length = idx + 1;
4807
+ elements[idx] = s.value;
4808
+ holes = holes.filter((h) => h !== idx);
4809
+ }
4810
+ elements.length = len;
4811
+ acc = abs(
4812
+ { k: "tuple", elements, holes: holes.length > 0 ? holes : void 0 },
4813
+ void 0,
4814
+ void 0,
4815
+ confJoin(acc.conf, src.conf)
4816
+ );
4817
+ }
4818
+ }
4819
+ return acc;
4820
+ }
4821
+ case "is": {
4822
+ const a02 = args[0];
4823
+ const a1 = args[1];
4824
+ if (a02 && a1 && isExactLit(a02) && isExactLit(a1)) {
4825
+ const va = a02.term.value;
4826
+ const vb = a1.term.value;
4827
+ return boolLit(Object.is(va, vb));
4828
+ }
4829
+ return boolPrim();
4830
+ }
4831
+ case "freeze": {
4832
+ if (a0) return markExtState(a0, "frozen");
4833
+ return void 0;
4834
+ }
4835
+ case "seal": {
4836
+ if (a0) return markExtState(a0, "sealed");
4837
+ return void 0;
4838
+ }
4839
+ case "preventExtensions": {
4840
+ if (a0) return markExtState(a0, "nonext");
4841
+ return void 0;
4842
+ }
4843
+ case "isFrozen": {
4844
+ const t = args[0];
4845
+ if (isPrimLike(t)) return boolLit(true);
4846
+ return boolLit(extStateOf(t) === "frozen");
4847
+ }
4848
+ case "isSealed": {
4849
+ const t = args[0];
4850
+ if (isPrimLike(t)) return boolLit(true);
4851
+ const s = extStateOf(t);
4852
+ return boolLit(s === "sealed" || s === "frozen");
4853
+ }
4854
+ case "isExtensible": {
4855
+ const t = args[0];
4856
+ if (isPrimLike(t)) return boolLit(false);
4857
+ return boolLit(extStateOf(t) === void 0);
4858
+ }
4859
+ case "defineProperty": {
4860
+ const kvR = args[1] ? litValue(args[1]) : void 0;
4861
+ const kv = kvR?.ok ? kvR.value : void 0;
4862
+ if (!a0 || typeof kv !== "string" && typeof kv !== "number") return a0;
4863
+ if (a0.term?.op === "lit") throw new NudoThrow(errorTypeAbs("TypeError"));
4864
+ const key = String(kv);
4865
+ const descAbs = args[2];
4866
+ if (!descAbs || descAbs.shape.k !== "obj") return unknown;
4867
+ const dslots = descAbs.shape.slots;
4868
+ const field = (k) => {
4869
+ const s = dslots[k]?.value;
4870
+ if (!s) return { present: false, v: void 0 };
4871
+ const lvR = litValue(s);
4872
+ if (lvR.ok) return { present: true, v: lvR.value };
4873
+ return { present: true, v: "fn-or-abstract" };
4874
+ };
4875
+ const getF = field("get");
4876
+ const setF = field("set");
4877
+ const valueF = field("value");
4878
+ const invalidAccessor = (f) => f.present && f.v !== void 0 && f.v !== "fn-or-abstract";
4879
+ if (invalidAccessor(getF) || invalidAccessor(setF)) return unknown;
4880
+ const accessorPresent = getF.present && getF.v !== void 0 || setF.present && setF.v !== void 0;
4881
+ if (accessorPresent && valueF.present && valueF.v !== void 0) return unknown;
4882
+ const dv = (k) => {
4883
+ const s = dslots[k]?.value;
4884
+ if (!s) return void 0;
4885
+ const r = litValue(s);
4886
+ return r.ok ? r.value : void 0;
4887
+ };
4888
+ const value = dv("value");
4889
+ const toBool = (k) => {
4890
+ const f = field(k);
4891
+ if (!f.present || f.v === void 0 || f.v === "fn-or-abstract") return void 0;
4892
+ return Boolean(f.v);
4893
+ };
4894
+ const writable = toBool("writable");
4895
+ const enumerable = toBool("enumerable");
4896
+ const configurable = toBool("configurable");
4897
+ const innerForExists = a0.shape.k === "brand" ? a0.shape.shape : a0;
4898
+ const exists = innerForExists.shape.k === "obj" && Object.prototype.hasOwnProperty.call(innerForExists.shape.slots, key);
4899
+ const flags = {};
4900
+ if (exists) {
4901
+ if (writable === false) flags.writable = false;
4902
+ if (enumerable === false) flags.enumerable = false;
4903
+ if (configurable === false) flags.configurable = false;
4904
+ } else {
4905
+ if (writable !== true) flags.writable = false;
4906
+ if (enumerable !== true) flags.enumerable = false;
4907
+ if (configurable !== true) flags.configurable = false;
4908
+ }
4909
+ const litOf = (v2) => {
4910
+ if (v2 === void 0) return void 0;
4911
+ if (typeof v2 === "number") return numLit(v2);
4912
+ if (typeof v2 === "string") return strLit(v2);
4913
+ if (typeof v2 === "boolean") return boolLit(v2);
4914
+ if (v2 === null) return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
4915
+ return void 0;
4916
+ };
4917
+ let out = a0;
4918
+ const putSlots = (inner) => {
4919
+ if (inner.shape.k !== "obj") return inner;
4920
+ const lit3 = litOf(value);
4921
+ const slots = lit3 ? { ...inner.shape.slots, [key]: { value: lit3 } } : { ...inner.shape.slots };
4922
+ const next = abs({ k: "obj", slots }, void 0, void 0, inner.conf);
4923
+ migrateInvariants(inner, next);
4924
+ return next;
4925
+ };
4926
+ if (out.shape.k === "obj") {
4927
+ out = putSlots(out);
4928
+ } else if (out.shape.k === "brand") {
4929
+ const inner = putSlots(out.shape.shape);
4930
+ if (inner !== out.shape.shape) {
4931
+ out = abs({ k: "brand", name: out.shape.name, shape: inner }, out.term, out.pred, out.conf);
4932
+ }
4933
+ }
4934
+ setPropFlags(out, key, flags);
4935
+ return out;
4936
+ }
4937
+ default:
4938
+ return void 0;
4939
+ }
4940
+ }
4941
+
4942
+ // src/algebra/builtins/json.ts
4943
+ var NOT_LITERAL = /* @__PURE__ */ Symbol("nudo:not-literal");
4944
+ function absToJsonNative(a, seen) {
4945
+ if (seen.has(a)) return NOT_LITERAL;
4946
+ const t = a.term;
4947
+ if (t?.op === "lit") return t.value;
4948
+ const s = a.shape;
4949
+ if (s.k === "tuple") {
4950
+ if (a.shape.rest) return NOT_LITERAL;
4951
+ seen.add(a);
4952
+ const holes = a.shape.holes ?? [];
4953
+ const out = [];
4954
+ for (let i = 0; i < s.elements.length; i++) {
4955
+ if (holes.includes(i)) {
4956
+ out.push(void 0);
4957
+ continue;
4958
+ }
4959
+ const v2 = absToJsonNative(s.elements[i], seen);
4960
+ if (v2 === NOT_LITERAL) return NOT_LITERAL;
4961
+ out.push(v2);
4962
+ }
4963
+ return out;
4964
+ }
4965
+ if (s.k === "obj") {
4966
+ if (s.open || s.index) return NOT_LITERAL;
4967
+ seen.add(a);
4968
+ const out = {};
4969
+ const flags = getPropFlags(a);
4970
+ for (const [k, sv] of Object.entries(s.slots)) {
4971
+ if (flags?.get(k)?.enumerable === false) continue;
4972
+ const v2 = absToJsonNative(sv.value, seen);
4973
+ if (v2 === NOT_LITERAL) return NOT_LITERAL;
4974
+ out[k] = v2;
4975
+ }
4976
+ return out;
4977
+ }
4978
+ return NOT_LITERAL;
4979
+ }
4980
+ function jsonValueToAbs(v2) {
4981
+ if (v2 === null) return abs({ k: "unknown" }, { op: "lit", value: null }, pTrue, "exact");
4982
+ if (typeof v2 === "number") return numLit(v2);
4983
+ if (typeof v2 === "string") return strLit(v2);
4984
+ if (typeof v2 === "boolean") return boolLit(v2);
4985
+ if (Array.isArray(v2)) {
4986
+ return abs({ k: "tuple", elements: v2.map(jsonValueToAbs) }, void 0, void 0, "exact");
4987
+ }
4988
+ const slots = /* @__PURE__ */ Object.create(null);
4989
+ for (const [k, sv] of Object.entries(v2)) {
4990
+ setSlot(slots, k, { value: jsonValueToAbs(sv) });
4991
+ }
4992
+ return abs({ k: "obj", slots }, void 0, void 0, "exact");
4993
+ }
4994
+ function isNonJsonTopLevel(a) {
4995
+ if (a.shape.k === "fn") return true;
4996
+ if (a.shape.k === "prim" && a.shape.type === "symbol") return true;
4997
+ return false;
4998
+ }
4999
+ function evalJsonMethod(name, args) {
5000
+ if (name === "parse") {
5001
+ const a0Abs = args[0];
5002
+ if (!a0Abs) throw new NudoThrow(errorTypeAbs("SyntaxError"));
5003
+ if (args[1]) return unknown;
5004
+ const t = a0Abs.term;
5005
+ if (t?.op !== "lit") return unknown;
5006
+ const v2 = t.value;
5007
+ if (v2 === void 0) throw new NudoThrow(errorTypeAbs("SyntaxError"));
5008
+ if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
5009
+ const src = typeof v2 === "string" ? v2 : typeof v2 === "number" || typeof v2 === "boolean" || typeof v2 === "bigint" ? String(v2) : v2 === null ? "null" : void 0;
5010
+ if (src === void 0) return unknown;
5011
+ try {
5012
+ return jsonValueToAbs(JSON.parse(src));
5013
+ } catch {
5014
+ throw new NudoThrow(errorTypeAbs("SyntaxError"));
5015
+ }
5016
+ }
5017
+ if (name === "stringify") {
5018
+ const a0Abs = args[0];
5019
+ if (!a0Abs) return undefAbs();
5020
+ const v2 = absToJsonNative(a0Abs, /* @__PURE__ */ new Set());
5021
+ if (v2 === NOT_LITERAL) {
5022
+ if (isNonJsonTopLevel(a0Abs)) return undefAbs();
5023
+ return str2("partial");
5024
+ }
5025
+ const replacerArg = args[1];
5026
+ let replacer;
5027
+ if (replacerArg) {
5028
+ const rv = absToJsonNative(replacerArg, /* @__PURE__ */ new Set());
5029
+ if (rv === NOT_LITERAL) return str2("partial");
5030
+ if (Array.isArray(rv)) {
5031
+ replacer = rv.filter(
5032
+ (x) => typeof x === "string" || typeof x === "number"
5033
+ );
5034
+ } else if (typeof rv === "function") {
5035
+ return str2("partial");
5036
+ }
5037
+ }
5038
+ const spaceArg = args[2];
5039
+ let space;
5040
+ if (spaceArg) {
5041
+ const t = spaceArg.term;
5042
+ if (t?.op !== "lit") return str2("partial");
5043
+ const sv = t.value;
5044
+ if (typeof sv === "number" || typeof sv === "string") {
5045
+ space = sv;
5046
+ } else if (sv !== void 0 && sv !== null) {
5047
+ return str2("partial");
5048
+ }
5049
+ }
5050
+ try {
5051
+ const s = JSON.stringify(v2, replacer, space);
5052
+ return s === void 0 ? undefAbs() : strLit(s);
5053
+ } catch {
5054
+ throw new NudoThrow(errorTypeAbs("TypeError"));
5055
+ }
5056
+ }
5057
+ return void 0;
5058
+ }
5059
+
5060
+ // src/algebra/builtins/number.ts
5061
+ function foldParseInt(s, radix) {
5062
+ const str6 = String(s);
5063
+ if (radix === void 0) return numLit(parseInt(str6));
5064
+ const r = Number(radix) | 0;
5065
+ if (r === 0) return numLit(parseInt(str6));
5066
+ if (r < 2 || r > 36) return numLit(NaN);
5067
+ return numLit(parseInt(str6, r));
5068
+ }
5069
+ function foldParseFloat(s) {
5070
+ return numLit(parseFloat(String(s)));
5071
+ }
5072
+ function toStringLitArg(a) {
5073
+ if (!a) return { lit: true, v: void 0 };
5074
+ if (a.term?.op !== "lit") return { lit: false };
5075
+ const v2 = a.term.value;
5076
+ if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
5077
+ return { lit: true, v: v2 };
5078
+ }
5079
+ function radixLitArg(a) {
5080
+ if (!a) return { ok: true, v: void 0 };
5081
+ if (a.term?.op !== "lit") return { ok: false };
5082
+ const v2 = a.term.value;
5083
+ if (typeof v2 === "symbol") throw new NudoThrow(errorTypeAbs("TypeError"));
5084
+ if (v2 === void 0) return { ok: true, v: void 0 };
5085
+ if (typeof v2 === "number" || typeof v2 === "string" || typeof v2 === "boolean" || v2 === null) {
5086
+ return { ok: true, v: v2 };
5087
+ }
5088
+ return { ok: false };
5089
+ }
5090
+ function evalNumberStatic(name, args) {
5091
+ const a0Arg = args[0];
5092
+ const a0R = a0Arg ? litValue(a0Arg) : void 0;
5093
+ const a0 = a0R?.ok ? a0R.value : void 0;
5094
+ const foldStrictNumberPred = (pred) => {
5095
+ if (!a0Arg) return boolLit(false);
5096
+ if (a0Arg.term?.op !== "lit") return void 0;
5097
+ const v2 = a0Arg.term.value;
5098
+ return boolLit(typeof v2 === "number" && pred(v2));
5099
+ };
5100
+ switch (name) {
5101
+ case "isInteger":
5102
+ return foldStrictNumberPred(Number.isInteger) ?? boolPrim();
5103
+ case "isNaN": {
5104
+ const folded = foldStrictNumberPred(Number.isNaN);
5105
+ if (folded) return folded;
5106
+ if (a0Arg?.term) {
5107
+ return abs(
5108
+ { k: "prim", type: "boolean" },
5109
+ void 0,
5110
+ { op: "eq", a: a0Arg.term, b: { op: "lit", value: NaN } },
5111
+ "path"
5112
+ );
5113
+ }
5114
+ return boolPrim();
5115
+ }
5116
+ case "isFinite":
5117
+ return foldStrictNumberPred(Number.isFinite) ?? boolPrim();
5118
+ case "parseInt": {
5119
+ const s = toStringLitArg(a0Arg);
5120
+ if (!s.lit) return numPrim();
5121
+ const radix = radixLitArg(args[1]);
5122
+ if (!radix.ok) return numPrim();
5123
+ return foldParseInt(s.v, radix.v);
5124
+ }
5125
+ case "parseFloat": {
5126
+ const s = toStringLitArg(a0Arg);
5127
+ if (!s.lit) return numPrim();
5128
+ return foldParseFloat(s.v);
5129
+ }
5130
+ case "MAX_SAFE_INTEGER":
5131
+ return numLit(Number.MAX_SAFE_INTEGER);
5132
+ default:
5133
+ return void 0;
5134
+ }
5135
+ }
5136
+
5137
+ // src/algebra/collections.ts
5138
+ var NO_LIT_KEY = /* @__PURE__ */ Symbol("nudo:no-lit-key");
5139
+ var mapTables = /* @__PURE__ */ new WeakMap();
5140
+ var setTables = /* @__PURE__ */ new WeakMap();
5141
+ var armOverlays = [];
5142
+ function pushCollectionArm() {
5143
+ armOverlays.push(null);
5144
+ }
5145
+ function popCollectionArm() {
5146
+ return armOverlays.pop() ?? void 0;
5147
+ }
5148
+ function topArmOverlay() {
5149
+ const i = armOverlays.length - 1;
5150
+ let top = armOverlays[i];
5151
+ if (!top) {
5152
+ top = /* @__PURE__ */ new WeakMap();
5153
+ armOverlays[i] = top;
5154
+ }
5155
+ return top;
5156
+ }
5157
+ function cloneMapTable(t) {
5158
+ return {
5159
+ byLit: new Map(t.byLit),
5160
+ shadowValues: [...t.shadowValues],
5161
+ maybeAbsent: t.maybeAbsent ? new Set(t.maybeAbsent) : void 0
5162
+ };
5163
+ }
5164
+ function cloneSetTable(t) {
5165
+ return {
5166
+ elements: [...t.elements],
5167
+ maybeAbsent: t.maybeAbsent instanceof Set ? new Set(t.maybeAbsent) : t.maybeAbsent
5168
+ };
5169
+ }
5170
+ function setAbsentKey(t, k) {
5171
+ if (!t) return false;
5172
+ if (t.maybeAbsent === true) return true;
5173
+ return t.maybeAbsent instanceof Set && t.maybeAbsent.has(k);
5174
+ }
5175
+ function setAnyAbsent(t) {
5176
+ if (!t) return false;
5177
+ return t.maybeAbsent === true || t.maybeAbsent instanceof Set && t.maybeAbsent.size > 0;
5178
+ }
5179
+ function mergeCollectionArms(arms) {
5180
+ endCollectionFork(arms);
5181
+ }
5182
+ var forkTouchedStack = [];
5183
+ function beginCollectionFork() {
5184
+ forkTouchedStack.push(null);
5185
+ }
5186
+ function noteCollectionWrite(id) {
5187
+ const i = forkTouchedStack.length - 1;
5188
+ if (i < 0) return;
5189
+ let top = forkTouchedStack[i];
5190
+ if (!top) {
5191
+ top = /* @__PURE__ */ new Set();
5192
+ forkTouchedStack[i] = top;
5193
+ }
5194
+ top.add(id);
5195
+ }
5196
+ function endCollectionFork(arms) {
5197
+ const touched = forkTouchedStack.pop();
5198
+ if (!touched || touched.size === 0) return;
5199
+ if (arms.length === 0) return;
5200
+ const nested = armOverlays.length > 0;
5201
+ const outerArm = nested ? armOverlays[armOverlays.length - 1] : void 0;
5202
+ const commitMap = (id, merged) => {
5203
+ if (nested) {
5204
+ const outer = topArmOverlay();
5205
+ const e = outer.get(id) ?? {};
5206
+ outer.set(id, { ...e, map: merged });
5207
+ } else {
5208
+ mapTables.set(id, merged);
5209
+ }
5210
+ };
5211
+ const commitSet = (id, merged) => {
5212
+ if (nested) {
5213
+ const outer = topArmOverlay();
5214
+ const e = outer.get(id) ?? {};
5215
+ outer.set(id, { ...e, set: merged });
5216
+ } else {
5217
+ setTables.set(id, merged);
5218
+ }
5219
+ };
5220
+ for (const id of touched) {
5221
+ const armTables = [];
5222
+ const armSetTables = [];
5223
+ let anyMap = false;
5224
+ let anySet = false;
5225
+ for (const arm of arms) {
5226
+ const e = arm?.get(id);
5227
+ if (e?.map) {
5228
+ anyMap = true;
5229
+ armTables.push(e.map);
5230
+ } else if (anyMap || armTables.length > 0) {
5231
+ armTables.push(void 0);
5232
+ }
5233
+ if (e?.set) {
5234
+ anySet = true;
5235
+ armSetTables.push(e.set);
5236
+ } else if (anySet || armSetTables.length > 0) {
5237
+ armSetTables.push(void 0);
5238
+ }
5239
+ }
5240
+ if (anyMap || armTables.some(Boolean)) {
5241
+ const base = (nested ? mapTableForReadBase(outerArm, id) : mapTables.get(id)) ?? emptyMapTable();
5242
+ const perArm = arms.map((arm) => {
5243
+ const e = arm?.get(id);
5244
+ return e?.map ?? cloneMapTable(base);
5245
+ });
5246
+ const merged = { byLit: /* @__PURE__ */ new Map(), shadowValues: [], maybeAbsent: /* @__PURE__ */ new Set() };
5247
+ const keyArms = /* @__PURE__ */ new Map();
5248
+ const forcedAbsent = /* @__PURE__ */ new Set();
5249
+ for (const t of perArm) {
5250
+ for (const [k, v2] of t.byLit) {
5251
+ const prev = merged.byLit.get(k);
5252
+ merged.byLit.set(k, prev ? joinAbs(prev, v2) : v2);
5253
+ keyArms.set(k, (keyArms.get(k) ?? 0) + 1);
5254
+ }
5255
+ for (const sv of t.shadowValues) merged.shadowValues.push(sv);
5256
+ if (t.maybeAbsent) {
5257
+ for (const k of t.maybeAbsent) forcedAbsent.add(k);
5258
+ }
5259
+ }
5260
+ for (const [k, count] of keyArms) {
5261
+ if (count < perArm.length) merged.maybeAbsent.add(k);
5262
+ }
5263
+ for (const k of forcedAbsent) merged.maybeAbsent.add(k);
5264
+ if (merged.maybeAbsent.size === 0) delete merged.maybeAbsent;
5265
+ commitMap(id, merged);
5266
+ }
5267
+ if (anySet || armSetTables.some(Boolean)) {
5268
+ const base = (nested ? setTableForReadBase(outerArm, id) : setTables.get(id)) ?? emptySetTable();
5269
+ const perArm = arms.map((arm) => {
5270
+ const e = arm?.get(id);
5271
+ return e?.set ?? cloneSetTable(base);
5272
+ });
5273
+ const seen = /* @__PURE__ */ new Set();
5274
+ const mergedEls = [];
5275
+ const litArmCount = /* @__PURE__ */ new Map();
5276
+ const forcedAbsent = /* @__PURE__ */ new Set();
5277
+ let wholeUncertain = false;
5278
+ let hasNonLit = false;
5279
+ for (const t of perArm) {
5280
+ if (t.maybeAbsent === true) wholeUncertain = true;
5281
+ if (t.maybeAbsent instanceof Set) {
5282
+ for (const k of t.maybeAbsent) forcedAbsent.add(k);
5283
+ }
5284
+ const armLits = /* @__PURE__ */ new Set();
5285
+ for (const el of t.elements) {
5286
+ const lk = litKeyOf(el);
5287
+ if (isLitKey(lk)) {
5288
+ if (!seen.has(lk)) {
5289
+ seen.add(lk);
5290
+ mergedEls.push(el);
5291
+ }
5292
+ armLits.add(lk);
5293
+ } else {
5294
+ hasNonLit = true;
5295
+ mergedEls.push(el);
5296
+ }
5297
+ }
5298
+ for (const k of armLits) {
5299
+ litArmCount.set(k, (litArmCount.get(k) ?? 0) + 1);
5300
+ }
5301
+ }
5302
+ const maybeKeys = /* @__PURE__ */ new Set();
5303
+ if (wholeUncertain || hasNonLit) {
5304
+ wholeUncertain = true;
5305
+ } else {
5306
+ for (const [k, count] of litArmCount) {
5307
+ if (count < perArm.length) maybeKeys.add(k);
5308
+ }
5309
+ for (const k of forcedAbsent) maybeKeys.add(k);
5310
+ }
5311
+ commitSet(id, {
5312
+ elements: mergedEls,
4748
5313
  maybeAbsent: wholeUncertain ? true : maybeKeys.size > 0 ? maybeKeys : void 0
4749
5314
  });
4750
5315
  }
@@ -5403,7 +5968,7 @@ function arrayJoinToString(recv) {
5403
5968
  }
5404
5969
  function arrayMethodAbs(name) {
5405
5970
  return absFunction(["thisArg"], {
5406
- body: noBody,
5971
+ body: noBody2,
5407
5972
  bindThis: true,
5408
5973
  apply: (a) => {
5409
5974
  const recv = a[0] ?? undefAbs();
@@ -5766,11 +6331,11 @@ function evalPromiseCtor(args) {
5766
6331
  return undefAbs();
5767
6332
  };
5768
6333
  const resolveAbs = absFunction(["value"], {
5769
- body: noBody,
6334
+ body: noBody2,
5770
6335
  apply: (args2) => onResolve(args2[0])
5771
6336
  });
5772
6337
  const rejectAbs = absFunction(["reason"], {
5773
- body: noBody,
6338
+ body: noBody2,
5774
6339
  apply: (args2) => onReject(args2[0])
5775
6340
  });
5776
6341
  enterPromiseExecutorScope();
@@ -6453,7 +7018,7 @@ function evalObjectProtoMethod(name, thisVal, args) {
6453
7018
  }
6454
7019
  function objectProtoMethodAbs(name) {
6455
7020
  return absFunction(["thisArg", "arg0"], {
6456
- body: noBody,
7021
+ body: noBody2,
6457
7022
  bindThis: true,
6458
7023
  apply: (a) => {
6459
7024
  const recv = a[0] ?? undefLit();
@@ -6606,51 +7171,15 @@ function toNumericAbs(a) {
6606
7171
  }
6607
7172
  return n;
6608
7173
  }
6609
- function updateAddAbs(a) {
7174
+ function updateAddAbs(a, phi2 = pTrue) {
6610
7175
  const n = toNumericAbs(a);
6611
7176
  const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
6612
- if (n.shape.k === "prim" && n.shape.type === "bigint" && !n.term) {
6613
- return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
6614
- }
6615
- return addNumeric(n, one);
7177
+ return add(n, one, phi2);
6616
7178
  }
6617
- function updateSubAbs(a) {
7179
+ function updateSubAbs(a, phi2 = pTrue) {
6618
7180
  const n = toNumericAbs(a);
6619
7181
  const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
6620
- if (n.shape.k === "prim" && n.shape.type === "bigint" && !n.term) {
6621
- return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
6622
- }
6623
- return subNumeric(n, one);
6624
- }
6625
- function addNumeric(a, b) {
6626
- const ra = litValue(a);
6627
- const rb = litValue(b);
6628
- const va = ra.ok ? ra.value : void 0;
6629
- const vb = rb.ok ? rb.value : void 0;
6630
- if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va + vb);
6631
- if (typeof va === "number" && typeof vb === "number") return numLit(va + vb);
6632
- const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
6633
- return abs(
6634
- { k: "prim", type: big ? "bigint" : "number" },
6635
- void 0,
6636
- void 0,
6637
- confJoin(confJoin(a.conf, b.conf), "path")
6638
- );
6639
- }
6640
- function subNumeric(a, b) {
6641
- const ra = litValue(a);
6642
- const rb = litValue(b);
6643
- const va = ra.ok ? ra.value : void 0;
6644
- const vb = rb.ok ? rb.value : void 0;
6645
- if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va - vb);
6646
- if (typeof va === "number" && typeof vb === "number") return numLit(va - vb);
6647
- const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
6648
- return abs(
6649
- { k: "prim", type: big ? "bigint" : "number" },
6650
- void 0,
6651
- void 0,
6652
- confJoin(confJoin(a.conf, b.conf), "path")
6653
- );
7182
+ return sub(n, one, phi2);
6654
7183
  }
6655
7184
  function toNumberAbs(a) {
6656
7185
  if (isSymbolAbs(a)) {
@@ -7689,24 +8218,40 @@ function leqShape(src, tgt, phi2, env, depth) {
7689
8218
  return leqWithPred(s.element, t.element, phi2, env, depth + 1);
7690
8219
  }
7691
8220
  if (s.k === "tuple") {
7692
- return s.elements.every((el) => leqWithPred(el, t.element, phi2, env, depth + 1).ok) ? ok() : fail("tuple \u22AD arr");
8221
+ const elsOk = s.elements.every((el) => leqWithPred(el, t.element, phi2, env, depth + 1).ok);
8222
+ const restOk = !s.rest || leqWithPred(s.rest, t.element, phi2, env, depth + 1).ok;
8223
+ return elsOk && restOk ? ok() : fail("tuple \u22AD arr");
7693
8224
  }
7694
8225
  return fail(`shape ${s.k} \u22AD arr`);
7695
8226
  }
7696
8227
  if (t.k === "tuple") {
7697
8228
  if (s.k !== "tuple") return fail(`shape ${s.k} \u22AD tuple`);
7698
- if (s.elements.length !== t.elements.length) {
8229
+ if (!t.rest && s.elements.length !== t.elements.length) {
7699
8230
  return fail(`tuple arity ${s.elements.length} \u22AD ${t.elements.length}`);
7700
8231
  }
8232
+ if (t.rest && s.elements.length < t.elements.length) {
8233
+ return fail(`tuple arity ${s.elements.length} \u22AD ${t.elements.length} (target requires ${t.elements.length})`);
8234
+ }
8235
+ if (s.rest && !t.rest) {
8236
+ return fail(`tuple rest \u22AD fixed arity ${t.elements.length}`);
8237
+ }
7701
8238
  const sHoles = s.holes ?? [];
7702
8239
  const tHoles = t.holes ?? [];
7703
- if (sHoles.length !== tHoles.length || sHoles.some((h, i) => h !== tHoles[i])) {
7704
- return fail(`tuple holes [${sHoles.join(",")}] \u22AD [${tHoles.join(",")}]`);
8240
+ const overlap = Math.min(s.elements.length, t.elements.length);
8241
+ for (let i = 0; i < overlap; i++) {
8242
+ if (sHoles.includes(i) !== tHoles.includes(i)) {
8243
+ return fail(`tuple holes [${sHoles.join(",")}] \u22AD [${tHoles.join(",")}]`);
8244
+ }
7705
8245
  }
7706
- for (let i = 0; i < t.elements.length; i++) {
7707
- const r = leqWithPred(s.elements[i], t.elements[i], phi2, env, depth + 1);
8246
+ for (let i = 0; i < s.elements.length; i++) {
8247
+ const tgt2 = i < t.elements.length ? t.elements[i] : t.rest;
8248
+ const r = leqWithPred(s.elements[i], tgt2, phi2, env, depth + 1);
7708
8249
  if (!r.ok) return fail(`tuple[${i}]: ${r.reason}`);
7709
8250
  }
8251
+ if (s.rest && t.rest) {
8252
+ const r = leqWithPred(s.rest, t.rest, phi2, env, depth + 1);
8253
+ if (!r.ok) return fail(`tuple rest: ${r.reason}`);
8254
+ }
7710
8255
  return ok();
7711
8256
  }
7712
8257
  if (t.k === "fn") {
@@ -7781,13 +8326,30 @@ function formatAbs(a, opts = {}) {
7781
8326
  return parts.join(" ");
7782
8327
  }
7783
8328
  function formatShapeSlot(a) {
7784
- const base = formatShape(a);
8329
+ return formatShapeSlotB(a, new ProjectionBudget());
8330
+ }
8331
+ function formatShapeSlotB(a, budget) {
8332
+ const base = formatShapeB(a, budget);
7785
8333
  if (!a.term || a.term.op === "lit") return base;
7786
8334
  if (a.shape.k === "fn" || a.shape.k === "arr") return base;
7787
8335
  if (a.shape.k === "any" && a.term.op === "var") return termToString(a.term);
7788
8336
  return `${base} = ${termToString(a.term)}`;
7789
8337
  }
8338
+ var FORMAT_TRUNC = { cycle: "\u2026cycle", depth: "\u2026" };
7790
8339
  function formatShape(a) {
8340
+ return formatShapeB(a, new ProjectionBudget());
8341
+ }
8342
+ function formatShapeB(a, budget) {
8343
+ const stop = budget.enter(a);
8344
+ if (stop === "cycle") return FORMAT_TRUNC.cycle;
8345
+ if (stop === "depth") return FORMAT_TRUNC.depth;
8346
+ try {
8347
+ return formatShapeInner(a, budget);
8348
+ } finally {
8349
+ budget.exit();
8350
+ }
8351
+ }
8352
+ function formatShapeInner(a, budget) {
7791
8353
  const s = a.shape;
7792
8354
  switch (s.k) {
7793
8355
  case "never":
@@ -7814,28 +8376,28 @@ function formatShape(a) {
7814
8376
  const entries = Object.entries(s.slots).map(([k, slot]) => {
7815
8377
  const opt = slot.optional ? "?" : "";
7816
8378
  const key = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
7817
- return `${key}${opt}: ${formatShape(slot.value)}`;
8379
+ return `${key}${opt}: ${formatShapeB(slot.value, budget)}`;
7818
8380
  });
7819
8381
  return `{ ${entries.join(", ")} }`;
7820
8382
  }
7821
8383
  case "arr": {
7822
8384
  if (s.element.shape.k === "any" && s.element.term?.op === "var") {
7823
- return `arr(${formatShapeSlot(s.element)})`;
8385
+ return `arr(${formatShapeSlotB(s.element, budget)})`;
7824
8386
  }
7825
- return `${formatShape(s.element)}[]`;
8387
+ return `${formatShapeB(s.element, budget)}[]`;
7826
8388
  }
7827
8389
  case "tuple": {
7828
8390
  const holes = s.holes ?? [];
7829
8391
  const parts = s.elements.map(
7830
- (el, i) => holes.includes(i) ? "" : formatShape(el)
8392
+ (el, i) => holes.includes(i) ? "" : formatShapeB(el, budget)
7831
8393
  );
7832
8394
  if (s.rest) {
7833
- parts.push(`...${formatShape(s.rest)}`);
8395
+ parts.push(`...${formatShapeB(s.rest, budget)}`);
7834
8396
  }
7835
8397
  return `[${parts.join(", ")}]`;
7836
8398
  }
7837
8399
  case "fn": {
7838
- const ret = s.returnType !== void 0 ? formatShapeSlot(s.returnType) : "?";
8400
+ const ret = s.returnType !== void 0 ? formatShapeSlotB(s.returnType, budget) : "?";
7839
8401
  const labels = s.params ?? [];
7840
8402
  const paramTypes = s.paramTypes;
7841
8403
  const hasMarkers = labels.some(
@@ -7847,7 +8409,7 @@ function formatShape(a) {
7847
8409
  for (let i = 0; i < n; i++) {
7848
8410
  const label = labels[i];
7849
8411
  const type = paramTypes?.[i];
7850
- const typeText = type !== void 0 ? formatShapeSlot(type) : void 0;
8412
+ const typeText = type !== void 0 ? formatShapeSlotB(type, budget) : void 0;
7851
8413
  if (label?.startsWith("...")) {
7852
8414
  ps.push(typeText ? `...${label.slice(3)}: ${typeText}` : label);
7853
8415
  } else if (label?.endsWith("?")) {
@@ -7864,7 +8426,7 @@ function formatShape(a) {
7864
8426
  return `(${renderLabeled().join(", ")}) => ${ret}`;
7865
8427
  }
7866
8428
  if (paramTypes && paramTypes.length > 0) {
7867
- const ps = paramTypes.map((p) => formatShapeSlot(p));
8429
+ const ps = paramTypes.map((p) => formatShapeSlotB(p, budget));
7868
8430
  return `(${ps.join(", ")}) => ${ret}`;
7869
8431
  }
7870
8432
  return `(${labels.join(", ")}) => ${ret}`;
@@ -7875,7 +8437,7 @@ function formatShape(a) {
7875
8437
  if (slots) {
7876
8438
  const arg = (key) => {
7877
8439
  const sl = slots[key];
7878
- return sl ? formatShapeSlot(sl.value) : void 0;
8440
+ return sl ? formatShapeSlotB(sl.value, budget) : void 0;
7879
8441
  };
7880
8442
  if (s.name === "Map" || s.name === "ReadonlyMap" || s.name === "WeakMap") {
7881
8443
  const k = arg("__key");
@@ -7890,12 +8452,12 @@ function formatShape(a) {
7890
8452
  return `${s.name}`;
7891
8453
  }
7892
8454
  case "eff":
7893
- return `${s.eff}<${formatShape(s.inner)}>`;
8455
+ return `${s.eff}<${formatShapeB(s.inner, budget)}>`;
7894
8456
  case "sum": {
7895
8457
  const seen = /* @__PURE__ */ new Set();
7896
8458
  const parts = [];
7897
8459
  for (const m of s.members) {
7898
- const t = formatShape(m);
8460
+ const t = formatShapeB(m, budget);
7899
8461
  if (seen.has(t)) continue;
7900
8462
  seen.add(t);
7901
8463
  parts.push(t);
@@ -8204,8 +8766,10 @@ function identBoundaryRegex(name) {
8204
8766
  var NudoUnsupportedError = class extends Error {
8205
8767
  reason;
8206
8768
  loc;
8207
- constructor(reason, loc) {
8208
- super(`nudo:unsupported ${reason}`);
8769
+ constructor(reason, loc, detail) {
8770
+ super(
8771
+ detail ? `nudo:unsupported ${reason} (${detail})` : `nudo:unsupported ${reason}`
8772
+ );
8209
8773
  this.name = "NudoUnsupportedError";
8210
8774
  this.reason = reason;
8211
8775
  this.loc = loc;
@@ -9609,15 +10173,15 @@ function transpileStatement(stmt, depth, opts) {
9609
10173
  if (nsSpecs.length > 0) {
9610
10174
  if (!stmt.source) return `${pad}/* export * as without source skipped */`;
9611
10175
  return nsSpecs.map((s) => {
9612
- const exported = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
10176
+ const exported = s.exported.type === "Identifier" ? s.exported.name : JSON.stringify(s.exported.value);
9613
10177
  return `${pad}export * as ${exported} from ${JSON.stringify(stmt.source.value)};`;
9614
10178
  }).join("\n");
9615
10179
  }
9616
10180
  const specs = stmt.specifiers.filter(
9617
10181
  (s) => "local" in s
9618
10182
  ).map((s) => {
9619
- const local = s.local.type === "Identifier" ? s.local.name : s.local.value;
9620
- const exported = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
10183
+ const local = s.local.type === "Identifier" ? s.local.name : JSON.stringify(s.local.value);
10184
+ const exported = s.exported.type === "Identifier" ? s.exported.name : JSON.stringify(s.exported.value);
9621
10185
  return local === exported ? local : `${local} as ${exported}`;
9622
10186
  }).join(", ");
9623
10187
  if (stmt.source) {
@@ -10999,778 +11563,478 @@ ${emitFnBlockBody(prop.body, 1, methodOpts)}
10999
11563
  accRegs.push({
11000
11564
  key: mkey,
11001
11565
  set: `(__this, ${vname}) => {
11002
- ${emitFnBlockBody(prop.body, 1, methodOpts, { implicitReturn: false })}
11003
- return __this;
11004
- }`
11005
- });
11006
- }
11007
- continue;
11008
- }
11009
- let mBodyInner = emitFnBlockBody(prop.body, 1, methodOpts);
11010
- let mParams = ["__this", ...bindNames];
11011
- if (mHasArgs) {
11012
- const bound = emitParamBindingFromArgs(prop.params, " ", methodOpts, "__nudoArgs");
11013
- mBodyInner = [
11014
- ` let __nudoArgs = $arguments(__margs);`,
11015
- ...bound.prologue,
11016
- mBodyInner
11017
- ].join("\n");
11018
- mParams = ["__this", "...__margs"];
11019
- }
11020
- const bodySrc = `{
11021
- ${mBodyInner}
11022
- }`;
11023
- const fnValSrc = `$fnVal([${displayNames.map((p) => JSON.stringify(p)).join(", ")}], (${mParams.join(", ")}) => ${bodySrc}, { bindThis: true })`;
11024
- if (isProtoKey) {
11025
- acc = `$setKey(${acc ?? "$obj({})"}, $lit("__proto__"), ${fnValSrc})`;
11026
- } else {
11027
- props.push(`${mkey}: ${fnValSrc}`);
11028
- }
11029
- continue;
11030
- }
11031
- if (prop.type !== "ObjectProperty") continue;
11032
- if (prop.computed) {
11033
- flushProps();
11034
- const symK = symbolKeyOf(prop.key);
11035
- const v2 = transpileExpression(prop.value, opts);
11036
- const base = acc === null ? `$obj({})` : acc;
11037
- if (symK !== null) {
11038
- acc = `$set(${base}, ${symK}, ${v2})`;
11039
- continue;
11040
- }
11041
- const k = transpileExpression(prop.key, opts);
11042
- acc = `$setKey(${base}, ${k}, ${v2})`;
11043
- continue;
11044
- }
11045
- const key = (() => {
11046
- const k = staticKeyOf(prop.key);
11047
- return k === null ? null : JSON.stringify(k);
11048
- })();
11049
- if (key === null) continue;
11050
- if (!prop.computed && key === '"__proto__"') {
11051
- protoSet = transpileExpression(prop.value, opts);
11052
- continue;
11053
- }
11054
- if (prop.value.type === "FunctionExpression" && !prop.value.async) {
11055
- const fn = prop.value;
11056
- if (!fn.generator) {
11057
- const displayNames = paramDisplayNames(fn.params);
11058
- const bindNames = methodBindNames(fn.params);
11059
- const mHasArgs = fnBodyHasOwnArguments({ body: fn.body });
11060
- const methodOpts = {
11061
- ...opts,
11062
- inLoop: 0,
11063
- thisParam: "__this",
11064
- argsBinding: mHasArgs ? "__nudoArgs" : void 0
11065
- };
11066
- let mBodyInner = emitFnBlockBody(fn.body, 1, methodOpts);
11067
- let mParams = ["__this", ...bindNames];
11068
- if (mHasArgs) {
11069
- const bound = emitParamBindingFromArgs(fn.params, " ", methodOpts, "__nudoArgs");
11070
- mBodyInner = [
11071
- ` let __nudoArgs = $arguments(__margs);`,
11072
- ...bound.prologue,
11073
- mBodyInner
11074
- ].join("\n");
11075
- mParams = ["__this", "...__margs"];
11076
- }
11077
- const bodySrc = `{
11078
- ${mBodyInner}
11079
- }`;
11080
- props.push(
11081
- `${key}: $fnVal([${displayNames.map((p) => JSON.stringify(p)).join(", ")}], (${mParams.join(", ")}) => ${bodySrc}, { bindThis: true })`
11082
- );
11083
- continue;
11084
- }
11085
- }
11086
- const valSrc = transpileExpression(prop.value, opts);
11087
- props.push(`${key}: ${valSrc}`);
11088
- }
11089
- flushProps();
11090
- let result = acc ?? `$obj({})`;
11091
- for (const r of accRegs) {
11092
- result = `$objAccessor(${result}, ${r.key}, ${r.get ?? "null"}, ${r.set ?? "null"})`;
11093
- }
11094
- if (protoSet !== null) result = `$setProto(${result}, ${protoSet})`;
11095
- return result;
11096
- }
11097
- case "MemberExpression":
11098
- case "OptionalMemberExpression": {
11099
- const optional = expr.optional === true;
11100
- if (expr.computed) {
11101
- const obj2 = transpileExpression(expr.object, opts);
11102
- const key2 = expr.property;
11103
- if (key2.type === "StringLiteral") {
11104
- return optional ? `$optionalGet(${obj2}, ${JSON.stringify(key2.value)})` : `$get(${obj2}, ${JSON.stringify(key2.value)})`;
11105
- }
11106
- if (key2.type === "NumericLiteral") {
11107
- return optional ? `$optionalGet(${obj2}, ${JSON.stringify(String(key2.value))})` : `$idx(${obj2}, $lit(${key2.value}))`;
11108
- }
11109
- if (key2.type === "MemberExpression" && key2.computed !== true && key2.object.type === "Identifier" && key2.object.name === "Symbol" && key2.property.type === "Identifier") {
11110
- const symKey = JSON.stringify(`@@${key2.property.name}`);
11111
- return optional ? `$optionalGet(${obj2}, ${symKey})` : `$get(${obj2}, ${symKey})`;
11112
- }
11113
- if (isExpression(key2)) {
11114
- const k = transpileExpression(key2, opts);
11115
- return `$idx(${obj2}, ${k})`;
11116
- }
11117
- throw new NudoUnsupportedError(
11118
- `member:computed`,
11119
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11120
- );
11121
- }
11122
- if (expr.property.type !== "Identifier") {
11123
- throw new NudoUnsupportedError(
11124
- `member:${expr.property.type}`,
11125
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11126
- );
11127
- }
11128
- if (expr.property.name === "length") {
11129
- return `$len(${transpileExpression(expr.object, opts)})`;
11130
- }
11131
- const recv = transpileExpression(expr.object, opts);
11132
- const key = JSON.stringify(expr.property.name);
11133
- return optional ? `$optionalGet(${recv}, ${key})` : `$get(${recv}, ${key})`;
11134
- }
11135
- case "ArrayExpression": {
11136
- const hasSpread = expr.elements.some((el) => el?.type === "SpreadElement");
11137
- if (!hasSpread) {
11138
- const items = [];
11139
- const holes = [];
11140
- for (const el of expr.elements) {
11141
- if (!el) {
11142
- holes.push(items.length);
11143
- items.push("$lit(void 0)");
11144
- continue;
11145
- }
11146
- items.push(transpileExpression(el, opts));
11147
- }
11148
- return `$arrWithHoles([${items.join(", ")}], [${holes.join(", ")}])`;
11149
- }
11150
- let acc = null;
11151
- for (const el of expr.elements) {
11152
- if (!el) continue;
11153
- let piece;
11154
- if (el.type === "SpreadElement") {
11155
- piece = `$concat(${transpileExpression(el.argument, opts)}, $arr([]))`;
11156
- } else {
11157
- piece = `$arr([${transpileExpression(el, opts)}])`;
11158
- }
11159
- acc = acc === null ? piece : `$concat(${acc}, ${piece})`;
11160
- }
11161
- return acc ?? `$arr([])`;
11162
- }
11163
- case "AssignmentExpression": {
11164
- if (expr.operator === "=" && (expr.left.type === "ArrayPattern" || expr.left.type === "ObjectPattern")) {
11165
- const right2 = transpileExpression(expr.right, opts);
11166
- const out = [];
11167
- emitDestructure(expr.left, "__d", "", "", opts, out, { n: 0 });
11168
- return `((__d) => { ${out.join(" ")} return __d; })(${right2})`;
11169
- }
11170
- const compoundFn = COMPOUND_OPS[expr.operator];
11171
- const right = transpileExpression(expr.right, opts);
11172
- const op = expr.operator;
11173
- if (op === "||=" || op === "&&=" || op === "??=") {
11174
- const rNode = expr.right;
11175
- const emitLogicalAssign = (targetSrc, setSrc) => {
11176
- if (op === "||=") {
11177
- const sc2 = transpileShortCircuitExpr(opts, {
11178
- alwaysNodes: [],
11179
- alwaysSrc: targetSrc,
11180
- consSrc: "__test",
11181
- consNodes: [],
11182
- altSrc: right,
11183
- altNodes: [rNode]
11184
- });
11185
- return setSrc(sc2);
11186
- }
11187
- if (op === "&&=") {
11188
- const sc2 = transpileShortCircuitExpr(opts, {
11189
- alwaysNodes: [],
11190
- alwaysSrc: targetSrc,
11191
- consSrc: right,
11192
- consNodes: [rNode],
11193
- altSrc: "__test",
11194
- altNodes: []
11195
- });
11196
- return setSrc(sc2);
11197
- }
11198
- const sc = transpileShortCircuitExpr(opts, {
11199
- alwaysNodes: [],
11200
- alwaysSrc: targetSrc,
11201
- consSrc: right,
11202
- consNodes: [rNode],
11203
- altSrc: targetSrc,
11204
- altNodes: [],
11205
- testSrc: `$nullishTest(${targetSrc})`
11206
- });
11207
- return setSrc(sc);
11208
- };
11209
- if (expr.left.type === "Identifier") {
11210
- if (isConstAssignTarget(expr.left.name, opts)) {
11211
- const lhs = expr.left.name;
11212
- const skipsWrite = op === "||=" ? `$litTruth(${lhs}) === true` : op === "&&=" ? `$litTruth(${lhs}) === false` : `$litTruth($nullishTest(${lhs})) === false`;
11213
- return `((${lhs}) => { if (!(${skipsWrite})) $throwConstAssign(); return ${lhs}; })(${lhs})`;
11214
- }
11215
- return emitLogicalAssign(expr.left.name, (val) => `${expr.left.type === "Identifier" ? expr.left.name : ""} = ${val}`);
11216
- }
11217
- if (expr.left.type === "MemberExpression") {
11218
- const m = expr.left;
11219
- const path = memberPathOf(m, opts);
11220
- if (path) {
11221
- return emitLogicalAssign(readPathSrc(path), (val) => {
11222
- return `((__v) => { ${path.rootSrc} = ${setPathSrc(path, "__v")}; return __v; })(${val})`;
11223
- });
11224
- }
11225
- }
11226
- throw new NudoUnsupportedError(
11227
- `assign:${op}`,
11228
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11229
- );
11230
- }
11231
- if (expr.left.type === "MemberExpression") {
11232
- const m = expr.left;
11233
- const path = memberPathOf(m, opts);
11234
- if (path) {
11235
- const valSrc = compoundFn ? `${compoundFn}(${readPathSrc(path)}, ${right})` : right;
11236
- return `((__v) => { ${path.rootSrc} = ${setPathSrc(path, "__v")}; return __v; })(${valSrc})`;
11237
- }
11238
- if (!m.computed && m.property.type === "Identifier") {
11239
- const obj2 = transpileExpression(m.object, opts);
11240
- return `((__v) => (($set(${obj2}, ${JSON.stringify(m.property.name)}, __v)), __v))(${right})`;
11241
- }
11242
- if (m.computed) {
11243
- const obj2 = transpileExpression(m.object, opts);
11244
- const k = m.property;
11245
- if (k.type === "NumericLiteral") {
11246
- return `((__v) => (($idxSet(${obj2}, $lit(${k.value}), __v)), __v))(${right})`;
11566
+ ${emitFnBlockBody(prop.body, 1, methodOpts, { implicitReturn: false })}
11567
+ return __this;
11568
+ }`
11569
+ });
11570
+ }
11571
+ continue;
11247
11572
  }
11248
- if (k.type === "StringLiteral") {
11249
- return `((__v) => (($set(${obj2}, ${JSON.stringify(k.value)}, __v)), __v))(${right})`;
11573
+ let mBodyInner = emitFnBlockBody(prop.body, 1, methodOpts);
11574
+ let mParams = ["__this", ...bindNames];
11575
+ if (mHasArgs) {
11576
+ const bound = emitParamBindingFromArgs(prop.params, " ", methodOpts, "__nudoArgs");
11577
+ mBodyInner = [
11578
+ ` let __nudoArgs = $arguments(__margs);`,
11579
+ ...bound.prologue,
11580
+ mBodyInner
11581
+ ].join("\n");
11582
+ mParams = ["__this", "...__margs"];
11250
11583
  }
11251
- if (isExpression(k)) {
11252
- return `((__v) => (($idxSet(${obj2}, ${transpileExpression(k, opts)}, __v)), __v))(${right})`;
11584
+ const bodySrc = `{
11585
+ ${mBodyInner}
11586
+ }`;
11587
+ const fnValSrc = `$fnVal([${displayNames.map((p) => JSON.stringify(p)).join(", ")}], (${mParams.join(", ")}) => ${bodySrc}, { bindThis: true })`;
11588
+ if (isProtoKey) {
11589
+ acc = `$setKey(${acc ?? "$obj({})"}, $lit("__proto__"), ${fnValSrc})`;
11590
+ } else {
11591
+ props.push(`${mkey}: ${fnValSrc}`);
11253
11592
  }
11593
+ continue;
11254
11594
  }
11255
- throw new NudoUnsupportedError(
11256
- `assign-target`,
11257
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11258
- );
11259
- }
11260
- if (expr.left.type === "Identifier") {
11261
- const name = expr.left.name;
11262
- if (isConstAssignTarget(name, opts)) {
11263
- return `$throwConstAssign()`;
11595
+ if (prop.type !== "ObjectProperty") continue;
11596
+ if (prop.computed) {
11597
+ flushProps();
11598
+ const symK = symbolKeyOf(prop.key);
11599
+ const v2 = transpileExpression(prop.value, opts);
11600
+ const base = acc === null ? `$obj({})` : acc;
11601
+ if (symK !== null) {
11602
+ acc = `$set(${base}, ${symK}, ${v2})`;
11603
+ continue;
11604
+ }
11605
+ const k = transpileExpression(prop.key, opts);
11606
+ acc = `$setKey(${base}, ${k}, ${v2})`;
11607
+ continue;
11264
11608
  }
11265
- const cond = (opts.inLoop ?? 0) > 0 || (opts.conditionalFlow ?? 0) > 0;
11266
- const locLine = expr.loc?.start.line ?? 0;
11267
- const locCol = expr.loc?.start.column ?? 0;
11268
- const valSrc = compoundFn ? `${compoundFn}(${name}, ${right})` : right;
11269
- const bindSrc = !opts.inFunction ? ` $recordBinding(${JSON.stringify(name)}, __v);` : "";
11270
- return `((__v) => { $assignRecord(${JSON.stringify(name)}, ${name}, __v, ${locLine}, ${locCol}, ${cond});${bindSrc} return ${name} = __v; })(${valSrc})`;
11271
- }
11272
- throw new NudoUnsupportedError(
11273
- `assign-target`,
11274
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11275
- );
11276
- }
11277
- case "CallExpression":
11278
- case "OptionalCallExpression": {
11279
- const exprAny = expr;
11280
- const optionalCall = exprAny.type === "OptionalCallExpression" || exprAny.optional === true;
11281
- const callee = expr.callee;
11282
- if (callee.type === "Super" && opts.thisParam && opts.className) {
11283
- const args2 = expr.arguments.map(
11284
- (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11285
- ).join(", ");
11286
- return `${opts.thisParam} = $super(${opts.thisParam}, ${JSON.stringify(opts.className)}, [${args2}])`;
11287
- }
11288
- if (callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Super" && callee.property.type === "Identifier" && opts.thisParam && opts.className) {
11289
- const args2 = expr.arguments.map(
11290
- (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11291
- ).join(", ");
11292
- return `$invokeSuper(${opts.thisParam}, ${JSON.stringify(opts.className)}, ${JSON.stringify(callee.property.name)}, [${args2}])`;
11293
- }
11294
- if (callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "require" && callee.property.type === "Identifier" && callee.property.name === "resolve") {
11295
- const spec = foldRequireSpecArg(expr.arguments[0]);
11296
- if (spec !== void 0) return `$lit(${JSON.stringify(spec)})`;
11297
- return "$unknown()";
11298
- }
11299
- if (callee.type === "Identifier" && callee.name === "require") {
11300
- const spec = foldRequireSpecArg(expr.arguments[0]);
11301
- if (spec !== void 0) return `__nudoRequire(${JSON.stringify(spec)})`;
11302
- return "$unknown()";
11303
- }
11304
- if ((callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") && !callee.computed && callee.property.type === "Identifier") {
11305
- const recv = transpileExpression(callee.object, opts);
11306
- const args2 = expr.arguments.map(
11307
- (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11308
- ).join(", ");
11309
- const name = JSON.stringify(callee.property.name);
11310
- const opt = optionalCall || callee.optional === true;
11311
- const loc = expr.loc;
11312
- const locArg = loc ? `, [${loc.start.line}, ${loc.start.column}]` : "";
11313
- if (!opt && REGEX_STATEFUL_NAMES.has(callee.property.name) && callee.object.type === "Identifier") {
11314
- const recvName = callee.object.name;
11315
- return `(() => { const __v = $invoke(${recvName}, ${name}, [${args2}]${locArg}); ${recvName} = $reStateCall(${recvName}, ${name}, [${args2}]); return __v; })()`;
11609
+ const key = (() => {
11610
+ const k = staticKeyOf(prop.key);
11611
+ return k === null ? null : JSON.stringify(k);
11612
+ })();
11613
+ if (key === null) continue;
11614
+ if (!prop.computed && key === '"__proto__"') {
11615
+ protoSet = transpileExpression(prop.value, opts);
11616
+ continue;
11316
11617
  }
11317
- return opt ? `$optionalInvoke(${recv}, ${name}, [${args2}])` : `$invoke(${recv}, ${name}, [${args2}]${locArg})`;
11318
- }
11319
- if (callee.type === "Identifier" && !HOST_INTRINSIC_SET.has(callee.name)) {
11320
- const argSrcs = [];
11321
- const argLocSrcs = [];
11322
- for (const a of expr.arguments) {
11323
- if (a.type === "SpreadElement") {
11324
- argSrcs.push(`...$elems(${transpileExpression(a.argument, opts)})`);
11325
- argLocSrcs.push("null");
11326
- } else {
11327
- argSrcs.push(transpileExpression(a, opts));
11328
- const al = a.loc;
11329
- argLocSrcs.push(al ? `[${al.start.line}, ${al.start.column}]` : "null");
11618
+ if (prop.value.type === "FunctionExpression" && !prop.value.async) {
11619
+ const fn = prop.value;
11620
+ if (!fn.generator) {
11621
+ const displayNames = paramDisplayNames(fn.params);
11622
+ const bindNames = methodBindNames(fn.params);
11623
+ const mHasArgs = fnBodyHasOwnArguments({ body: fn.body });
11624
+ const methodOpts = {
11625
+ ...opts,
11626
+ inLoop: 0,
11627
+ thisParam: "__this",
11628
+ argsBinding: mHasArgs ? "__nudoArgs" : void 0
11629
+ };
11630
+ let mBodyInner = emitFnBlockBody(fn.body, 1, methodOpts);
11631
+ let mParams = ["__this", ...bindNames];
11632
+ if (mHasArgs) {
11633
+ const bound = emitParamBindingFromArgs(fn.params, " ", methodOpts, "__nudoArgs");
11634
+ mBodyInner = [
11635
+ ` let __nudoArgs = $arguments(__margs);`,
11636
+ ...bound.prologue,
11637
+ mBodyInner
11638
+ ].join("\n");
11639
+ mParams = ["__this", "...__margs"];
11640
+ }
11641
+ const bodySrc = `{
11642
+ ${mBodyInner}
11643
+ }`;
11644
+ props.push(
11645
+ `${key}: $fnVal([${displayNames.map((p) => JSON.stringify(p)).join(", ")}], (${mParams.join(", ")}) => ${bodySrc}, { bindThis: true })`
11646
+ );
11647
+ continue;
11330
11648
  }
11331
11649
  }
11332
- const loc = expr.loc;
11333
- const locArg = loc ? `, [${loc.start.line}, ${loc.start.column}]` : "";
11334
- const argLocArg = loc ? `, [${argLocSrcs.join(", ")}]` : "";
11335
- const calleeRef = opts.lenientGlobals ? `(typeof ${callee.name} !== "undefined" ? ${callee.name} : void 0)` : callee.name;
11336
- return `$callNamed(${JSON.stringify(callee.name)}, ${calleeRef}, [${argSrcs.join(", ")}]${locArg}${argLocArg})`;
11650
+ const valSrc = transpileExpression(prop.value, opts);
11651
+ props.push(`${key}: ${valSrc}`);
11337
11652
  }
11338
- const args = expr.arguments.map(
11339
- (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11340
- ).join(", ");
11341
- const c = callee.type === "Identifier" ? callee.name : isExpression(callee) ? transpileExpression(callee, opts) : "/* callee */";
11342
- if (callee.type !== "Identifier") {
11343
- return `$call(${c}, [${args}])`;
11653
+ flushProps();
11654
+ let result = acc ?? `$obj({})`;
11655
+ for (const r of accRegs) {
11656
+ result = `$objAccessor(${result}, ${r.key}, ${r.get ?? "null"}, ${r.set ?? "null"})`;
11344
11657
  }
11345
- return `${c}(${args})`;
11658
+ if (protoSet !== null) result = `$setProto(${result}, ${protoSet})`;
11659
+ return result;
11346
11660
  }
11347
- case "ArrowFunctionExpression":
11348
- case "FunctionExpression": {
11349
- const fn = expr;
11350
- const isArrow = expr.type === "ArrowFunctionExpression";
11351
- const hasThis = !isArrow && fnBodyHasThis(fn);
11352
- const hasArgs = !isArrow && fnBodyHasOwnArguments(fn);
11353
- const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
11354
- const fnBodyOpts = {
11355
- ...opts,
11356
- inLoop: 0,
11357
- inFunction: true,
11358
- ...hasThis ? { thisParam: "__this" } : {},
11359
- ...isArrow ? {} : { argsBinding: hasArgs ? "__nudoArgs" : void 0 }
11360
- };
11361
- const useArgsSlot = hasArgs && !hasThis;
11362
- const restRaw = rest && !useArgsSlot ? `__rest_raw` : rest;
11363
- const restPrologue = rest && !useArgsSlot && restRaw ? [` const ${rest} = $arr(${restRaw});`] : [];
11364
- const paramParts = restRaw ? [...sig, `...${restRaw}`] : sig;
11365
- const nameList = `[${paramDisplayNames(fn.params).map((p) => JSON.stringify(p)).join(", ")}]`;
11366
- const thisPrologue = hasThis ? [`const __this = $rawThis(this);`] : [];
11367
- let argsSlotPrologue = [];
11368
- let argsParamParts = paramParts;
11369
- if (useArgsSlot) {
11370
- const bound = emitParamBindingFromArgs(fn.params, " ", fnBodyOpts, "__nudoArgs");
11371
- argsSlotPrologue = [` let __nudoArgs = $arguments(__allArgs);`, ...bound.prologue];
11372
- argsParamParts = ["...__allArgs"];
11373
- } else if (hasArgs && hasThis) {
11374
- argsSlotPrologue = [` let __nudoArgs = $arguments(arguments);`];
11375
- }
11376
- const allPrologue = useArgsSlot ? [...argsSlotPrologue, ...thisPrologue] : [...prologue, ...restPrologue, ...thisPrologue, ...argsSlotPrologue];
11377
- if (fn.body.type === "BlockStatement") {
11378
- const inner = withImplicitReturn(
11379
- fn.body,
11380
- [...allPrologue, transpileFnBodyStmts(fn.body.body, 1, fnBodyOpts)].join("\n"),
11381
- 1
11382
- );
11383
- if (hasThis) {
11384
- const wrap = fn.async ? `function (${argsParamParts.join(", ")}) { return $async(() => {
11385
- ${inner}
11386
- }); }` : `function (${argsParamParts.join(", ")}) {
11387
- ${inner}
11388
- }`;
11389
- return `$fnVal(${nameList}, ${wrap})`;
11661
+ case "MemberExpression":
11662
+ case "OptionalMemberExpression": {
11663
+ const optional = expr.optional === true;
11664
+ if (expr.computed) {
11665
+ const obj2 = transpileExpression(expr.object, opts);
11666
+ const key2 = expr.property;
11667
+ if (key2.type === "StringLiteral") {
11668
+ return optional ? `$optionalGet(${obj2}, ${JSON.stringify(key2.value)})` : `$get(${obj2}, ${JSON.stringify(key2.value)})`;
11390
11669
  }
11391
- if (fn.async) {
11392
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => $async(() => {
11393
- ${inner}
11394
- }))`;
11670
+ if (key2.type === "NumericLiteral") {
11671
+ return optional ? `$optionalGet(${obj2}, ${JSON.stringify(String(key2.value))})` : `$idx(${obj2}, $lit(${key2.value}))`;
11395
11672
  }
11396
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11397
- ${inner}
11398
- })`;
11399
- }
11400
- const bodySrc = transpileExpression(fn.body, fnBodyOpts);
11401
- if (allPrologue.length > 0 || hasThis) {
11402
- const rebinds2 = emitArrMutatorRebinds(fn.body, fnBodyOpts, " ");
11403
- const inner = [
11404
- ...allPrologue,
11405
- ...rebinds2.map((l) => ` ${l}`),
11406
- ` return ${fn.async ? `$async(() => ${bodySrc})` : bodySrc};`
11407
- ].join("\n");
11408
- if (hasThis) {
11409
- const wrap = `function (${argsParamParts.join(", ")}) {
11410
- ${inner}
11411
- }`;
11412
- return `$fnVal(${nameList}, ${wrap})`;
11673
+ if (key2.type === "MemberExpression" && key2.computed !== true && key2.object.type === "Identifier" && key2.object.name === "Symbol" && key2.property.type === "Identifier") {
11674
+ const symKey = JSON.stringify(`@@${key2.property.name}`);
11675
+ return optional ? `$optionalGet(${obj2}, ${symKey})` : `$get(${obj2}, ${symKey})`;
11413
11676
  }
11414
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11415
- ${inner}
11416
- })`;
11677
+ if (isExpression(key2)) {
11678
+ const k = transpileExpression(key2, opts);
11679
+ return `$idx(${obj2}, ${k})`;
11680
+ }
11681
+ throw new NudoUnsupportedError(
11682
+ `member:computed`,
11683
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11684
+ );
11417
11685
  }
11418
- const rebinds = emitArrMutatorRebinds(fn.body, fnBodyOpts, " ");
11419
- if (rebinds.length > 0) {
11420
- const inner = [
11421
- ...rebinds.map((l) => ` ${l}`),
11422
- ` return ${fn.async ? `$async(() => ${bodySrc})` : bodySrc};`
11423
- ].join("\n");
11424
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11425
- ${inner}
11426
- })`;
11686
+ if (expr.property.type !== "Identifier") {
11687
+ throw new NudoUnsupportedError(
11688
+ `member:${expr.property.type}`,
11689
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11690
+ );
11427
11691
  }
11428
- if (fn.async) {
11429
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => $async(() => ${bodySrc}))`;
11692
+ if (expr.property.name === "length") {
11693
+ return `$len(${transpileExpression(expr.object, opts)})`;
11430
11694
  }
11431
- return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => ${bodySrc})`;
11695
+ const recv = transpileExpression(expr.object, opts);
11696
+ const key = JSON.stringify(expr.property.name);
11697
+ return optional ? `$optionalGet(${recv}, ${key})` : `$get(${recv}, ${key})`;
11432
11698
  }
11433
- case "MetaProperty":
11434
- return "$importMeta()";
11435
- case "ImportExpression": {
11436
- const specSrc = transpileExpression(expr.source, opts);
11437
- return `$dynamicImport(${specSrc})`;
11699
+ case "ArrayExpression": {
11700
+ const hasSpread = expr.elements.some((el) => el?.type === "SpreadElement");
11701
+ if (!hasSpread) {
11702
+ const items = [];
11703
+ const holes = [];
11704
+ for (const el of expr.elements) {
11705
+ if (!el) {
11706
+ holes.push(items.length);
11707
+ items.push("$lit(void 0)");
11708
+ continue;
11709
+ }
11710
+ items.push(transpileExpression(el, opts));
11711
+ }
11712
+ return `$arrWithHoles([${items.join(", ")}], [${holes.join(", ")}])`;
11713
+ }
11714
+ let acc = null;
11715
+ for (const el of expr.elements) {
11716
+ if (!el) continue;
11717
+ let piece;
11718
+ if (el.type === "SpreadElement") {
11719
+ piece = `$concat(${transpileExpression(el.argument, opts)}, $arr([]))`;
11720
+ } else {
11721
+ piece = `$arr([${transpileExpression(el, opts)}])`;
11722
+ }
11723
+ acc = acc === null ? piece : `$concat(${acc}, ${piece})`;
11724
+ }
11725
+ return acc ?? `$arr([])`;
11438
11726
  }
11439
- case "JSXElement":
11440
- case "JSXFragment":
11441
- return "$unknown()";
11442
- default:
11443
- throw new NudoUnsupportedError(
11444
- `expression:${expr.type}`,
11445
- expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11446
- );
11447
- }
11448
- }
11449
- bindTranspileExpression(transpileExpression);
11450
- bindTranspileShortCircuit(transpileShortCircuitExpr);
11451
-
11452
- // src/algebra/exec/transpile.ts
11453
- function transpileSource(source, opts = {}) {
11454
- const file = parseSource(source);
11455
- return transpileFile(file, { ...opts, source: opts.source ?? source });
11456
- }
11457
- function runtimeImportOf(runtime) {
11458
- return `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`;
11459
- }
11460
- function transpileFile(file, opts = {}) {
11461
- const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
11462
- const lines = [
11463
- `// nudo evaluator transpile \u2014 values are Abs; operators are overloaded calls`,
11464
- `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`,
11465
- ``
11466
- ];
11467
- for (const stmt of file.program.body) {
11468
- lines.push(transpileStatement(stmt, 0, opts));
11469
- }
11470
- return lines.join("\n") + "\n";
11471
- }
11472
- function transpile(source, opts) {
11473
- return transpileSource(source, opts);
11474
- }
11475
-
11476
- // src/algebra/exec/runtime/state.ts
11477
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
11478
- function writeInPlace(target, next) {
11479
- target.shape = next.shape;
11480
- target.conf = next.conf;
11481
- target.term = void 0;
11482
- target.pred = void 0;
11483
- return target;
11484
- }
11485
- function clearStaleTermPred(v2) {
11486
- v2.term = void 0;
11487
- v2.pred = void 0;
11488
- }
11489
- var phi = pTrue;
11490
- function currentExecPhi() {
11491
- return phi;
11492
- }
11493
- function withExecPhi(p, body) {
11494
- const prev = phi;
11495
- phi = p;
11496
- try {
11497
- return body();
11498
- } finally {
11499
- phi = prev;
11500
- }
11501
- }
11502
- var noBody2 = { type: "BlockStatement", body: [], directives: [] };
11503
- function asAbsVal(v2) {
11504
- if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
11505
- if (typeof v2 === "function") {
11506
- const n = Math.max(0, v2.length);
11507
- const params = Array.from({ length: n }, (_, i) => `arg${i}`);
11508
- return absFunction(params, {
11509
- body: noBody2,
11510
- // 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
11511
- apply: (args) => callAtFunctionBoundary(() => v2(...args))
11512
- });
11513
- }
11514
- return $lit(v2);
11515
- }
11516
- function callAtFunctionBoundary(body) {
11517
- let forwarded = [];
11518
- try {
11519
- return runWithLoopExits(() => {
11520
- try {
11521
- const r = body();
11522
- forwarded = takeThrowExits();
11523
- return r;
11524
- } catch (e) {
11525
- forwarded = takeThrowExits();
11526
- if (isNudoReturn(e)) return e.absValue;
11527
- throw e;
11727
+ case "AssignmentExpression": {
11728
+ if (expr.operator === "=" && (expr.left.type === "ArrayPattern" || expr.left.type === "ObjectPattern")) {
11729
+ const right2 = transpileExpression(expr.right, opts);
11730
+ const out = [];
11731
+ emitDestructure(expr.left, "__d", "", "", opts, out, { n: 0 });
11732
+ return `((__d) => { ${out.join(" ")} return __d; })(${right2})`;
11528
11733
  }
11529
- });
11530
- } finally {
11531
- for (const x of forwarded) pushThrowExit(x);
11532
- }
11533
- }
11534
- function $fnVal(params, impl, opts) {
11535
- return absFunction(params, {
11536
- body: noBody2,
11537
- // bindThis(对象方法):receiver 走首参注入,无宿主 this;
11538
- // 非方法 fn:宿主 this 传递(call/apply/bind 的 thisArg 经 $rawThis 进入函数体)
11539
- apply: opts?.bindThis ? (args) => callAtFunctionBoundary(() => impl(...args)) : (args, thisVal) => callAtFunctionBoundary(() => impl.apply(thisVal, args)),
11540
- ...opts?.bindThis ? { bindThis: true } : {}
11541
- });
11542
- }
11543
- function $rawThis(v2) {
11544
- if (v2 === void 0 || v2 === globalThis) return $lit(void 0);
11545
- if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
11546
- return $lit(v2);
11547
- }
11548
- function throwStrictWrite() {
11549
- throw new NudoThrow(errorTypeAbs("TypeError"));
11550
- }
11551
- function $throwConstAssign() {
11552
- throw new NudoThrow(errorTypeAbs("TypeError"));
11553
- }
11554
- function $litTruth(a) {
11555
- return litTruth(a);
11556
- }
11557
- function $lit(v2) {
11558
- if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
11559
- return v2;
11560
- }
11561
- return litAbsFromJs(v2);
11562
- }
11563
- function litAbsFromJs(v2, depth = 0) {
11564
- if (v2 === null || v2 === void 0) {
11565
- return abs({ k: "unknown" }, { op: "lit", value: v2 }, pTrue, "exact");
11566
- }
11567
- const t = typeof v2;
11568
- if (t === "number" || t === "string" || t === "boolean" || t === "bigint") {
11569
- return abs(
11570
- { k: "prim", type: t },
11571
- { op: "lit", value: v2 },
11572
- pTrue,
11573
- "exact"
11574
- );
11575
- }
11576
- if (depth < 8) {
11577
- if (Array.isArray(v2)) {
11578
- const els = v2.map((x) => litAbsFromJs(x, depth + 1));
11579
- if (shouldWidenArrayLiteral(els.length)) {
11580
- return abs(
11581
- { k: "arr", element: els.reduce((x, y) => joinAbs(x, y)) },
11582
- void 0,
11583
- void 0,
11584
- widenedArrayConf()
11734
+ const compoundFn = COMPOUND_OPS[expr.operator];
11735
+ const right = transpileExpression(expr.right, opts);
11736
+ const op = expr.operator;
11737
+ if (op === "||=" || op === "&&=" || op === "??=") {
11738
+ const rNode = expr.right;
11739
+ const emitLogicalAssign = (targetSrc, setSrc) => {
11740
+ if (op === "||=") {
11741
+ const sc2 = transpileShortCircuitExpr(opts, {
11742
+ alwaysNodes: [],
11743
+ alwaysSrc: targetSrc,
11744
+ consSrc: "__test",
11745
+ consNodes: [],
11746
+ altSrc: right,
11747
+ altNodes: [rNode]
11748
+ });
11749
+ return setSrc(sc2);
11750
+ }
11751
+ if (op === "&&=") {
11752
+ const sc2 = transpileShortCircuitExpr(opts, {
11753
+ alwaysNodes: [],
11754
+ alwaysSrc: targetSrc,
11755
+ consSrc: right,
11756
+ consNodes: [rNode],
11757
+ altSrc: "__test",
11758
+ altNodes: []
11759
+ });
11760
+ return setSrc(sc2);
11761
+ }
11762
+ const sc = transpileShortCircuitExpr(opts, {
11763
+ alwaysNodes: [],
11764
+ alwaysSrc: targetSrc,
11765
+ consSrc: right,
11766
+ consNodes: [rNode],
11767
+ altSrc: targetSrc,
11768
+ altNodes: [],
11769
+ testSrc: `$nullishTest(${targetSrc})`
11770
+ });
11771
+ return setSrc(sc);
11772
+ };
11773
+ if (expr.left.type === "Identifier") {
11774
+ if (isConstAssignTarget(expr.left.name, opts)) {
11775
+ const lhs = expr.left.name;
11776
+ const skipsWrite = op === "||=" ? `$litTruth(${lhs}) === true` : op === "&&=" ? `$litTruth(${lhs}) === false` : `$litTruth($nullishTest(${lhs})) === false`;
11777
+ return `((${lhs}) => { if (!(${skipsWrite})) $throwConstAssign(); return ${lhs}; })(${lhs})`;
11778
+ }
11779
+ return emitLogicalAssign(expr.left.name, (val) => `${expr.left.type === "Identifier" ? expr.left.name : ""} = ${val}`);
11780
+ }
11781
+ if (expr.left.type === "MemberExpression") {
11782
+ const m = expr.left;
11783
+ const path = memberPathOf(m, opts);
11784
+ if (path) {
11785
+ return emitLogicalAssign(readPathSrc(path), (val) => {
11786
+ return `((__v) => { ${path.rootSrc} = ${setPathSrc(path, "__v")}; return __v; })(${val})`;
11787
+ });
11788
+ }
11789
+ }
11790
+ throw new NudoUnsupportedError(
11791
+ `assign:${op}`,
11792
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11585
11793
  );
11586
11794
  }
11587
- return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
11795
+ if (expr.left.type === "MemberExpression") {
11796
+ const m = expr.left;
11797
+ const path = memberPathOf(m, opts);
11798
+ if (path) {
11799
+ const valSrc = compoundFn ? `${compoundFn}(${readPathSrc(path)}, ${right})` : right;
11800
+ return `((__v) => { ${path.rootSrc} = ${setPathSrc(path, "__v")}; return __v; })(${valSrc})`;
11801
+ }
11802
+ if (!m.computed && m.property.type === "Identifier") {
11803
+ const obj2 = transpileExpression(m.object, opts);
11804
+ return `((__v) => (($set(${obj2}, ${JSON.stringify(m.property.name)}, __v)), __v))(${right})`;
11805
+ }
11806
+ if (m.computed) {
11807
+ const obj2 = transpileExpression(m.object, opts);
11808
+ const k = m.property;
11809
+ if (k.type === "NumericLiteral") {
11810
+ return `((__v) => (($idxSet(${obj2}, $lit(${k.value}), __v)), __v))(${right})`;
11811
+ }
11812
+ if (k.type === "StringLiteral") {
11813
+ return `((__v) => (($set(${obj2}, ${JSON.stringify(k.value)}, __v)), __v))(${right})`;
11814
+ }
11815
+ if (isExpression(k)) {
11816
+ return `((__v) => (($idxSet(${obj2}, ${transpileExpression(k, opts)}, __v)), __v))(${right})`;
11817
+ }
11818
+ }
11819
+ throw new NudoUnsupportedError(
11820
+ `assign-target`,
11821
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11822
+ );
11823
+ }
11824
+ if (expr.left.type === "Identifier") {
11825
+ const name = expr.left.name;
11826
+ if (isConstAssignTarget(name, opts)) {
11827
+ return `$throwConstAssign()`;
11828
+ }
11829
+ const cond = (opts.inLoop ?? 0) > 0 || (opts.conditionalFlow ?? 0) > 0;
11830
+ const locLine = expr.loc?.start.line ?? 0;
11831
+ const locCol = expr.loc?.start.column ?? 0;
11832
+ const valSrc = compoundFn ? `${compoundFn}(${name}, ${right})` : right;
11833
+ const bindSrc = !opts.inFunction ? ` $recordBinding(${JSON.stringify(name)}, __v);` : "";
11834
+ return `((__v) => { $assignRecord(${JSON.stringify(name)}, ${name}, __v, ${locLine}, ${locCol}, ${cond});${bindSrc} return ${name} = __v; })(${valSrc})`;
11835
+ }
11836
+ throw new NudoUnsupportedError(
11837
+ `assign-target`,
11838
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
11839
+ );
11588
11840
  }
11589
- if (t === "object") {
11590
- const proto = Object.getPrototypeOf(v2);
11591
- if (proto === Object.prototype || proto === null) {
11592
- const slots = {};
11593
- for (const [k, val] of Object.entries(v2)) {
11594
- Object.defineProperty(slots, k, {
11595
- value: { value: litAbsFromJs(val, depth + 1) },
11596
- enumerable: true,
11597
- writable: true,
11598
- configurable: true
11599
- });
11841
+ case "CallExpression":
11842
+ case "OptionalCallExpression": {
11843
+ const exprAny = expr;
11844
+ const optionalCall = exprAny.type === "OptionalCallExpression" || exprAny.optional === true;
11845
+ const callee = expr.callee;
11846
+ if (callee.type === "Super" && opts.thisParam && opts.className) {
11847
+ const args2 = expr.arguments.map(
11848
+ (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11849
+ ).join(", ");
11850
+ return `${opts.thisParam} = $super(${opts.thisParam}, ${JSON.stringify(opts.className)}, [${args2}])`;
11851
+ }
11852
+ if (callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Super" && callee.property.type === "Identifier" && opts.thisParam && opts.className) {
11853
+ const args2 = expr.arguments.map(
11854
+ (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11855
+ ).join(", ");
11856
+ return `$invokeSuper(${opts.thisParam}, ${JSON.stringify(opts.className)}, ${JSON.stringify(callee.property.name)}, [${args2}])`;
11857
+ }
11858
+ if (callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "require" && callee.property.type === "Identifier" && callee.property.name === "resolve") {
11859
+ const spec = foldRequireSpecArg(expr.arguments[0]);
11860
+ if (spec !== void 0) return `$lit(${JSON.stringify(spec)})`;
11861
+ return "$unknown()";
11862
+ }
11863
+ if (callee.type === "Identifier" && callee.name === "require") {
11864
+ const spec = foldRequireSpecArg(expr.arguments[0]);
11865
+ if (spec !== void 0) return `__nudoRequire(${JSON.stringify(spec)})`;
11866
+ return "$unknown()";
11867
+ }
11868
+ if ((callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") && !callee.computed && callee.property.type === "Identifier") {
11869
+ const recv = transpileExpression(callee.object, opts);
11870
+ const args2 = expr.arguments.map(
11871
+ (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11872
+ ).join(", ");
11873
+ const name = JSON.stringify(callee.property.name);
11874
+ const opt = optionalCall || callee.optional === true;
11875
+ const loc = expr.loc;
11876
+ const locArg = loc ? `, [${loc.start.line}, ${loc.start.column}]` : "";
11877
+ if (!opt && REGEX_STATEFUL_NAMES.has(callee.property.name) && callee.object.type === "Identifier") {
11878
+ const recvName = callee.object.name;
11879
+ return `(() => { const __v = $invoke(${recvName}, ${name}, [${args2}]${locArg}); ${recvName} = $reStateCall(${recvName}, ${name}, [${args2}]); return __v; })()`;
11600
11880
  }
11601
- return objOf(slots);
11881
+ return opt ? `$optionalInvoke(${recv}, ${name}, [${args2}])` : `$invoke(${recv}, ${name}, [${args2}]${locArg})`;
11882
+ }
11883
+ if (callee.type === "Identifier" && !HOST_INTRINSIC_SET.has(callee.name)) {
11884
+ const argSrcs = [];
11885
+ const argLocSrcs = [];
11886
+ for (const a of expr.arguments) {
11887
+ if (a.type === "SpreadElement") {
11888
+ argSrcs.push(`...$elems(${transpileExpression(a.argument, opts)})`);
11889
+ argLocSrcs.push("null");
11890
+ } else {
11891
+ argSrcs.push(transpileExpression(a, opts));
11892
+ const al = a.loc;
11893
+ argLocSrcs.push(al ? `[${al.start.line}, ${al.start.column}]` : "null");
11894
+ }
11895
+ }
11896
+ const loc = expr.loc;
11897
+ const locArg = loc ? `, [${loc.start.line}, ${loc.start.column}]` : "";
11898
+ const argLocArg = loc ? `, [${argLocSrcs.join(", ")}]` : "";
11899
+ const calleeRef = opts.lenientGlobals ? `(typeof ${callee.name} !== "undefined" ? ${callee.name} : void 0)` : callee.name;
11900
+ return `$callNamed(${JSON.stringify(callee.name)}, ${calleeRef}, [${argSrcs.join(", ")}]${locArg}${argLocArg})`;
11901
+ }
11902
+ const args = expr.arguments.map(
11903
+ (a) => a.type === "SpreadElement" ? `...$elems(${transpileExpression(a.argument, opts)})` : transpileExpression(a, opts)
11904
+ ).join(", ");
11905
+ const c = callee.type === "Identifier" ? callee.name : isExpression(callee) ? transpileExpression(callee, opts) : "/* callee */";
11906
+ if (callee.type !== "Identifier") {
11907
+ return `$call(${c}, [${args}])`;
11602
11908
  }
11909
+ return `${c}(${args})`;
11603
11910
  }
11911
+ case "ArrowFunctionExpression":
11912
+ case "FunctionExpression": {
11913
+ const fn = expr;
11914
+ const isArrow = expr.type === "ArrowFunctionExpression";
11915
+ const hasThis = !isArrow && fnBodyHasThis(fn);
11916
+ const hasArgs = !isArrow && fnBodyHasOwnArguments(fn);
11917
+ const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
11918
+ const fnBodyOpts = {
11919
+ ...opts,
11920
+ inLoop: 0,
11921
+ inFunction: true,
11922
+ ...hasThis ? { thisParam: "__this" } : {},
11923
+ ...isArrow ? {} : { argsBinding: hasArgs ? "__nudoArgs" : void 0 }
11924
+ };
11925
+ const useArgsSlot = hasArgs && !hasThis;
11926
+ const restRaw = rest && !useArgsSlot ? `__rest_raw` : rest;
11927
+ const restPrologue = rest && !useArgsSlot && restRaw ? [` const ${rest} = $arr(${restRaw});`] : [];
11928
+ const paramParts = restRaw ? [...sig, `...${restRaw}`] : sig;
11929
+ const nameList = `[${paramDisplayNames(fn.params).map((p) => JSON.stringify(p)).join(", ")}]`;
11930
+ const thisPrologue = hasThis ? [`const __this = $rawThis(this);`] : [];
11931
+ let argsSlotPrologue = [];
11932
+ let argsParamParts = paramParts;
11933
+ if (useArgsSlot) {
11934
+ const bound = emitParamBindingFromArgs(fn.params, " ", fnBodyOpts, "__nudoArgs");
11935
+ argsSlotPrologue = [` let __nudoArgs = $arguments(__allArgs);`, ...bound.prologue];
11936
+ argsParamParts = ["...__allArgs"];
11937
+ } else if (hasArgs && hasThis) {
11938
+ argsSlotPrologue = [` let __nudoArgs = $arguments(arguments);`];
11939
+ }
11940
+ const allPrologue = useArgsSlot ? [...argsSlotPrologue, ...thisPrologue] : [...prologue, ...restPrologue, ...thisPrologue, ...argsSlotPrologue];
11941
+ if (fn.body.type === "BlockStatement") {
11942
+ const inner = withImplicitReturn(
11943
+ fn.body,
11944
+ [...allPrologue, transpileFnBodyStmts(fn.body.body, 1, fnBodyOpts)].join("\n"),
11945
+ 1
11946
+ );
11947
+ if (hasThis) {
11948
+ const wrap = fn.async ? `function (${argsParamParts.join(", ")}) { return $async(() => {
11949
+ ${inner}
11950
+ }); }` : `function (${argsParamParts.join(", ")}) {
11951
+ ${inner}
11952
+ }`;
11953
+ return `$fnVal(${nameList}, ${wrap})`;
11954
+ }
11955
+ if (fn.async) {
11956
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => $async(() => {
11957
+ ${inner}
11958
+ }))`;
11959
+ }
11960
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11961
+ ${inner}
11962
+ })`;
11963
+ }
11964
+ const bodySrc = transpileExpression(fn.body, fnBodyOpts);
11965
+ if (allPrologue.length > 0 || hasThis) {
11966
+ const rebinds2 = emitArrMutatorRebinds(fn.body, fnBodyOpts, " ");
11967
+ const inner = [
11968
+ ...allPrologue,
11969
+ ...rebinds2.map((l) => ` ${l}`),
11970
+ ` return ${fn.async ? `$async(() => ${bodySrc})` : bodySrc};`
11971
+ ].join("\n");
11972
+ if (hasThis) {
11973
+ const wrap = `function (${argsParamParts.join(", ")}) {
11974
+ ${inner}
11975
+ }`;
11976
+ return `$fnVal(${nameList}, ${wrap})`;
11977
+ }
11978
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11979
+ ${inner}
11980
+ })`;
11981
+ }
11982
+ const rebinds = emitArrMutatorRebinds(fn.body, fnBodyOpts, " ");
11983
+ if (rebinds.length > 0) {
11984
+ const inner = [
11985
+ ...rebinds.map((l) => ` ${l}`),
11986
+ ` return ${fn.async ? `$async(() => ${bodySrc})` : bodySrc};`
11987
+ ].join("\n");
11988
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => {
11989
+ ${inner}
11990
+ })`;
11991
+ }
11992
+ if (fn.async) {
11993
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => $async(() => ${bodySrc}))`;
11994
+ }
11995
+ return `$fnVal(${nameList}, (${argsParamParts.join(", ")}) => ${bodySrc})`;
11996
+ }
11997
+ case "MetaProperty":
11998
+ return "$importMeta()";
11999
+ case "ImportExpression": {
12000
+ const specSrc = transpileExpression(expr.source, opts);
12001
+ return `$dynamicImport(${specSrc})`;
12002
+ }
12003
+ case "JSXElement":
12004
+ case "JSXFragment":
12005
+ return "$unknown()";
12006
+ default:
12007
+ throw new NudoUnsupportedError(
12008
+ `expression:${expr.type}`,
12009
+ expr.loc ? { line: expr.loc.start.line, column: expr.loc.start.column } : void 0
12010
+ );
11604
12011
  }
11605
- return unknown;
11606
- }
11607
- function litTruth(a) {
11608
- if (a.term?.op === "lit") {
11609
- return Boolean(a.term.value);
11610
- }
11611
- switch (a.shape.k) {
11612
- case "obj":
11613
- case "arr":
11614
- case "tuple":
11615
- case "fn":
11616
- case "brand":
11617
- case "eff":
11618
- return true;
11619
- case "prim":
11620
- return a.shape.type === "symbol" ? true : void 0;
11621
- case "never":
11622
- return false;
11623
- default:
11624
- return void 0;
11625
- }
11626
- }
11627
- function isDefinitelyTrue(a) {
11628
- return litTruth(a) === true;
11629
- }
11630
- function isDefinitelyFalse(a) {
11631
- const t = litTruth(a);
11632
- if (t === false) return true;
11633
- if (a.shape.k === "never") return true;
11634
- return false;
11635
- }
11636
- function undef() {
11637
- return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
11638
- }
11639
- var loopExitsAls = new AsyncLocalStorage2();
11640
- var throwExitsAls = new AsyncLocalStorage2();
11641
- var tryMarksAls = new AsyncLocalStorage2();
11642
- var softFrameActiveAls = new AsyncLocalStorage2();
11643
- function runWithLoopExits(body) {
11644
- return loopExitsAls.run(
11645
- [],
11646
- () => throwExitsAls.run(
11647
- [],
11648
- () => tryMarksAls.run([], () => softFrameActiveAls.run([], body))
11649
- )
11650
- );
11651
- }
11652
- function takeLoopExits() {
11653
- return loopExitsAls.getStore() ?? [];
11654
- }
11655
- function takeThrowExits() {
11656
- return throwExitsAls.getStore() ?? [];
11657
- }
11658
- function pushLoopExit(v2) {
11659
- loopExitsAls.getStore()?.push(v2);
11660
- }
11661
- function pushThrowExit(v2) {
11662
- throwExitsAls.getStore()?.push(v2);
11663
- }
11664
- function $pushLoopExit(v2) {
11665
- pushLoopExit(v2);
11666
- }
11667
- function $tryMark() {
11668
- $tryMarkSoft();
11669
- softFrameActiveAls.getStore()?.push(true);
11670
- const store = throwExitsAls.getStore();
11671
- const m = store?.length ?? 0;
11672
- tryMarksAls.getStore()?.push(m);
11673
- return m;
11674
- }
11675
- function $tryCurrentMark() {
11676
- const stack = tryMarksAls.getStore();
11677
- return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
11678
- }
11679
- function $tryPopMark() {
11680
- tryMarksAls.getStore()?.pop();
11681
- const soft = softFrameActiveAls.getStore();
11682
- if (soft && soft.length > 0) {
11683
- if (soft[soft.length - 1]) $tryReleaseSoftOut();
11684
- soft.pop();
11685
- }
11686
- }
11687
- function $tryTakeSince(mark) {
11688
- const store = throwExitsAls.getStore();
11689
- if (!store) return [];
11690
- return store.splice(Math.min(mark, store.length));
11691
- }
11692
- function peekThrowExitsSince(mark) {
11693
- const store = throwExitsAls.getStore();
11694
- if (!store) return [];
11695
- return store.slice(Math.min(mark, store.length));
11696
- }
11697
- function throwExitsMark() {
11698
- return throwExitsAls.getStore()?.length ?? 0;
11699
- }
11700
- function $tryDigestSoftCatch() {
11701
- const soft = softFrameActiveAls.getStore();
11702
- if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
11703
- $tryDigestSoft();
11704
- soft[soft.length - 1] = false;
11705
- }
11706
- function $tryReleaseSoftCatch() {
11707
- const soft = softFrameActiveAls.getStore();
11708
- if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
11709
- $tryReleaseSoft();
11710
- soft[soft.length - 1] = false;
11711
- }
11712
- function $tryDetachSoftCatch() {
11713
- const soft = softFrameActiveAls.getStore();
11714
- if (!soft || soft.length === 0 || !soft[soft.length - 1]) return [];
11715
- const effects = popMayThrowFrame(false);
11716
- soft[soft.length - 1] = false;
11717
- return effects;
11718
- }
11719
- function $tryDiscardSoft(_effects) {
11720
12012
  }
11721
- function $tryOrphanSoft(effects) {
11722
- orphanMayThrowEffects(effects);
11723
- }
11724
- function $tryReleaseSoftOut() {
11725
- const soft = softFrameActiveAls.getStore();
11726
- if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
11727
- $tryReleaseSoft();
11728
- soft[soft.length - 1] = false;
11729
- }
11730
- var NudoReturn = class extends Error {
11731
- absValue;
11732
- constructor(absValue) {
11733
- super("nudo:return");
11734
- this.name = "NudoReturn";
11735
- this.absValue = absValue;
11736
- }
11737
- };
11738
- function isNudoReturn(e) {
11739
- return e instanceof NudoReturn;
12013
+ bindTranspileExpression(transpileExpression);
12014
+ bindTranspileShortCircuit(transpileShortCircuitExpr);
12015
+
12016
+ // src/algebra/exec/transpile.ts
12017
+ function transpileSource(source, opts = {}) {
12018
+ const file = parseSource(source);
12019
+ return transpileFile(file, { ...opts, source: opts.source ?? source });
11740
12020
  }
11741
- function $loopReturn(v2) {
11742
- throw new NudoReturn(v2);
12021
+ function runtimeImportOf(runtime) {
12022
+ return `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`;
11743
12023
  }
11744
- var NudoLoopSignal = class extends Error {
11745
- kind;
11746
- label;
11747
- constructor(kind, label) {
11748
- super("nudo:loop");
11749
- this.name = "NudoLoopSignal";
11750
- this.kind = kind;
11751
- this.label = label;
12024
+ function transpileFile(file, opts = {}) {
12025
+ const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
12026
+ const lines = [
12027
+ `// nudo evaluator transpile \u2014 values are Abs; operators are overloaded calls`,
12028
+ `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`,
12029
+ ``
12030
+ ];
12031
+ for (const stmt of file.program.body) {
12032
+ lines.push(transpileStatement(stmt, 0, opts));
11752
12033
  }
11753
- };
11754
- function $loopBreak(label) {
11755
- throw new NudoLoopSignal("break", label || void 0);
11756
- }
11757
- function $loopContinue(label) {
11758
- throw new NudoLoopSignal("continue", label || void 0);
11759
- }
11760
- function loopSignalMatches(e, label) {
11761
- return e.label === void 0 || e.label === label;
11762
- }
11763
- function isNudoBreak(e, label) {
11764
- return e instanceof NudoLoopSignal && e.kind === "break" && loopSignalMatches(e, label);
11765
- }
11766
- function isNudoContinue(e, label) {
11767
- return e instanceof NudoLoopSignal && e.kind === "continue" && loopSignalMatches(e, label);
11768
- }
11769
- function $isBreakTo(e, label) {
11770
- return e instanceof NudoLoopSignal && e.kind === "break" && e.label === label;
12034
+ return lines.join("\n") + "\n";
11771
12035
  }
11772
- function $rethrowIfNudoReturn(e) {
11773
- if (isNudoReturn(e)) throw e;
12036
+ function transpile(source, opts) {
12037
+ return transpileSource(source, opts);
11774
12038
  }
11775
12039
 
11776
12040
  // src/algebra/exec/runtime/ops.ts
@@ -11846,10 +12110,10 @@ function $toNumeric(a) {
11846
12110
  return toNumericAbs(a);
11847
12111
  }
11848
12112
  function $updateAdd(a) {
11849
- return updateAddAbs(a);
12113
+ return updateAddAbs(a, currentExecPhi());
11850
12114
  }
11851
12115
  function $updateSub(a) {
11852
- return updateSubAbs(a);
12116
+ return updateSubAbs(a, currentExecPhi());
11853
12117
  }
11854
12118
  function $neg(a) {
11855
12119
  return negAbs(a);
@@ -12095,14 +12359,44 @@ function noteObjSlotMissing(recv, name, loc) {
12095
12359
 
12096
12360
  // src/algebra/exec/class-registry.ts
12097
12361
  var classRegistry = /* @__PURE__ */ new Map();
12362
+ var classEpoch = 0;
12363
+ var classEpochs = /* @__PURE__ */ new Map();
12364
+ var classCollisions = [];
12365
+ function beginClassEpoch() {
12366
+ classEpoch++;
12367
+ }
12368
+ function drainClassCollisions() {
12369
+ return classCollisions.splice(0, classCollisions.length);
12370
+ }
12371
+ function specShape(spec) {
12372
+ const ctorName = spec.ctor?.name ?? "anon";
12373
+ const methods = Object.keys(spec.methods ?? {}).sort().join(",");
12374
+ const statics = Object.keys(spec.staticMethods ?? {}).sort().join(",");
12375
+ const accessors = Object.keys(spec.accessors ?? {}).sort().join(",");
12376
+ return `${ctorName}[${methods}](${statics}){${accessors}}`;
12377
+ }
12098
12378
  function registerEvalClass(spec) {
12379
+ const prev = classRegistry.get(spec.name);
12380
+ const prevEpoch = classEpochs.get(spec.name);
12381
+ if (prev && prev !== spec && // 同 epoch(同一次 run 内)注册两次才可能是真碰撞:
12382
+ // 块级作用域同名类。跨 epoch = 顺序重注册(常态)。
12383
+ prevEpoch === classEpoch && specShape(prev) !== specShape(spec)) {
12384
+ classCollisions.push({
12385
+ name: spec.name,
12386
+ previous: specShape(prev),
12387
+ next: specShape(spec)
12388
+ });
12389
+ }
12099
12390
  classRegistry.set(spec.name, spec);
12391
+ classEpochs.set(spec.name, classEpoch);
12100
12392
  }
12101
12393
  function getEvalClass(name) {
12102
12394
  return classRegistry.get(name);
12103
12395
  }
12104
12396
  function clearBClasses() {
12105
12397
  classRegistry.clear();
12398
+ classEpochs.clear();
12399
+ classCollisions.length = 0;
12106
12400
  }
12107
12401
 
12108
12402
  // src/algebra/exec/runtime.ts
@@ -12400,6 +12694,8 @@ function $copy(a) {
12400
12694
  {
12401
12695
  k: "tuple",
12402
12696
  elements: s.elements.map($copy),
12697
+ // rest 槽必须随快照迁移(与 hof snapshotAbs 同口径),否则副本丢尾段
12698
+ ...s.rest ? { rest: $copy(s.rest) } : {},
12403
12699
  holes: s.holes ? [...s.holes] : void 0
12404
12700
  },
12405
12701
  a.term,
@@ -12590,7 +12886,7 @@ function $idx(a, i) {
12590
12886
  if (slots.length === 0) return objShape.open ? unknown : undef();
12591
12887
  const joinSlotsWithUndef = () => joinAbs(slots.reduce((x, y) => joinAbs(x, y)), undef());
12592
12888
  if (typeof iv === "string" || typeof iv === "number" || typeof iv === "boolean") {
12593
- const slot = objShape.slots[String(iv)];
12889
+ const slot = getSlot(objShape.slots, String(iv));
12594
12890
  if (slot) return slot.value;
12595
12891
  if (objShape.open) return unknown;
12596
12892
  return undef();
@@ -12807,6 +13103,20 @@ function $arrRest(a, start) {
12807
13103
  return parts.length ? parts.reduce((x, y) => joinAbs(x, y)) : unknown;
12808
13104
  }
12809
13105
  if (a.shape.k === "tuple") {
13106
+ if (a.shape.rest) {
13107
+ const sliced = a.shape.elements.slice(start);
13108
+ if (start < a.shape.elements.length && !shouldWidenArrayLiteral(sliced.length + 1)) {
13109
+ return abs(
13110
+ { k: "tuple", elements: sliced, rest: a.shape.rest },
13111
+ void 0,
13112
+ void 0,
13113
+ a.conf
13114
+ );
13115
+ }
13116
+ const restEl = a.shape.rest.shape.k === "arr" ? a.shape.rest.shape.element : a.shape.rest;
13117
+ const el = sliced.reduce((x, y) => joinAbs(x, y), restEl);
13118
+ return abs({ k: "arr", element: el }, void 0, void 0, a.conf);
13119
+ }
12810
13120
  return tupleOrWiden(a.shape.elements.slice(start), a.conf);
12811
13121
  }
12812
13122
  if (a.shape.k === "arr") return a;
@@ -13052,7 +13362,7 @@ function $get(o, key, opts) {
13052
13362
  const raw = o[key];
13053
13363
  if (typeof raw === "function") {
13054
13364
  return absFunction([`${ns}.${key}`], {
13055
- body: noBody2,
13365
+ body: noBody,
13056
13366
  apply: (args) => evalNamespaceCall(ns, key, args) ?? unknown
13057
13367
  });
13058
13368
  }
@@ -13071,7 +13381,7 @@ function $get(o, key, opts) {
13071
13381
  }
13072
13382
  if (o.shape.k === "eff" && o.shape.eff === "promise" && (key === "then" || key === "catch" || key === "finally")) {
13073
13383
  return absFunction([key === "then" ? "onFulfilled" : key === "catch" ? "onRejected" : "onFinally"], {
13074
- body: noBody2
13384
+ body: noBody
13075
13385
  });
13076
13386
  }
13077
13387
  if (o.shape.k === "brand") {
@@ -13082,7 +13392,7 @@ function $get(o, key, opts) {
13082
13392
  const isClassVal = classNameOfValue(o) === o.shape.name;
13083
13393
  const builtinM = BUILTIN_BRAND_METHODS[o.shape.name];
13084
13394
  if (builtinM && !isClassVal && (key === "@@iterator" || builtinM.has(key))) {
13085
- return absFunction([], { body: noBody2 });
13395
+ return absFunction([], { body: noBody });
13086
13396
  }
13087
13397
  if (key === "size" && o.shape.name === "Map") return mapSizeAbs(o);
13088
13398
  if (key === "size" && o.shape.name === "Set") return setSizeAbs(o);
@@ -13098,14 +13408,14 @@ function $get(o, key, opts) {
13098
13408
  for (const n of evalClassChain(o.shape.name)) {
13099
13409
  const spec = getEvalClass(n);
13100
13410
  if (spec?.staticMethods?.[key]) {
13101
- return absFunction(spec.staticMethodParams?.[key] ?? [], { body: noBody2 });
13411
+ return absFunction(spec.staticMethodParams?.[key] ?? [], { body: noBody });
13102
13412
  }
13103
13413
  }
13104
13414
  if (key === "prototype") {
13105
13415
  return abs({ k: "obj", slots: {} }, void 0, void 0, "path");
13106
13416
  }
13107
13417
  if (key === "call" || key === "apply" || key === "bind") {
13108
- return absFunction([], { body: noBody2 });
13418
+ return absFunction([], { body: noBody });
13109
13419
  }
13110
13420
  } else {
13111
13421
  const acc = findClassAccessor(o.shape.name, key);
@@ -13114,7 +13424,7 @@ function $get(o, key, opts) {
13114
13424
  for (const n of evalClassChain(o.shape.name)) {
13115
13425
  const spec = getEvalClass(n);
13116
13426
  if (spec?.methods?.[key]) {
13117
- return absFunction(spec.methodParams?.[key] ?? [], { body: noBody2 });
13427
+ return absFunction(spec.methodParams?.[key] ?? [], { body: noBody });
13118
13428
  }
13119
13429
  }
13120
13430
  }
@@ -15435,7 +15745,7 @@ function namespaceAbsOf(mod2) {
15435
15745
  return abs({ k: "obj", slots, open: true }, void 0, void 0, "path");
15436
15746
  }
15437
15747
  function bindImports(node, env, modules) {
15438
- const mod2 = modules[node.source.value];
15748
+ const mod2 = Object.hasOwn(modules, node.source.value) ? modules[node.source.value] : void 0;
15439
15749
  if (!mod2) {
15440
15750
  for (const s of node.specifiers) {
15441
15751
  env.vars.set(s.local.name, unknown);
@@ -15447,7 +15757,8 @@ function bindImports(node, env, modules) {
15447
15757
  env.vars.set(s.local.name, mod2.default ?? unknown);
15448
15758
  } else if (s.type === "ImportSpecifier") {
15449
15759
  const imported = s.imported.type === "Identifier" ? s.imported.name : String(s.imported);
15450
- env.vars.set(s.local.name, mod2.named[imported] ?? unknown);
15760
+ const named = Object.hasOwn(mod2.named, imported) ? mod2.named[imported] : void 0;
15761
+ env.vars.set(s.local.name, named ?? unknown);
15451
15762
  } else if (s.type === "ImportNamespaceSpecifier") {
15452
15763
  env.vars.set(s.local.name, namespaceAbsOf(mod2));
15453
15764
  }
@@ -15473,7 +15784,7 @@ function collectAbsExports(file, env, modules) {
15473
15784
  for (const stmt of file.program.body) {
15474
15785
  if (stmt.type === "ExportNamedDeclaration") {
15475
15786
  if (stmt.source && modules) {
15476
- const mod2 = modules[stmt.source.value];
15787
+ const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
15477
15788
  if (mod2) {
15478
15789
  for (const spec of stmt.specifiers) {
15479
15790
  if (spec.type === "ExportNamespaceSpecifier") {
@@ -15485,7 +15796,7 @@ function collectAbsExports(file, env, modules) {
15485
15796
  if (spec.type !== "ExportSpecifier") continue;
15486
15797
  const local = spec.local.type === "Identifier" ? spec.local.name : spec.local.value;
15487
15798
  const exported = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
15488
- const v2 = local === "default" ? mod2.default : mod2.named[local];
15799
+ const v2 = local === "default" ? mod2.default : Object.hasOwn(mod2.named, local) ? mod2.named[local] : void 0;
15489
15800
  const slot = v2 ?? unknown;
15490
15801
  if (exported === "default") defaultExport = slot;
15491
15802
  else {
@@ -15531,7 +15842,7 @@ function collectAbsExports(file, env, modules) {
15531
15842
  }
15532
15843
  }
15533
15844
  } else if (stmt.type === "ExportAllDeclaration" && stmt.source && modules) {
15534
- const mod2 = modules[stmt.source.value];
15845
+ const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
15535
15846
  if (mod2?.named) {
15536
15847
  for (const [k, v2] of Object.entries(mod2.named)) {
15537
15848
  if (!explicitNames.has(k)) named[k] = v2;
@@ -15876,6 +16187,7 @@ ${js}`;
15876
16187
  const fn = new Function(...argNames, `${js}
15877
16188
  ${ret}`);
15878
16189
  setEvalBindingSink(bindings);
16190
+ beginClassEpoch();
15879
16191
  try {
15880
16192
  const result = fn(...args);
15881
16193
  runBindings.set(result, bindings);
@@ -15883,6 +16195,18 @@ ${ret}`);
15883
16195
  } finally {
15884
16196
  setEvalBindingSink(null);
15885
16197
  drainPromiseMicros();
16198
+ noteDrainedClassCollisions();
16199
+ }
16200
+ }
16201
+ function noteDrainedClassCollisions() {
16202
+ for (const c of drainClassCollisions()) {
16203
+ noteEvalFallback(
16204
+ new NudoUnsupportedError(
16205
+ "class-collision",
16206
+ void 0,
16207
+ `class '${c.name}' registered again with a different shape (${c.previous} -> ${c.next}); name-keyed lookup may resolve to either definition`
16208
+ )
16209
+ );
15886
16210
  }
15887
16211
  }
15888
16212
  var evalFallbackCollector = null;
@@ -15944,14 +16268,16 @@ function isAbsVal(v2) {
15944
16268
  }
15945
16269
  function callTranspiledExportFull(exports, name, args, opts) {
15946
16270
  enterEvalCallBudgetSession();
16271
+ beginClassEpoch();
15947
16272
  try {
15948
16273
  return callTranspiledExportFullInner(exports, name, args, opts);
15949
16274
  } finally {
15950
16275
  exitEvalCallBudgetSession();
16276
+ noteDrainedClassCollisions();
15951
16277
  }
15952
16278
  }
15953
16279
  function callTranspiledExportFullInner(exports, name, args, opts) {
15954
- const fn = exports[name];
16280
+ const fn = Object.hasOwn(exports, name) ? exports[name] : void 0;
15955
16281
  if (typeof fn === "function") {
15956
16282
  const callArgs = args.map(
15957
16283
  (a) => a && typeof a === "object" && "shape" in a ? $copy(a) : a
@@ -16535,7 +16861,7 @@ function $instanceofNonIdent(_left) {
16535
16861
  }
16536
16862
  function $classExpr() {
16537
16863
  return absFunction(["_rest"], {
16538
- body: noBody2,
16864
+ body: noBody,
16539
16865
  apply: () => unknown
16540
16866
  });
16541
16867
  }
@@ -16623,6 +16949,7 @@ export {
16623
16949
  v,
16624
16950
  app,
16625
16951
  termEquals,
16952
+ litKeyString,
16626
16953
  termToString,
16627
16954
  simplifyTerm,
16628
16955
  TYPEOF_NAMES,
@@ -16654,6 +16981,8 @@ export {
16654
16981
  geNum,
16655
16982
  ltNum,
16656
16983
  leNum,
16984
+ PROJECTION_MAX_DEPTH,
16985
+ ProjectionBudget,
16657
16986
  never,
16658
16987
  unknown,
16659
16988
  anyAbs,
@@ -16797,6 +17126,43 @@ export {
16797
17126
  getPropFlags,
16798
17127
  setPropFlags,
16799
17128
  migrateInvariants,
17129
+ clearStaleTermPred,
17130
+ currentExecPhi,
17131
+ withExecPhi,
17132
+ asAbsVal,
17133
+ callAtFunctionBoundary,
17134
+ $fnVal,
17135
+ $rawThis,
17136
+ $lit,
17137
+ litTruth,
17138
+ isDefinitelyTrue,
17139
+ isDefinitelyFalse,
17140
+ runWithLoopExits,
17141
+ takeLoopExits,
17142
+ takeThrowExits,
17143
+ pushLoopExit,
17144
+ pushThrowExit,
17145
+ $pushLoopExit,
17146
+ $tryMark,
17147
+ $tryCurrentMark,
17148
+ $tryPopMark,
17149
+ $tryTakeSince,
17150
+ $tryDigestSoftCatch,
17151
+ $tryReleaseSoftCatch,
17152
+ $tryDetachSoftCatch,
17153
+ $tryDiscardSoft,
17154
+ $tryOrphanSoft,
17155
+ $tryReleaseSoftOut,
17156
+ NudoReturn,
17157
+ isNudoReturn,
17158
+ $loopReturn,
17159
+ NudoLoopSignal,
17160
+ $loopBreak,
17161
+ $loopContinue,
17162
+ isNudoBreak,
17163
+ isNudoContinue,
17164
+ $isBreakTo,
17165
+ $rethrowIfNudoReturn,
16800
17166
  evalMathMethod,
16801
17167
  builtinCtorAbs,
16802
17168
  builtinCtorNameOf,
@@ -16965,43 +17331,6 @@ export {
16965
17331
  runtimeImportOf,
16966
17332
  transpileFile,
16967
17333
  transpile,
16968
- clearStaleTermPred,
16969
- currentExecPhi,
16970
- withExecPhi,
16971
- asAbsVal,
16972
- callAtFunctionBoundary,
16973
- $fnVal,
16974
- $rawThis,
16975
- $lit,
16976
- litTruth,
16977
- isDefinitelyTrue,
16978
- isDefinitelyFalse,
16979
- runWithLoopExits,
16980
- takeLoopExits,
16981
- takeThrowExits,
16982
- pushLoopExit,
16983
- pushThrowExit,
16984
- $pushLoopExit,
16985
- $tryMark,
16986
- $tryCurrentMark,
16987
- $tryPopMark,
16988
- $tryTakeSince,
16989
- $tryDigestSoftCatch,
16990
- $tryReleaseSoftCatch,
16991
- $tryDetachSoftCatch,
16992
- $tryDiscardSoft,
16993
- $tryOrphanSoft,
16994
- $tryReleaseSoftOut,
16995
- NudoReturn,
16996
- isNudoReturn,
16997
- $loopReturn,
16998
- NudoLoopSignal,
16999
- $loopBreak,
17000
- $loopContinue,
17001
- isNudoBreak,
17002
- isNudoContinue,
17003
- $isBreakTo,
17004
- $rethrowIfNudoReturn,
17005
17334
  $unknown,
17006
17335
  $importMeta,
17007
17336
  $dynamicImport,
@@ -17130,6 +17459,7 @@ export {
17130
17459
  resetEvalFallbackStats,
17131
17460
  noteEvalFallback,
17132
17461
  tryRunTranspiled,
17462
+ isAbsVal,
17133
17463
  callTranspiledExportFull,
17134
17464
  callTranspiledExport,
17135
17465
  callTranspiledExportApply,