@nudojs/core 1.5.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.
- package/dist/{chunk-YO4GKCNE.js → chunk-I35CHJNO.js} +120 -34
- package/dist/{chunk-W2MP6REI.js → chunk-LZJC7X5J.js} +214 -87
- package/dist/exec.d.ts +5 -3
- package/dist/exec.js +3 -1
- package/dist/index.d.ts +13 -6
- package/dist/index.js +28 -19
- package/dist/internal.d.ts +23 -5
- package/dist/internal.js +108 -16
- package/dist/{check-report-Ci1dDysO.d.ts → projection-budget-CGbs16aX.d.ts} +61 -3
- package/dist/{run-WJfj477N.d.ts → run-Dg7gQO2z.d.ts} +6 -2
- package/package.json +1 -1
|
@@ -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"
|
|
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
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
return
|
|
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 ? "?" : ""}: ${
|
|
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 `${
|
|
1114
|
+
return `${shapeToStringB(s.element.shape, budget)}[]`;
|
|
1054
1115
|
case "tuple":
|
|
1055
|
-
return `[${s.elements.map((e) =>
|
|
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}<${
|
|
1122
|
+
return `${s.eff}<${shapeToStringB(s.inner.shape, budget)}>`;
|
|
1062
1123
|
case "sum":
|
|
1063
|
-
return s.members.map(
|
|
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}:${
|
|
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
|
}
|
|
@@ -1806,7 +1867,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
|
1806
1867
|
try {
|
|
1807
1868
|
const s = a.shape;
|
|
1808
1869
|
if (s.k === "prim") {
|
|
1809
|
-
if (a.term?.op === "lit") return `prim:${s.type}:${
|
|
1870
|
+
if (a.term?.op === "lit") return `prim:${s.type}:${litKeyString(a.term.value)}`;
|
|
1810
1871
|
const t = a.term ? termToString(a.term) : "";
|
|
1811
1872
|
const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
|
|
1812
1873
|
return `prim:${s.type}:${t}:${p}`;
|
|
@@ -1818,7 +1879,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
|
1818
1879
|
const v2 = a.term.value;
|
|
1819
1880
|
if (v2 === void 0) return "unknown:undefined";
|
|
1820
1881
|
if (v2 === null) return "unknown:null";
|
|
1821
|
-
return `unknown:lit:${typeof v2}:${
|
|
1882
|
+
return `unknown:lit:${typeof v2}:${litKeyString(v2)}`;
|
|
1822
1883
|
}
|
|
1823
1884
|
if (a.term) return `unknown:${termToString(a.term)}`;
|
|
1824
1885
|
return "unknown";
|
|
@@ -2491,7 +2552,7 @@ function bindTypeVars(pattern, arg, map, depth = 0) {
|
|
|
2491
2552
|
}
|
|
2492
2553
|
if (ps.k === "obj" && as.k === "obj") {
|
|
2493
2554
|
for (const [key, slot] of Object.entries(ps.slots)) {
|
|
2494
|
-
const aSlot = as.slots
|
|
2555
|
+
const aSlot = getSlot(as.slots, key);
|
|
2495
2556
|
if (aSlot) bindTypeVars(slot.value, aSlot.value, map, depth + 1);
|
|
2496
2557
|
}
|
|
2497
2558
|
return;
|
|
@@ -4886,6 +4947,7 @@ function absToJsonNative(a, seen) {
|
|
|
4886
4947
|
if (t?.op === "lit") return t.value;
|
|
4887
4948
|
const s = a.shape;
|
|
4888
4949
|
if (s.k === "tuple") {
|
|
4950
|
+
if (a.shape.rest) return NOT_LITERAL;
|
|
4889
4951
|
seen.add(a);
|
|
4890
4952
|
const holes = a.shape.holes ?? [];
|
|
4891
4953
|
const out = [];
|
|
@@ -7109,51 +7171,15 @@ function toNumericAbs(a) {
|
|
|
7109
7171
|
}
|
|
7110
7172
|
return n;
|
|
7111
7173
|
}
|
|
7112
|
-
function updateAddAbs(a) {
|
|
7174
|
+
function updateAddAbs(a, phi2 = pTrue) {
|
|
7113
7175
|
const n = toNumericAbs(a);
|
|
7114
7176
|
const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
|
|
7115
|
-
|
|
7116
|
-
return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
|
|
7117
|
-
}
|
|
7118
|
-
return addNumeric(n, one);
|
|
7177
|
+
return add(n, one, phi2);
|
|
7119
7178
|
}
|
|
7120
|
-
function updateSubAbs(a) {
|
|
7179
|
+
function updateSubAbs(a, phi2 = pTrue) {
|
|
7121
7180
|
const n = toNumericAbs(a);
|
|
7122
7181
|
const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
|
|
7123
|
-
|
|
7124
|
-
return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
|
|
7125
|
-
}
|
|
7126
|
-
return subNumeric(n, one);
|
|
7127
|
-
}
|
|
7128
|
-
function addNumeric(a, b) {
|
|
7129
|
-
const ra = litValue(a);
|
|
7130
|
-
const rb = litValue(b);
|
|
7131
|
-
const va = ra.ok ? ra.value : void 0;
|
|
7132
|
-
const vb = rb.ok ? rb.value : void 0;
|
|
7133
|
-
if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va + vb);
|
|
7134
|
-
if (typeof va === "number" && typeof vb === "number") return numLit(va + vb);
|
|
7135
|
-
const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
|
|
7136
|
-
return abs(
|
|
7137
|
-
{ k: "prim", type: big ? "bigint" : "number" },
|
|
7138
|
-
void 0,
|
|
7139
|
-
void 0,
|
|
7140
|
-
confJoin(confJoin(a.conf, b.conf), "path")
|
|
7141
|
-
);
|
|
7142
|
-
}
|
|
7143
|
-
function subNumeric(a, b) {
|
|
7144
|
-
const ra = litValue(a);
|
|
7145
|
-
const rb = litValue(b);
|
|
7146
|
-
const va = ra.ok ? ra.value : void 0;
|
|
7147
|
-
const vb = rb.ok ? rb.value : void 0;
|
|
7148
|
-
if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va - vb);
|
|
7149
|
-
if (typeof va === "number" && typeof vb === "number") return numLit(va - vb);
|
|
7150
|
-
const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
|
|
7151
|
-
return abs(
|
|
7152
|
-
{ k: "prim", type: big ? "bigint" : "number" },
|
|
7153
|
-
void 0,
|
|
7154
|
-
void 0,
|
|
7155
|
-
confJoin(confJoin(a.conf, b.conf), "path")
|
|
7156
|
-
);
|
|
7182
|
+
return sub(n, one, phi2);
|
|
7157
7183
|
}
|
|
7158
7184
|
function toNumberAbs(a) {
|
|
7159
7185
|
if (isSymbolAbs(a)) {
|
|
@@ -8192,24 +8218,40 @@ function leqShape(src, tgt, phi2, env, depth) {
|
|
|
8192
8218
|
return leqWithPred(s.element, t.element, phi2, env, depth + 1);
|
|
8193
8219
|
}
|
|
8194
8220
|
if (s.k === "tuple") {
|
|
8195
|
-
|
|
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");
|
|
8196
8224
|
}
|
|
8197
8225
|
return fail(`shape ${s.k} \u22AD arr`);
|
|
8198
8226
|
}
|
|
8199
8227
|
if (t.k === "tuple") {
|
|
8200
8228
|
if (s.k !== "tuple") return fail(`shape ${s.k} \u22AD tuple`);
|
|
8201
|
-
if (s.elements.length !== t.elements.length) {
|
|
8229
|
+
if (!t.rest && s.elements.length !== t.elements.length) {
|
|
8202
8230
|
return fail(`tuple arity ${s.elements.length} \u22AD ${t.elements.length}`);
|
|
8203
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
|
+
}
|
|
8204
8238
|
const sHoles = s.holes ?? [];
|
|
8205
8239
|
const tHoles = t.holes ?? [];
|
|
8206
|
-
|
|
8207
|
-
|
|
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
|
+
}
|
|
8208
8245
|
}
|
|
8209
|
-
for (let i = 0; i <
|
|
8210
|
-
const
|
|
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);
|
|
8211
8249
|
if (!r.ok) return fail(`tuple[${i}]: ${r.reason}`);
|
|
8212
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
|
+
}
|
|
8213
8255
|
return ok();
|
|
8214
8256
|
}
|
|
8215
8257
|
if (t.k === "fn") {
|
|
@@ -8284,13 +8326,30 @@ function formatAbs(a, opts = {}) {
|
|
|
8284
8326
|
return parts.join(" ");
|
|
8285
8327
|
}
|
|
8286
8328
|
function formatShapeSlot(a) {
|
|
8287
|
-
|
|
8329
|
+
return formatShapeSlotB(a, new ProjectionBudget());
|
|
8330
|
+
}
|
|
8331
|
+
function formatShapeSlotB(a, budget) {
|
|
8332
|
+
const base = formatShapeB(a, budget);
|
|
8288
8333
|
if (!a.term || a.term.op === "lit") return base;
|
|
8289
8334
|
if (a.shape.k === "fn" || a.shape.k === "arr") return base;
|
|
8290
8335
|
if (a.shape.k === "any" && a.term.op === "var") return termToString(a.term);
|
|
8291
8336
|
return `${base} = ${termToString(a.term)}`;
|
|
8292
8337
|
}
|
|
8338
|
+
var FORMAT_TRUNC = { cycle: "\u2026cycle", depth: "\u2026" };
|
|
8293
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) {
|
|
8294
8353
|
const s = a.shape;
|
|
8295
8354
|
switch (s.k) {
|
|
8296
8355
|
case "never":
|
|
@@ -8317,28 +8376,28 @@ function formatShape(a) {
|
|
|
8317
8376
|
const entries = Object.entries(s.slots).map(([k, slot]) => {
|
|
8318
8377
|
const opt = slot.optional ? "?" : "";
|
|
8319
8378
|
const key = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
|
|
8320
|
-
return `${key}${opt}: ${
|
|
8379
|
+
return `${key}${opt}: ${formatShapeB(slot.value, budget)}`;
|
|
8321
8380
|
});
|
|
8322
8381
|
return `{ ${entries.join(", ")} }`;
|
|
8323
8382
|
}
|
|
8324
8383
|
case "arr": {
|
|
8325
8384
|
if (s.element.shape.k === "any" && s.element.term?.op === "var") {
|
|
8326
|
-
return `arr(${
|
|
8385
|
+
return `arr(${formatShapeSlotB(s.element, budget)})`;
|
|
8327
8386
|
}
|
|
8328
|
-
return `${
|
|
8387
|
+
return `${formatShapeB(s.element, budget)}[]`;
|
|
8329
8388
|
}
|
|
8330
8389
|
case "tuple": {
|
|
8331
8390
|
const holes = s.holes ?? [];
|
|
8332
8391
|
const parts = s.elements.map(
|
|
8333
|
-
(el, i) => holes.includes(i) ? "" :
|
|
8392
|
+
(el, i) => holes.includes(i) ? "" : formatShapeB(el, budget)
|
|
8334
8393
|
);
|
|
8335
8394
|
if (s.rest) {
|
|
8336
|
-
parts.push(`...${
|
|
8395
|
+
parts.push(`...${formatShapeB(s.rest, budget)}`);
|
|
8337
8396
|
}
|
|
8338
8397
|
return `[${parts.join(", ")}]`;
|
|
8339
8398
|
}
|
|
8340
8399
|
case "fn": {
|
|
8341
|
-
const ret = s.returnType !== void 0 ?
|
|
8400
|
+
const ret = s.returnType !== void 0 ? formatShapeSlotB(s.returnType, budget) : "?";
|
|
8342
8401
|
const labels = s.params ?? [];
|
|
8343
8402
|
const paramTypes = s.paramTypes;
|
|
8344
8403
|
const hasMarkers = labels.some(
|
|
@@ -8350,7 +8409,7 @@ function formatShape(a) {
|
|
|
8350
8409
|
for (let i = 0; i < n; i++) {
|
|
8351
8410
|
const label = labels[i];
|
|
8352
8411
|
const type = paramTypes?.[i];
|
|
8353
|
-
const typeText = type !== void 0 ?
|
|
8412
|
+
const typeText = type !== void 0 ? formatShapeSlotB(type, budget) : void 0;
|
|
8354
8413
|
if (label?.startsWith("...")) {
|
|
8355
8414
|
ps.push(typeText ? `...${label.slice(3)}: ${typeText}` : label);
|
|
8356
8415
|
} else if (label?.endsWith("?")) {
|
|
@@ -8367,7 +8426,7 @@ function formatShape(a) {
|
|
|
8367
8426
|
return `(${renderLabeled().join(", ")}) => ${ret}`;
|
|
8368
8427
|
}
|
|
8369
8428
|
if (paramTypes && paramTypes.length > 0) {
|
|
8370
|
-
const ps = paramTypes.map((p) =>
|
|
8429
|
+
const ps = paramTypes.map((p) => formatShapeSlotB(p, budget));
|
|
8371
8430
|
return `(${ps.join(", ")}) => ${ret}`;
|
|
8372
8431
|
}
|
|
8373
8432
|
return `(${labels.join(", ")}) => ${ret}`;
|
|
@@ -8378,7 +8437,7 @@ function formatShape(a) {
|
|
|
8378
8437
|
if (slots) {
|
|
8379
8438
|
const arg = (key) => {
|
|
8380
8439
|
const sl = slots[key];
|
|
8381
|
-
return sl ?
|
|
8440
|
+
return sl ? formatShapeSlotB(sl.value, budget) : void 0;
|
|
8382
8441
|
};
|
|
8383
8442
|
if (s.name === "Map" || s.name === "ReadonlyMap" || s.name === "WeakMap") {
|
|
8384
8443
|
const k = arg("__key");
|
|
@@ -8393,12 +8452,12 @@ function formatShape(a) {
|
|
|
8393
8452
|
return `${s.name}`;
|
|
8394
8453
|
}
|
|
8395
8454
|
case "eff":
|
|
8396
|
-
return `${s.eff}<${
|
|
8455
|
+
return `${s.eff}<${formatShapeB(s.inner, budget)}>`;
|
|
8397
8456
|
case "sum": {
|
|
8398
8457
|
const seen = /* @__PURE__ */ new Set();
|
|
8399
8458
|
const parts = [];
|
|
8400
8459
|
for (const m of s.members) {
|
|
8401
|
-
const t =
|
|
8460
|
+
const t = formatShapeB(m, budget);
|
|
8402
8461
|
if (seen.has(t)) continue;
|
|
8403
8462
|
seen.add(t);
|
|
8404
8463
|
parts.push(t);
|
|
@@ -8707,8 +8766,10 @@ function identBoundaryRegex(name) {
|
|
|
8707
8766
|
var NudoUnsupportedError = class extends Error {
|
|
8708
8767
|
reason;
|
|
8709
8768
|
loc;
|
|
8710
|
-
constructor(reason, loc) {
|
|
8711
|
-
super(
|
|
8769
|
+
constructor(reason, loc, detail) {
|
|
8770
|
+
super(
|
|
8771
|
+
detail ? `nudo:unsupported ${reason} (${detail})` : `nudo:unsupported ${reason}`
|
|
8772
|
+
);
|
|
8712
8773
|
this.name = "NudoUnsupportedError";
|
|
8713
8774
|
this.reason = reason;
|
|
8714
8775
|
this.loc = loc;
|
|
@@ -10112,15 +10173,15 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
10112
10173
|
if (nsSpecs.length > 0) {
|
|
10113
10174
|
if (!stmt.source) return `${pad}/* export * as without source skipped */`;
|
|
10114
10175
|
return nsSpecs.map((s) => {
|
|
10115
|
-
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);
|
|
10116
10177
|
return `${pad}export * as ${exported} from ${JSON.stringify(stmt.source.value)};`;
|
|
10117
10178
|
}).join("\n");
|
|
10118
10179
|
}
|
|
10119
10180
|
const specs = stmt.specifiers.filter(
|
|
10120
10181
|
(s) => "local" in s
|
|
10121
10182
|
).map((s) => {
|
|
10122
|
-
const local = s.local.type === "Identifier" ? s.local.name : s.local.value;
|
|
10123
|
-
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);
|
|
10124
10185
|
return local === exported ? local : `${local} as ${exported}`;
|
|
10125
10186
|
}).join(", ");
|
|
10126
10187
|
if (stmt.source) {
|
|
@@ -12049,10 +12110,10 @@ function $toNumeric(a) {
|
|
|
12049
12110
|
return toNumericAbs(a);
|
|
12050
12111
|
}
|
|
12051
12112
|
function $updateAdd(a) {
|
|
12052
|
-
return updateAddAbs(a);
|
|
12113
|
+
return updateAddAbs(a, currentExecPhi());
|
|
12053
12114
|
}
|
|
12054
12115
|
function $updateSub(a) {
|
|
12055
|
-
return updateSubAbs(a);
|
|
12116
|
+
return updateSubAbs(a, currentExecPhi());
|
|
12056
12117
|
}
|
|
12057
12118
|
function $neg(a) {
|
|
12058
12119
|
return negAbs(a);
|
|
@@ -12298,14 +12359,44 @@ function noteObjSlotMissing(recv, name, loc) {
|
|
|
12298
12359
|
|
|
12299
12360
|
// src/algebra/exec/class-registry.ts
|
|
12300
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
|
+
}
|
|
12301
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
|
+
}
|
|
12302
12390
|
classRegistry.set(spec.name, spec);
|
|
12391
|
+
classEpochs.set(spec.name, classEpoch);
|
|
12303
12392
|
}
|
|
12304
12393
|
function getEvalClass(name) {
|
|
12305
12394
|
return classRegistry.get(name);
|
|
12306
12395
|
}
|
|
12307
12396
|
function clearBClasses() {
|
|
12308
12397
|
classRegistry.clear();
|
|
12398
|
+
classEpochs.clear();
|
|
12399
|
+
classCollisions.length = 0;
|
|
12309
12400
|
}
|
|
12310
12401
|
|
|
12311
12402
|
// src/algebra/exec/runtime.ts
|
|
@@ -12603,6 +12694,8 @@ function $copy(a) {
|
|
|
12603
12694
|
{
|
|
12604
12695
|
k: "tuple",
|
|
12605
12696
|
elements: s.elements.map($copy),
|
|
12697
|
+
// rest 槽必须随快照迁移(与 hof snapshotAbs 同口径),否则副本丢尾段
|
|
12698
|
+
...s.rest ? { rest: $copy(s.rest) } : {},
|
|
12606
12699
|
holes: s.holes ? [...s.holes] : void 0
|
|
12607
12700
|
},
|
|
12608
12701
|
a.term,
|
|
@@ -12793,7 +12886,7 @@ function $idx(a, i) {
|
|
|
12793
12886
|
if (slots.length === 0) return objShape.open ? unknown : undef();
|
|
12794
12887
|
const joinSlotsWithUndef = () => joinAbs(slots.reduce((x, y) => joinAbs(x, y)), undef());
|
|
12795
12888
|
if (typeof iv === "string" || typeof iv === "number" || typeof iv === "boolean") {
|
|
12796
|
-
const slot = objShape.slots
|
|
12889
|
+
const slot = getSlot(objShape.slots, String(iv));
|
|
12797
12890
|
if (slot) return slot.value;
|
|
12798
12891
|
if (objShape.open) return unknown;
|
|
12799
12892
|
return undef();
|
|
@@ -13010,6 +13103,20 @@ function $arrRest(a, start) {
|
|
|
13010
13103
|
return parts.length ? parts.reduce((x, y) => joinAbs(x, y)) : unknown;
|
|
13011
13104
|
}
|
|
13012
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
|
+
}
|
|
13013
13120
|
return tupleOrWiden(a.shape.elements.slice(start), a.conf);
|
|
13014
13121
|
}
|
|
13015
13122
|
if (a.shape.k === "arr") return a;
|
|
@@ -15638,7 +15745,7 @@ function namespaceAbsOf(mod2) {
|
|
|
15638
15745
|
return abs({ k: "obj", slots, open: true }, void 0, void 0, "path");
|
|
15639
15746
|
}
|
|
15640
15747
|
function bindImports(node, env, modules) {
|
|
15641
|
-
const mod2 = modules[node.source.value];
|
|
15748
|
+
const mod2 = Object.hasOwn(modules, node.source.value) ? modules[node.source.value] : void 0;
|
|
15642
15749
|
if (!mod2) {
|
|
15643
15750
|
for (const s of node.specifiers) {
|
|
15644
15751
|
env.vars.set(s.local.name, unknown);
|
|
@@ -15650,7 +15757,8 @@ function bindImports(node, env, modules) {
|
|
|
15650
15757
|
env.vars.set(s.local.name, mod2.default ?? unknown);
|
|
15651
15758
|
} else if (s.type === "ImportSpecifier") {
|
|
15652
15759
|
const imported = s.imported.type === "Identifier" ? s.imported.name : String(s.imported);
|
|
15653
|
-
|
|
15760
|
+
const named = Object.hasOwn(mod2.named, imported) ? mod2.named[imported] : void 0;
|
|
15761
|
+
env.vars.set(s.local.name, named ?? unknown);
|
|
15654
15762
|
} else if (s.type === "ImportNamespaceSpecifier") {
|
|
15655
15763
|
env.vars.set(s.local.name, namespaceAbsOf(mod2));
|
|
15656
15764
|
}
|
|
@@ -15676,7 +15784,7 @@ function collectAbsExports(file, env, modules) {
|
|
|
15676
15784
|
for (const stmt of file.program.body) {
|
|
15677
15785
|
if (stmt.type === "ExportNamedDeclaration") {
|
|
15678
15786
|
if (stmt.source && modules) {
|
|
15679
|
-
const mod2 = modules[stmt.source.value];
|
|
15787
|
+
const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
|
|
15680
15788
|
if (mod2) {
|
|
15681
15789
|
for (const spec of stmt.specifiers) {
|
|
15682
15790
|
if (spec.type === "ExportNamespaceSpecifier") {
|
|
@@ -15688,7 +15796,7 @@ function collectAbsExports(file, env, modules) {
|
|
|
15688
15796
|
if (spec.type !== "ExportSpecifier") continue;
|
|
15689
15797
|
const local = spec.local.type === "Identifier" ? spec.local.name : spec.local.value;
|
|
15690
15798
|
const exported = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
15691
|
-
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;
|
|
15692
15800
|
const slot = v2 ?? unknown;
|
|
15693
15801
|
if (exported === "default") defaultExport = slot;
|
|
15694
15802
|
else {
|
|
@@ -15734,7 +15842,7 @@ function collectAbsExports(file, env, modules) {
|
|
|
15734
15842
|
}
|
|
15735
15843
|
}
|
|
15736
15844
|
} else if (stmt.type === "ExportAllDeclaration" && stmt.source && modules) {
|
|
15737
|
-
const mod2 = modules[stmt.source.value];
|
|
15845
|
+
const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
|
|
15738
15846
|
if (mod2?.named) {
|
|
15739
15847
|
for (const [k, v2] of Object.entries(mod2.named)) {
|
|
15740
15848
|
if (!explicitNames.has(k)) named[k] = v2;
|
|
@@ -16079,6 +16187,7 @@ ${js}`;
|
|
|
16079
16187
|
const fn = new Function(...argNames, `${js}
|
|
16080
16188
|
${ret}`);
|
|
16081
16189
|
setEvalBindingSink(bindings);
|
|
16190
|
+
beginClassEpoch();
|
|
16082
16191
|
try {
|
|
16083
16192
|
const result = fn(...args);
|
|
16084
16193
|
runBindings.set(result, bindings);
|
|
@@ -16086,6 +16195,18 @@ ${ret}`);
|
|
|
16086
16195
|
} finally {
|
|
16087
16196
|
setEvalBindingSink(null);
|
|
16088
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
|
+
);
|
|
16089
16210
|
}
|
|
16090
16211
|
}
|
|
16091
16212
|
var evalFallbackCollector = null;
|
|
@@ -16147,14 +16268,16 @@ function isAbsVal(v2) {
|
|
|
16147
16268
|
}
|
|
16148
16269
|
function callTranspiledExportFull(exports, name, args, opts) {
|
|
16149
16270
|
enterEvalCallBudgetSession();
|
|
16271
|
+
beginClassEpoch();
|
|
16150
16272
|
try {
|
|
16151
16273
|
return callTranspiledExportFullInner(exports, name, args, opts);
|
|
16152
16274
|
} finally {
|
|
16153
16275
|
exitEvalCallBudgetSession();
|
|
16276
|
+
noteDrainedClassCollisions();
|
|
16154
16277
|
}
|
|
16155
16278
|
}
|
|
16156
16279
|
function callTranspiledExportFullInner(exports, name, args, opts) {
|
|
16157
|
-
const fn = exports[name];
|
|
16280
|
+
const fn = Object.hasOwn(exports, name) ? exports[name] : void 0;
|
|
16158
16281
|
if (typeof fn === "function") {
|
|
16159
16282
|
const callArgs = args.map(
|
|
16160
16283
|
(a) => a && typeof a === "object" && "shape" in a ? $copy(a) : a
|
|
@@ -16826,6 +16949,7 @@ export {
|
|
|
16826
16949
|
v,
|
|
16827
16950
|
app,
|
|
16828
16951
|
termEquals,
|
|
16952
|
+
litKeyString,
|
|
16829
16953
|
termToString,
|
|
16830
16954
|
simplifyTerm,
|
|
16831
16955
|
TYPEOF_NAMES,
|
|
@@ -16857,6 +16981,8 @@ export {
|
|
|
16857
16981
|
geNum,
|
|
16858
16982
|
ltNum,
|
|
16859
16983
|
leNum,
|
|
16984
|
+
PROJECTION_MAX_DEPTH,
|
|
16985
|
+
ProjectionBudget,
|
|
16860
16986
|
never,
|
|
16861
16987
|
unknown,
|
|
16862
16988
|
anyAbs,
|
|
@@ -17333,6 +17459,7 @@ export {
|
|
|
17333
17459
|
resetEvalFallbackStats,
|
|
17334
17460
|
noteEvalFallback,
|
|
17335
17461
|
tryRunTranspiled,
|
|
17462
|
+
isAbsVal,
|
|
17336
17463
|
callTranspiledExportFull,
|
|
17337
17464
|
callTranspiledExport,
|
|
17338
17465
|
callTranspiledExportApply,
|
package/dist/exec.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as Abs, M as MayThrowEffect, b as Phi } from './run-
|
|
2
|
-
export { O as $assignRecord, Q as $call, U as $callNamed, V as $recordBinding, a1 as EvalAbsAssignRecord, a2 as EvalCallRecord, a3 as EvalFallback, f as EvalFallbackStats, a6 as MAX_EVAL_CALL_DEPTH, a7 as MAX_EVAL_TOTAL_CALLS, a8 as RUNTIME_IMPORT_RE, N as RunTranspiledOptions, aa as TranspiledCallResult, ao as bindingsOf, ar as callTranspiledExport, as as callTranspiledExportApply, at as callTranspiledExportFull, g as clearPureCallMemo, h as clearPureMemo, i as enterEvalCallBudgetSession, ay as evalExprAbs, k as exitEvalCallBudgetSession, q as getEvalCallBudgetState, aB as getEvalCallCollector, r as getEvalFallbackStats,
|
|
1
|
+
import { A as Abs, M as MayThrowEffect, b as Phi } from './run-Dg7gQO2z.js';
|
|
2
|
+
export { O as $assignRecord, Q as $call, U as $callNamed, V as $recordBinding, a1 as EvalAbsAssignRecord, a2 as EvalCallRecord, a3 as EvalFallback, f as EvalFallbackStats, a6 as MAX_EVAL_CALL_DEPTH, a7 as MAX_EVAL_TOTAL_CALLS, a8 as RUNTIME_IMPORT_RE, N as RunTranspiledOptions, aa as TranspiledCallResult, ao as bindingsOf, ar as callTranspiledExport, as as callTranspiledExportApply, at as callTranspiledExportFull, g as clearPureCallMemo, h as clearPureMemo, i as enterEvalCallBudgetSession, ay as evalExprAbs, k as exitEvalCallBudgetSession, q as getEvalCallBudgetState, aB as getEvalCallCollector, r as getEvalFallbackStats, aI as isAbsVal, a_ as noteEvalCallRecord, a$ as noteEvalFallback, bg as resetEvalCallBudget, z as resetEvalFallbackStats, bA as routeApplyThrows, bh as runTranspiled, bi as runTranspiledOptionsMemoKey, bj as setEvalAssignCollector, bk as setEvalBindingSink, bl as setEvalCallCollector, bm as setEvalFallbackCollector, bx as tryRunTranspiled, H as withEvalBudgetOverride } from './run-Dg7gQO2z.js';
|
|
3
3
|
import { Node, Expression, File } from '@babel/types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -584,7 +584,9 @@ declare class NudoUnsupportedError extends Error {
|
|
|
584
584
|
constructor(reason: string, loc?: {
|
|
585
585
|
line: number;
|
|
586
586
|
column: number;
|
|
587
|
-
}
|
|
587
|
+
},
|
|
588
|
+
/** BUG-026:附加辨析面(如 class 碰撞的双方特征)——进 message 随回落观测 */
|
|
589
|
+
detail?: string);
|
|
588
590
|
}
|
|
589
591
|
|
|
590
592
|
export { $add, $arguments, $arr, $arrMutContainer, $arrRest, $arrWithHoles, $async, $asyncReturn, $await, $bitand, $bitnot, $bitor, $bitxor, $catchVal, $class, $classExpr, $collectionForEach, $concat, $copy, $del, $delRes, $div, $dynamicImport, $elems, $eq, $eqLoose, $fnVal, $for, $forInKeys, $forIter, $forOf, $fork, $ge, $gen, $get, $gt, $idx, $idxSet, $importMeta, $in, $instanceof, $instanceofNonIdent, $invoke, $invokeSuper, $isBreakTo, $isForkExit, $join, $le, $len, $lit, $loopBreak, $loopContinue, $loopReturn, $lt, $mod, $mul, $ne, $neLoose, $neg, $new, $not, $nullishTest, $obj, $objAccessor, $objRest, $optionalGet, $optionalInvoke, $orDefault, $pow, $pushLoopExit, $rawThis, $reStateCall, $regex, $rethrowIfNudoReturn, $set, $setKey, $setProto, $shl, $shr, $spread, $staticInvoke, $sub, $super, $switch, $thisGet, $thisSet, $throw, $toNumber, $toNumeric, $tryCurrentMark, $tryDetachSoftCatch, $tryDigestSoftCatch, $tryDiscardSoft, $tryMark, $tryOrphanSoft, $tryPopMark, $tryReleaseSoftCatch, $tryReleaseSoftOut, $tryTakeSince, $typeof, $unknown, $updateAdd, $updateSub, $ushr, $while, $whileSeq, $yield, DEFAULT_MAX_LOOP_ITERS, type EvalClassSpec, NudoLoopSignal, NudoReturn, NudoThrow, NudoUnsupportedError, type TranspileOptions, asAbsVal, callAtFunctionBoundary, clearBClasses, clearStaleTermPred, currentExecPhi, fillTuple, foldRequireSpecArg, foldStaticStringExpr, getEvalClass, isArrMutator, isDefinitelyFalse, isDefinitelyTrue, isNudoBreak, isNudoContinue, isNudoReturn, isNudoThrow, litTruth, lookupObjAccessor, namespaceNameOf, pushLoopExit, pushThrowExit, registerEvalClass, runWithLoopExits, runtimeImportOf, takeLoopExits, takeThrowExits, transpile, transpileBodyNode, transpileExpression, transpileFile, transpileSource, withExecPhi };
|
package/dist/exec.js
CHANGED
|
@@ -140,6 +140,7 @@ import {
|
|
|
140
140
|
getEvalCallCollector,
|
|
141
141
|
getEvalClass,
|
|
142
142
|
getEvalFallbackStats,
|
|
143
|
+
isAbsVal,
|
|
143
144
|
isArrMutator,
|
|
144
145
|
isDefinitelyFalse,
|
|
145
146
|
isDefinitelyTrue,
|
|
@@ -176,7 +177,7 @@ import {
|
|
|
176
177
|
tryRunTranspiled,
|
|
177
178
|
withEvalBudgetOverride,
|
|
178
179
|
withExecPhi
|
|
179
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-LZJC7X5J.js";
|
|
180
181
|
export {
|
|
181
182
|
$add,
|
|
182
183
|
$arguments,
|
|
@@ -318,6 +319,7 @@ export {
|
|
|
318
319
|
getEvalCallCollector,
|
|
319
320
|
getEvalClass,
|
|
320
321
|
getEvalFallbackStats,
|
|
322
|
+
isAbsVal,
|
|
321
323
|
isArrMutator,
|
|
322
324
|
isDefinitelyFalse,
|
|
323
325
|
isDefinitelyTrue,
|