@nudojs/core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RZOQL6PT.js → chunk-P3G2TODS.js} +381 -70
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +1 -1
- package/dist/{index-OfNo5qlN.d.ts → index-FITqyJ8v.d.ts} +1 -1
- package/dist/index.d.ts +180 -227
- package/dist/index.js +158 -1106
- package/package.json +1 -1
|
@@ -309,11 +309,18 @@ var phiAnd = and;
|
|
|
309
309
|
function implies(phi2, pred) {
|
|
310
310
|
if (pred.op === "true") return true;
|
|
311
311
|
if (pred.op === "false") return false;
|
|
312
|
+
if (phi2.op === "false") return true;
|
|
313
|
+
if (predEquals(phi2, pred)) return true;
|
|
314
|
+
if (phi2.op === "and" && phi2.args.some((c) => predEquals(c, pred))) return true;
|
|
315
|
+
if (phi2.op === "or") {
|
|
316
|
+
return phi2.args.every((a) => implies(a, pred));
|
|
317
|
+
}
|
|
318
|
+
if (pred.op === "or") {
|
|
319
|
+
return pred.args.some((b) => implies(phi2, b));
|
|
320
|
+
}
|
|
312
321
|
if (phi2.op === "true") {
|
|
313
322
|
return decideLiteralPred(pred) === true;
|
|
314
323
|
}
|
|
315
|
-
if (predEquals(phi2, pred)) return true;
|
|
316
|
-
if (phi2.op === "and" && phi2.args.some((c) => predEquals(c, pred))) return true;
|
|
317
324
|
const bounds = extractBounds(phi2);
|
|
318
325
|
const implied = impliesViaBounds(pred, bounds);
|
|
319
326
|
if (implied !== void 0) return implied;
|
|
@@ -869,6 +876,141 @@ function coerceToStringParts(a) {
|
|
|
869
876
|
return void 0;
|
|
870
877
|
}
|
|
871
878
|
|
|
879
|
+
// src/algebra/derivation.ts
|
|
880
|
+
var collector = null;
|
|
881
|
+
var nextId = 1;
|
|
882
|
+
var byAbs = /* @__PURE__ */ new WeakMap();
|
|
883
|
+
var sessionNodes = null;
|
|
884
|
+
function setDerivationCollector(fn) {
|
|
885
|
+
collector = fn;
|
|
886
|
+
}
|
|
887
|
+
function hasDerivationSession() {
|
|
888
|
+
return sessionNodes !== null;
|
|
889
|
+
}
|
|
890
|
+
function beginDerivationSession() {
|
|
891
|
+
sessionNodes = /* @__PURE__ */ new Map();
|
|
892
|
+
nextId = 1;
|
|
893
|
+
}
|
|
894
|
+
function endDerivationSession() {
|
|
895
|
+
const nodes = sessionNodes ? [...sessionNodes.values()] : [];
|
|
896
|
+
sessionNodes = null;
|
|
897
|
+
collector = null;
|
|
898
|
+
return nodes;
|
|
899
|
+
}
|
|
900
|
+
function abortDerivationSession() {
|
|
901
|
+
sessionNodes = null;
|
|
902
|
+
collector = null;
|
|
903
|
+
}
|
|
904
|
+
function note(node) {
|
|
905
|
+
const full = { ...node, id: nextId++ };
|
|
906
|
+
if (sessionNodes) sessionNodes.set(full.id, full);
|
|
907
|
+
collector?.(full);
|
|
908
|
+
return full;
|
|
909
|
+
}
|
|
910
|
+
function tagDerivationRoot(abs2, meta) {
|
|
911
|
+
const node = note({
|
|
912
|
+
kind: "root",
|
|
913
|
+
expr: meta.expr,
|
|
914
|
+
...meta.importFrom !== void 0 ? { importFrom: meta.importFrom } : {},
|
|
915
|
+
...meta.importName !== void 0 ? { importName: meta.importName } : {},
|
|
916
|
+
parents: []
|
|
917
|
+
});
|
|
918
|
+
byAbs.set(abs2, node);
|
|
919
|
+
return node;
|
|
920
|
+
}
|
|
921
|
+
function getDerivation(abs2) {
|
|
922
|
+
return byAbs.get(abs2);
|
|
923
|
+
}
|
|
924
|
+
function setDerivation(abs2, node) {
|
|
925
|
+
byAbs.set(abs2, node);
|
|
926
|
+
}
|
|
927
|
+
function derivationChain(node) {
|
|
928
|
+
const chain = [node];
|
|
929
|
+
const seen = /* @__PURE__ */ new Set([node.id]);
|
|
930
|
+
let cur = node;
|
|
931
|
+
while (cur.kind !== "root" && cur.parents.length > 0) {
|
|
932
|
+
const pid = cur.parents[0];
|
|
933
|
+
if (seen.has(pid) || !sessionNodes) break;
|
|
934
|
+
const parent = sessionNodes.get(pid);
|
|
935
|
+
if (!parent) break;
|
|
936
|
+
seen.add(pid);
|
|
937
|
+
chain.push(parent);
|
|
938
|
+
cur = parent;
|
|
939
|
+
}
|
|
940
|
+
return chain;
|
|
941
|
+
}
|
|
942
|
+
function noteDerivationAdd(a, b, result) {
|
|
943
|
+
if (!sessionNodes) return;
|
|
944
|
+
const vb = litValue(b);
|
|
945
|
+
const va = litValue(a);
|
|
946
|
+
let parent;
|
|
947
|
+
let offset;
|
|
948
|
+
if (typeof vb === "number" && Number.isFinite(vb)) {
|
|
949
|
+
parent = byAbs.get(a);
|
|
950
|
+
offset = vb;
|
|
951
|
+
} else if (typeof va === "number" && Number.isFinite(va)) {
|
|
952
|
+
parent = byAbs.get(b);
|
|
953
|
+
offset = va;
|
|
954
|
+
}
|
|
955
|
+
if (!parent || offset === void 0) return;
|
|
956
|
+
const node = note({
|
|
957
|
+
kind: "shift",
|
|
958
|
+
offset,
|
|
959
|
+
parents: [parent.id]
|
|
960
|
+
});
|
|
961
|
+
byAbs.set(result, node);
|
|
962
|
+
}
|
|
963
|
+
function noteDerivationJoin(inputs, result) {
|
|
964
|
+
if (!sessionNodes) return;
|
|
965
|
+
const parents = [];
|
|
966
|
+
for (const a of inputs) {
|
|
967
|
+
const n = byAbs.get(a);
|
|
968
|
+
if (n && !parents.includes(n.id)) parents.push(n.id);
|
|
969
|
+
}
|
|
970
|
+
if (parents.length === 0) return;
|
|
971
|
+
const node = note({ kind: "join", parents });
|
|
972
|
+
byAbs.set(result, node);
|
|
973
|
+
}
|
|
974
|
+
function projectDerivationDsl(node, localName) {
|
|
975
|
+
const chain = derivationChain(node);
|
|
976
|
+
const root = chain[chain.length - 1];
|
|
977
|
+
if (!root || root.kind !== "root" || root.expr === void 0) return void 0;
|
|
978
|
+
if (chain.some((n) => n.kind === "join" || n.kind === "opaque")) return void 0;
|
|
979
|
+
const shifts = [];
|
|
980
|
+
for (let i = chain.length - 2; i >= 0; i--) {
|
|
981
|
+
const n = chain[i];
|
|
982
|
+
if (n.kind !== "shift" || n.offset === void 0) return void 0;
|
|
983
|
+
shifts.push(n.offset);
|
|
984
|
+
}
|
|
985
|
+
const rootExpr = root.expr;
|
|
986
|
+
const imports = [];
|
|
987
|
+
if (root.importFrom !== void 0) {
|
|
988
|
+
imports.push({
|
|
989
|
+
name: root.importName ?? rootExpr,
|
|
990
|
+
from: root.importFrom
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
if (shifts.length === 0) {
|
|
994
|
+
return { prelude: [], expr: rootExpr, imports };
|
|
995
|
+
}
|
|
996
|
+
let current = rootExpr;
|
|
997
|
+
const prelude = [];
|
|
998
|
+
for (let i = 0; i < shifts.length; i++) {
|
|
999
|
+
const step = `${current}.shift(${shifts[i]})`;
|
|
1000
|
+
if (i === shifts.length - 1) {
|
|
1001
|
+
prelude.push(`const ${localName} = ${step};`);
|
|
1002
|
+
return { prelude, expr: localName, imports };
|
|
1003
|
+
}
|
|
1004
|
+
const tmp = `${localName}_${i}`;
|
|
1005
|
+
prelude.push(`const ${tmp} = ${step};`);
|
|
1006
|
+
current = tmp;
|
|
1007
|
+
}
|
|
1008
|
+
return void 0;
|
|
1009
|
+
}
|
|
1010
|
+
function termKey3(t) {
|
|
1011
|
+
return t === void 0 ? "<none>" : termToString(t);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
872
1014
|
// src/algebra/objects.ts
|
|
873
1015
|
function objOf(slots, opts) {
|
|
874
1016
|
const shape = { k: "obj", slots };
|
|
@@ -970,29 +1112,59 @@ function flattenSum(xs) {
|
|
|
970
1112
|
const seen = /* @__PURE__ */ new Set();
|
|
971
1113
|
const deduped = [];
|
|
972
1114
|
for (const x of out) {
|
|
973
|
-
const key =
|
|
1115
|
+
const key = absShapeKey(x);
|
|
974
1116
|
if (seen.has(key)) continue;
|
|
975
1117
|
seen.add(key);
|
|
976
1118
|
deduped.push(x);
|
|
977
1119
|
}
|
|
978
1120
|
return deduped;
|
|
979
1121
|
}
|
|
980
|
-
function
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1122
|
+
function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
1123
|
+
if (seen.has(a)) return "cycle";
|
|
1124
|
+
seen.add(a);
|
|
1125
|
+
try {
|
|
1126
|
+
const s = a.shape;
|
|
1127
|
+
if (s.k === "prim") {
|
|
1128
|
+
const lv = litValue(a);
|
|
1129
|
+
if (lv !== void 0) return `prim:${s.type}:${String(lv)}`;
|
|
1130
|
+
const t = a.term ? termToString(a.term) : "";
|
|
1131
|
+
const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
|
|
1132
|
+
return `prim:${s.type}:${t}:${p}`;
|
|
1133
|
+
}
|
|
1134
|
+
if (s.k === "never") return "never";
|
|
1135
|
+
if (s.k === "any") return "any";
|
|
1136
|
+
if (s.k === "unknown") return "unknown";
|
|
1137
|
+
if (s.k === "arr") return `arr(${absShapeKey(s.element, seen)})`;
|
|
1138
|
+
if (s.k === "tuple") {
|
|
1139
|
+
const els = s.elements.map((e) => absShapeKey(e, seen)).join(",");
|
|
1140
|
+
const rest = s.rest ? `...${absShapeKey(s.rest, seen)}` : "";
|
|
1141
|
+
return `tuple[${els}${rest}]`;
|
|
1142
|
+
}
|
|
1143
|
+
if (s.k === "brand") return `brand:${s.name}(${absShapeKey(s.shape, seen)})`;
|
|
1144
|
+
if (s.k === "eff") return `eff:${s.eff}<${absShapeKey(s.inner, seen)}>`;
|
|
1145
|
+
if (s.k === "obj") {
|
|
1146
|
+
const slots = Object.keys(s.slots).sort().map((k) => {
|
|
1147
|
+
const slot = s.slots[k];
|
|
1148
|
+
const flags = (slot.optional ? "?" : "") + (slot.readonly ? "r" : "");
|
|
1149
|
+
return `${k}${flags}:${absShapeKey(slot.value, seen)}`;
|
|
1150
|
+
}).join(",");
|
|
1151
|
+
const idx = s.index ? `idx(${absShapeKey(s.index.key, seen)}\u2192${absShapeKey(s.index.value, seen)})` : "";
|
|
1152
|
+
const open = s.open ? "open" : "";
|
|
1153
|
+
return `obj{${slots}}${idx}${open}`;
|
|
1154
|
+
}
|
|
1155
|
+
if (s.k === "fn") {
|
|
1156
|
+
const pts = (s.paramTypes ?? []).map((t) => absShapeKey(t, seen)).join(",");
|
|
1157
|
+
const ret = s.returnType ? absShapeKey(s.returnType, seen) : "?";
|
|
1158
|
+
const name = s.name ? `#${s.name}` : "";
|
|
1159
|
+
return `fn${name}(${s.params.join(",")}|${pts})=>${ret}`;
|
|
1160
|
+
}
|
|
1161
|
+
if (s.k === "sum") {
|
|
1162
|
+
return `sum(${s.members.map((m) => absShapeKey(m, seen)).join("|")})`;
|
|
1163
|
+
}
|
|
1164
|
+
return "other";
|
|
1165
|
+
} finally {
|
|
1166
|
+
seen.delete(a);
|
|
988
1167
|
}
|
|
989
|
-
if (s.k === "never") return "never";
|
|
990
|
-
if (s.k === "any") return "any";
|
|
991
|
-
if (s.k === "unknown") return "unknown";
|
|
992
|
-
if (s.k === "obj") return `obj:${Object.keys(s.slots).sort().join(",")}`;
|
|
993
|
-
if (s.k === "fn") return `fn:${s.params.length}`;
|
|
994
|
-
if (s.k === "sum") return `sum:${s.members.length}`;
|
|
995
|
-
return "other";
|
|
996
1168
|
}
|
|
997
1169
|
function fnOf(params, name) {
|
|
998
1170
|
const shape = { k: "fn", params };
|
|
@@ -1017,7 +1189,9 @@ function joinAbs(a, b) {
|
|
|
1017
1189
|
if (b.shape.k === "never") return a;
|
|
1018
1190
|
if (isObj(a) && isObj(b)) return joinObjects(a, b);
|
|
1019
1191
|
if (a.shape.k === "fn" && b.shape.k === "fn") return joinFunctions(a, b);
|
|
1020
|
-
|
|
1192
|
+
const result = joinValues(a, b);
|
|
1193
|
+
noteDerivationJoin([a, b], result);
|
|
1194
|
+
return result;
|
|
1021
1195
|
}
|
|
1022
1196
|
|
|
1023
1197
|
// src/algebra/arithmetic.ts
|
|
@@ -1042,7 +1216,9 @@ function add(a, b, phi2 = pTrue) {
|
|
|
1042
1216
|
const term = simplifyTerm(app("+", [a.term, b.term]));
|
|
1043
1217
|
const pred = addPred(a, b, term, phi2);
|
|
1044
1218
|
const conf = term.op === "lit" ? "exact" : confJoin(confJoin(a.conf, b.conf), "path");
|
|
1045
|
-
|
|
1219
|
+
const result = abs({ k: "prim", type: "number" }, term, pred, conf);
|
|
1220
|
+
noteDerivationAdd(a, b, result);
|
|
1221
|
+
return result;
|
|
1046
1222
|
}
|
|
1047
1223
|
if (isAnyLike(a) || isAnyLike(b)) {
|
|
1048
1224
|
const term = a.term && b.term ? simplifyTerm(app("+", [a.term, b.term])) : void 0;
|
|
@@ -1081,7 +1257,7 @@ function dedupAbsMembers(ms) {
|
|
|
1081
1257
|
const seen = /* @__PURE__ */ new Set();
|
|
1082
1258
|
const out = [];
|
|
1083
1259
|
for (const m of ms) {
|
|
1084
|
-
const key = m
|
|
1260
|
+
const key = absShapeKey(m);
|
|
1085
1261
|
if (seen.has(key)) continue;
|
|
1086
1262
|
seen.add(key);
|
|
1087
1263
|
out.push(m);
|
|
@@ -1161,7 +1337,7 @@ function collectBoundsFromPred(pred, term, acc) {
|
|
|
1161
1337
|
}
|
|
1162
1338
|
if (p.op === "gt" && match(p.a) && p.b.op === "lit" && typeof p.b.value === "number") {
|
|
1163
1339
|
const n = p.b.value;
|
|
1164
|
-
if (acc.lo === void 0 || n > acc.lo.value || n === acc.lo.value &&
|
|
1340
|
+
if (acc.lo === void 0 || n > acc.lo.value || n === acc.lo.value && !acc.lo.strict) {
|
|
1165
1341
|
acc.lo = { value: n, strict: true };
|
|
1166
1342
|
}
|
|
1167
1343
|
return;
|
|
@@ -1175,7 +1351,7 @@ function collectBoundsFromPred(pred, term, acc) {
|
|
|
1175
1351
|
}
|
|
1176
1352
|
if (p.op === "lt" && match(p.a) && p.b.op === "lit" && typeof p.b.value === "number") {
|
|
1177
1353
|
const n = p.b.value;
|
|
1178
|
-
if (acc.hi === void 0 || n < acc.hi.value) {
|
|
1354
|
+
if (acc.hi === void 0 || n < acc.hi.value || n === acc.hi.value && !acc.hi.strict) {
|
|
1179
1355
|
acc.hi = { value: n, strict: true };
|
|
1180
1356
|
}
|
|
1181
1357
|
return;
|
|
@@ -1194,7 +1370,7 @@ function collectBoundsFromPhi(phi2, id, acc) {
|
|
|
1194
1370
|
for (const p of conjs) {
|
|
1195
1371
|
if (p.op === "gt" && p.a.op === "var" && p.a.id === id && p.b.op === "lit" && typeof p.b.value === "number") {
|
|
1196
1372
|
const n = p.b.value;
|
|
1197
|
-
if (acc.lo === void 0 || n > acc.lo.value) {
|
|
1373
|
+
if (acc.lo === void 0 || n > acc.lo.value || n === acc.lo.value && !acc.lo.strict) {
|
|
1198
1374
|
acc.lo = { value: n, strict: true };
|
|
1199
1375
|
}
|
|
1200
1376
|
}
|
|
@@ -1206,7 +1382,7 @@ function collectBoundsFromPhi(phi2, id, acc) {
|
|
|
1206
1382
|
}
|
|
1207
1383
|
if (p.op === "lt" && p.a.op === "var" && p.a.id === id && p.b.op === "lit" && typeof p.b.value === "number") {
|
|
1208
1384
|
const n = p.b.value;
|
|
1209
|
-
if (acc.hi === void 0 || n < acc.hi.value) {
|
|
1385
|
+
if (acc.hi === void 0 || n < acc.hi.value || n === acc.hi.value && !acc.hi.strict) {
|
|
1210
1386
|
acc.hi = { value: n, strict: true };
|
|
1211
1387
|
}
|
|
1212
1388
|
}
|
|
@@ -1640,7 +1816,7 @@ function flipBounds(pred, src, dst, out) {
|
|
|
1640
1816
|
if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le") {
|
|
1641
1817
|
return;
|
|
1642
1818
|
}
|
|
1643
|
-
if (
|
|
1819
|
+
if (termKey4(p.a) !== termKey4(src)) return;
|
|
1644
1820
|
if (p.b.op !== "lit" || typeof p.b.value !== "number") return;
|
|
1645
1821
|
const n = p.b.value;
|
|
1646
1822
|
if (p.op === "gt") out.push(lt(dst, lit(-n)));
|
|
@@ -1650,7 +1826,7 @@ function flipBounds(pred, src, dst, out) {
|
|
|
1650
1826
|
};
|
|
1651
1827
|
apply(pred);
|
|
1652
1828
|
}
|
|
1653
|
-
function
|
|
1829
|
+
function termKey4(t) {
|
|
1654
1830
|
if (t.op === "lit") return `lit:${JSON.stringify(t.value)}`;
|
|
1655
1831
|
if (t.op === "var") return `var:${t.id}`;
|
|
1656
1832
|
return `app:${t.fn}`;
|
|
@@ -2138,6 +2314,8 @@ function evalMathMethod(name, args) {
|
|
|
2138
2314
|
case "round":
|
|
2139
2315
|
if (typeof a0 === "number") return numLit(Math.round(a0));
|
|
2140
2316
|
return numPrim();
|
|
2317
|
+
case "random":
|
|
2318
|
+
return numPrim("path");
|
|
2141
2319
|
case "sqrt":
|
|
2142
2320
|
if (typeof a0 === "number") return numLit(Math.sqrt(a0));
|
|
2143
2321
|
return numPrim();
|
|
@@ -2217,6 +2395,12 @@ function evalJsonMethod(name, args) {
|
|
|
2217
2395
|
if (name === "parse") return unknown;
|
|
2218
2396
|
return void 0;
|
|
2219
2397
|
}
|
|
2398
|
+
function foldParseInt(s, radix) {
|
|
2399
|
+
const str2 = String(s);
|
|
2400
|
+
if (radix === void 0) return numLit(parseInt(str2));
|
|
2401
|
+
if (!Number.isInteger(radix) || radix < 2 || radix > 36) return numLit(NaN);
|
|
2402
|
+
return numLit(parseInt(str2, radix));
|
|
2403
|
+
}
|
|
2220
2404
|
function evalNumberStatic(name, args) {
|
|
2221
2405
|
const a0 = args[0] ? litValue(args[0]) : void 0;
|
|
2222
2406
|
switch (name) {
|
|
@@ -2230,12 +2414,16 @@ function evalNumberStatic(name, args) {
|
|
|
2230
2414
|
if (typeof a0 === "number") return boolLit(Number.isFinite(a0));
|
|
2231
2415
|
return boolPrim();
|
|
2232
2416
|
case "parseInt":
|
|
2233
|
-
case "parseFloat":
|
|
2234
2417
|
if (typeof a0 === "string" || typeof a0 === "number") {
|
|
2235
|
-
const
|
|
2236
|
-
return
|
|
2418
|
+
const radix = args[1] ? litValue(args[1]) : void 0;
|
|
2419
|
+
if (radix === void 0) return foldParseInt(a0, void 0);
|
|
2420
|
+
if (typeof radix === "number") return foldParseInt(a0, radix);
|
|
2421
|
+
return numPrim();
|
|
2237
2422
|
}
|
|
2238
2423
|
return numPrim();
|
|
2424
|
+
case "parseFloat":
|
|
2425
|
+
if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
|
|
2426
|
+
return numPrim();
|
|
2239
2427
|
case "MAX_SAFE_INTEGER":
|
|
2240
2428
|
return numLit(Number.MAX_SAFE_INTEGER);
|
|
2241
2429
|
default:
|
|
@@ -2246,7 +2434,12 @@ function evalGlobalFn(name, args) {
|
|
|
2246
2434
|
const a0 = args[0] ? litValue(args[0]) : void 0;
|
|
2247
2435
|
switch (name) {
|
|
2248
2436
|
case "parseInt":
|
|
2249
|
-
if (typeof a0 === "string" || typeof a0 === "number")
|
|
2437
|
+
if (typeof a0 === "string" || typeof a0 === "number") {
|
|
2438
|
+
const radix = args[1] ? litValue(args[1]) : void 0;
|
|
2439
|
+
if (radix === void 0) return foldParseInt(a0, void 0);
|
|
2440
|
+
if (typeof radix === "number") return foldParseInt(a0, radix);
|
|
2441
|
+
return numPrim();
|
|
2442
|
+
}
|
|
2250
2443
|
return numPrim();
|
|
2251
2444
|
case "parseFloat":
|
|
2252
2445
|
if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
|
|
@@ -2269,13 +2462,20 @@ function evalGlobalFn(name, args) {
|
|
|
2269
2462
|
return void 0;
|
|
2270
2463
|
}
|
|
2271
2464
|
}
|
|
2465
|
+
function peelBrand(shape) {
|
|
2466
|
+
let s = shape;
|
|
2467
|
+
while (s.k === "brand") s = s.shape.shape;
|
|
2468
|
+
return s;
|
|
2469
|
+
}
|
|
2272
2470
|
function evalArrayStatic(name, args) {
|
|
2273
2471
|
const a0 = args[0];
|
|
2274
2472
|
switch (name) {
|
|
2275
2473
|
case "isArray": {
|
|
2276
2474
|
if (!a0) return boolLit(false);
|
|
2277
|
-
const
|
|
2278
|
-
|
|
2475
|
+
const s = peelBrand(a0.shape);
|
|
2476
|
+
if (s.k === "arr" || s.k === "tuple") return boolLit(true);
|
|
2477
|
+
if (s.k === "any" || s.k === "unknown" || s.k === "sum") return boolPrim();
|
|
2478
|
+
return boolLit(false);
|
|
2279
2479
|
}
|
|
2280
2480
|
case "of":
|
|
2281
2481
|
return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
|
|
@@ -2313,7 +2513,7 @@ function evalDateCtor(args) {
|
|
|
2313
2513
|
);
|
|
2314
2514
|
}
|
|
2315
2515
|
function evalDateStatic(name, _args) {
|
|
2316
|
-
if (name === "now") return
|
|
2516
|
+
if (name === "now") return numPrim("path");
|
|
2317
2517
|
return void 0;
|
|
2318
2518
|
}
|
|
2319
2519
|
function evalDateMethod(name, _recv, _args) {
|
|
@@ -3355,7 +3555,7 @@ function callAbsMethod(recv, name, args) {
|
|
|
3355
3555
|
const parts = lit3.split(sep).map((s) => strLit(s));
|
|
3356
3556
|
return abs({ k: "tuple", elements: parts }, void 0, void 0, "exact");
|
|
3357
3557
|
}
|
|
3358
|
-
return
|
|
3558
|
+
return strArr("path");
|
|
3359
3559
|
}
|
|
3360
3560
|
return strArr("path");
|
|
3361
3561
|
}
|
|
@@ -3640,8 +3840,8 @@ function callBudgetKey(kind, id, args) {
|
|
|
3640
3840
|
return `${kind}|${id}|${parts.join(",")}`;
|
|
3641
3841
|
}
|
|
3642
3842
|
var absTruncCollector = null;
|
|
3643
|
-
function setAbsTruncationCollector(
|
|
3644
|
-
absTruncCollector =
|
|
3843
|
+
function setAbsTruncationCollector(collector2) {
|
|
3844
|
+
absTruncCollector = collector2;
|
|
3645
3845
|
}
|
|
3646
3846
|
function noteTruncation(label) {
|
|
3647
3847
|
if (!absTruncCollector) return;
|
|
@@ -3665,8 +3865,10 @@ function exitCall() {
|
|
|
3665
3865
|
_activeCallKeys.pop();
|
|
3666
3866
|
}
|
|
3667
3867
|
var absCallCollector = null;
|
|
3668
|
-
function setAbsCallCollector(
|
|
3669
|
-
|
|
3868
|
+
function setAbsCallCollector(collector2) {
|
|
3869
|
+
const prev = absCallCollector;
|
|
3870
|
+
absCallCollector = collector2;
|
|
3871
|
+
return prev;
|
|
3670
3872
|
}
|
|
3671
3873
|
function recordAbsCall(fnName, args, result, callLoc, threw) {
|
|
3672
3874
|
if (!absCallCollector) return;
|
|
@@ -3676,8 +3878,8 @@ function recordAbsCall(fnName, args, result, callLoc, threw) {
|
|
|
3676
3878
|
}
|
|
3677
3879
|
}
|
|
3678
3880
|
var absNodeCollector = null;
|
|
3679
|
-
function setAbsNodeCollector(
|
|
3680
|
-
absNodeCollector =
|
|
3881
|
+
function setAbsNodeCollector(collector2) {
|
|
3882
|
+
absNodeCollector = collector2;
|
|
3681
3883
|
}
|
|
3682
3884
|
function recordAbsNode(node, value) {
|
|
3683
3885
|
if (!absNodeCollector || !value) return;
|
|
@@ -3688,8 +3890,8 @@ function recordAbsNode(node, value) {
|
|
|
3688
3890
|
}
|
|
3689
3891
|
var absAssignCollector = null;
|
|
3690
3892
|
var assignFlowDepth = 0;
|
|
3691
|
-
function setAbsAssignCollector(
|
|
3692
|
-
absAssignCollector =
|
|
3893
|
+
function setAbsAssignCollector(collector2) {
|
|
3894
|
+
absAssignCollector = collector2;
|
|
3693
3895
|
}
|
|
3694
3896
|
function evalInConditionalFlow(body) {
|
|
3695
3897
|
assignFlowDepth++;
|
|
@@ -3718,6 +3920,16 @@ function evalSource(source, entry, opts = {}) {
|
|
|
3718
3920
|
const file = opts.file ?? parseSource(source);
|
|
3719
3921
|
const env = emptyEnv();
|
|
3720
3922
|
let phi2 = opts.phi ?? pTrue;
|
|
3923
|
+
if (opts.seedVars) {
|
|
3924
|
+
for (const [k, v2] of Object.entries(opts.seedVars)) {
|
|
3925
|
+
env.vars.set(k, v2);
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
if (opts.seedFns) {
|
|
3929
|
+
for (const [k, fn] of Object.entries(opts.seedFns)) {
|
|
3930
|
+
env.fns.set(k, fn);
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3721
3933
|
if (opts.modules) {
|
|
3722
3934
|
for (const stmt of file.program.body) {
|
|
3723
3935
|
if (stmt.type === "ImportDeclaration") {
|
|
@@ -3751,8 +3963,13 @@ function evalSource(source, entry, opts = {}) {
|
|
|
3751
3963
|
}
|
|
3752
3964
|
}
|
|
3753
3965
|
}
|
|
3754
|
-
const
|
|
3755
|
-
return {
|
|
3966
|
+
const full = callFunctionFull(env, entry.fn, entry.args, phi2, opts.budget);
|
|
3967
|
+
return {
|
|
3968
|
+
value: full.result,
|
|
3969
|
+
phi: phi2,
|
|
3970
|
+
env,
|
|
3971
|
+
...full.throws.shape.k !== "never" ? { threw: true, ...full.throwLoc ? { throwLoc: full.throwLoc } : {} } : {}
|
|
3972
|
+
};
|
|
3756
3973
|
}
|
|
3757
3974
|
function registerClassDecl(env, node) {
|
|
3758
3975
|
const cls = node;
|
|
@@ -3808,6 +4025,37 @@ function registerFunction(env, decl) {
|
|
|
3808
4025
|
async: decl.async === true
|
|
3809
4026
|
});
|
|
3810
4027
|
}
|
|
4028
|
+
function callFunctionFull(env, name, args, phi2 = pTrue, budget = defaultLeakBudget) {
|
|
4029
|
+
const fn = env.fns.get(name);
|
|
4030
|
+
const neverAbs = abs({ k: "never" }, void 0, void 0, "exact");
|
|
4031
|
+
if (!fn) return { result: unknown, throws: neverAbs };
|
|
4032
|
+
const key = callBudgetKey("fn", name, args);
|
|
4033
|
+
if (!enterCall(key, name)) {
|
|
4034
|
+
return { result: truncatedAbs(), throws: neverAbs };
|
|
4035
|
+
}
|
|
4036
|
+
try {
|
|
4037
|
+
let local = { vars: new Map(env.vars), fns: env.fns, hofCollect: env.hofCollect };
|
|
4038
|
+
const cls = env.classes;
|
|
4039
|
+
if (cls) local.classes = cls;
|
|
4040
|
+
fn.params.forEach((p, i) => {
|
|
4041
|
+
local.vars.set(p, args[i] ?? unknown);
|
|
4042
|
+
});
|
|
4043
|
+
const result = evalNode(fn.body, local, phi2, budget);
|
|
4044
|
+
if (result.threw) {
|
|
4045
|
+
return {
|
|
4046
|
+
result: neverAbs,
|
|
4047
|
+
throws: result.value,
|
|
4048
|
+
...result.throwLoc ? { throwLoc: result.throwLoc } : {}
|
|
4049
|
+
};
|
|
4050
|
+
}
|
|
4051
|
+
if (fn.async) {
|
|
4052
|
+
return { result: coerceAsyncReturn(result.value), throws: neverAbs };
|
|
4053
|
+
}
|
|
4054
|
+
return { result: result.value, throws: neverAbs };
|
|
4055
|
+
} finally {
|
|
4056
|
+
exitCall();
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
3811
4059
|
function callFunction(env, name, args, phi2 = pTrue, budget = defaultLeakBudget) {
|
|
3812
4060
|
const fn = env.fns.get(name);
|
|
3813
4061
|
if (!fn) return unknown;
|
|
@@ -3974,7 +4222,18 @@ function evalNodeInner(node, env, phi2, budget) {
|
|
|
3974
4222
|
case "ThrowStatement": {
|
|
3975
4223
|
const arg = node.argument;
|
|
3976
4224
|
const v2 = arg ? evalNode(arg, env, phi2, budget).value : unknown;
|
|
3977
|
-
|
|
4225
|
+
const loc = node.loc ? { line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
4226
|
+
return { value: v2, phi: phi2, env, threw: true, ...loc ? { throwLoc: loc } : {} };
|
|
4227
|
+
}
|
|
4228
|
+
case "ConditionalExpression": {
|
|
4229
|
+
const cond = node;
|
|
4230
|
+
const t = evalNode(cond.test, env, phi2, budget).value;
|
|
4231
|
+
const tv = litValue(t);
|
|
4232
|
+
if (tv === true) return evalNode(cond.consequent, env, phi2, budget);
|
|
4233
|
+
if (tv === false) return evalNode(cond.alternate, env, phi2, budget);
|
|
4234
|
+
const a = evalNode(cond.consequent, env, phi2, budget);
|
|
4235
|
+
const b = evalNode(cond.alternate, env, phi2, budget);
|
|
4236
|
+
return { value: joinAbs(a.value, b.value), phi: phi2, env };
|
|
3978
4237
|
}
|
|
3979
4238
|
case "ForStatement":
|
|
3980
4239
|
return evalFor(node, env, phi2, budget);
|
|
@@ -4425,18 +4684,27 @@ function evalCall(node, env, phi2, budget) {
|
|
|
4425
4684
|
}
|
|
4426
4685
|
if (obj2.shape.k === "tuple") {
|
|
4427
4686
|
const kept = [];
|
|
4428
|
-
|
|
4429
|
-
|
|
4687
|
+
let anyUncertain = false;
|
|
4688
|
+
for (const el2 of obj2.shape.elements) {
|
|
4689
|
+
const p = applyUnaryCallback(fnNode, el2, env, phi2, budget);
|
|
4430
4690
|
const lv = litValue(p);
|
|
4431
4691
|
if (lv === false) continue;
|
|
4432
|
-
|
|
4692
|
+
if (lv !== true) anyUncertain = true;
|
|
4693
|
+
kept.push(el2);
|
|
4433
4694
|
}
|
|
4434
4695
|
if (kept.length === 0) {
|
|
4435
4696
|
return ok2(abs({ k: "arr", element: unknown }, void 0, void 0, "path"), phi2, env);
|
|
4436
4697
|
}
|
|
4437
|
-
if (
|
|
4698
|
+
if (!anyUncertain) {
|
|
4699
|
+
return ok2(
|
|
4700
|
+
abs({ k: "tuple", elements: kept }, void 0, void 0, confJoin(obj2.conf, "path")),
|
|
4701
|
+
phi2,
|
|
4702
|
+
env
|
|
4703
|
+
);
|
|
4704
|
+
}
|
|
4705
|
+
const el = kept.reduce((a, b) => joinAbs(a, b));
|
|
4438
4706
|
return ok2(
|
|
4439
|
-
abs({ k: "
|
|
4707
|
+
abs({ k: "arr", element: el }, void 0, void 0, confJoin(obj2.conf, "path")),
|
|
4440
4708
|
phi2,
|
|
4441
4709
|
env
|
|
4442
4710
|
);
|
|
@@ -4647,7 +4915,16 @@ function evalBlock(node, env, phi2, budget) {
|
|
|
4647
4915
|
pendingPartial = void 0;
|
|
4648
4916
|
}
|
|
4649
4917
|
if (r.returned || r.brk || r.cont || r.threw) {
|
|
4650
|
-
return {
|
|
4918
|
+
return {
|
|
4919
|
+
value: last,
|
|
4920
|
+
phi: curPhi,
|
|
4921
|
+
env: local,
|
|
4922
|
+
returned: r.returned,
|
|
4923
|
+
brk: r.brk,
|
|
4924
|
+
cont: r.cont,
|
|
4925
|
+
threw: r.threw,
|
|
4926
|
+
...r.throwLoc ? { throwLoc: r.throwLoc } : {}
|
|
4927
|
+
};
|
|
4651
4928
|
}
|
|
4652
4929
|
}
|
|
4653
4930
|
if (pendingPartial !== void 0) {
|
|
@@ -4838,6 +5115,20 @@ function evalIf(node, env, phi2, budget) {
|
|
|
4838
5115
|
function analyzeFn(source, fnName, args, phi2 = pTrue, budget, file, modules) {
|
|
4839
5116
|
return evalSource(source, { fn: fnName, args }, { phi: phi2, budget, file, modules }).value;
|
|
4840
5117
|
}
|
|
5118
|
+
function analyzeFnFull(source, fnName, args, opts = {}) {
|
|
5119
|
+
const r = evalSource(source, { fn: fnName, args }, opts);
|
|
5120
|
+
if (r.threw) {
|
|
5121
|
+
return {
|
|
5122
|
+
result: abs({ k: "never" }, void 0, void 0, "exact"),
|
|
5123
|
+
throws: r.value,
|
|
5124
|
+
...r.throwLoc ? { throwLoc: r.throwLoc } : {}
|
|
5125
|
+
};
|
|
5126
|
+
}
|
|
5127
|
+
return {
|
|
5128
|
+
result: r.value,
|
|
5129
|
+
throws: abs({ k: "never" }, void 0, void 0, "exact")
|
|
5130
|
+
};
|
|
5131
|
+
}
|
|
4841
5132
|
function evalProgramAbs(source, opts = {}) {
|
|
4842
5133
|
resetAbsCallBudget();
|
|
4843
5134
|
const file = opts.file ?? parseSource(source);
|
|
@@ -4971,8 +5262,8 @@ var GLOBAL_FNS = /* @__PURE__ */ new Set([
|
|
|
4971
5262
|
"String",
|
|
4972
5263
|
"Boolean"
|
|
4973
5264
|
]);
|
|
4974
|
-
function setBCallCollector(
|
|
4975
|
-
bCallCollector =
|
|
5265
|
+
function setBCallCollector(collector2) {
|
|
5266
|
+
bCallCollector = collector2;
|
|
4976
5267
|
}
|
|
4977
5268
|
function getBCallCollector() {
|
|
4978
5269
|
return bCallCollector;
|
|
@@ -6725,6 +7016,10 @@ function invokeArrMethod(arr, method, args) {
|
|
|
6725
7016
|
return acc;
|
|
6726
7017
|
}
|
|
6727
7018
|
if (method === "filter" && args[0]) {
|
|
7019
|
+
if (shape.k === "tuple") {
|
|
7020
|
+
const el = shape.elements.length > 0 ? shape.elements.reduce((a, b) => joinAbs(a, b)) : unknown;
|
|
7021
|
+
return abs({ k: "arr", element: el }, void 0, void 0, confJoin(arr.conf, "path"));
|
|
7022
|
+
}
|
|
6728
7023
|
return arr;
|
|
6729
7024
|
}
|
|
6730
7025
|
if (method === "flatMap" && args[0]) {
|
|
@@ -7150,22 +7445,6 @@ export {
|
|
|
7150
7445
|
isStrPrim,
|
|
7151
7446
|
isExactLit,
|
|
7152
7447
|
litValue,
|
|
7153
|
-
viewTemplateParts,
|
|
7154
|
-
knownPrefixOfViews,
|
|
7155
|
-
knownSuffixOfViews,
|
|
7156
|
-
allFixedTextOfViews,
|
|
7157
|
-
fixedLengthOfViews,
|
|
7158
|
-
formatTemplateNameViews,
|
|
7159
|
-
mergeAdjacentFixedViews,
|
|
7160
|
-
templateMatchesValue,
|
|
7161
|
-
decideStartsWith,
|
|
7162
|
-
decideEndsWith,
|
|
7163
|
-
decideIncludes,
|
|
7164
|
-
absTemplateViews,
|
|
7165
|
-
templatePartsOf,
|
|
7166
|
-
createTemplateAbs,
|
|
7167
|
-
isTemplateLike,
|
|
7168
|
-
concatString,
|
|
7169
7448
|
stripTypes,
|
|
7170
7449
|
resetParseSourceCache,
|
|
7171
7450
|
getParseSourceCacheSize,
|
|
@@ -7176,6 +7455,19 @@ export {
|
|
|
7176
7455
|
relationFingerprint,
|
|
7177
7456
|
relationFn,
|
|
7178
7457
|
shapeOnlyFn,
|
|
7458
|
+
setDerivationCollector,
|
|
7459
|
+
hasDerivationSession,
|
|
7460
|
+
beginDerivationSession,
|
|
7461
|
+
endDerivationSession,
|
|
7462
|
+
abortDerivationSession,
|
|
7463
|
+
tagDerivationRoot,
|
|
7464
|
+
getDerivation,
|
|
7465
|
+
setDerivation,
|
|
7466
|
+
derivationChain,
|
|
7467
|
+
noteDerivationAdd,
|
|
7468
|
+
noteDerivationJoin,
|
|
7469
|
+
projectDerivationDsl,
|
|
7470
|
+
termKey3 as termKey,
|
|
7179
7471
|
objOf,
|
|
7180
7472
|
isObj,
|
|
7181
7473
|
getSlot,
|
|
@@ -7183,6 +7475,7 @@ export {
|
|
|
7183
7475
|
joinObjects,
|
|
7184
7476
|
joinValues,
|
|
7185
7477
|
makeSum,
|
|
7478
|
+
absShapeKey,
|
|
7186
7479
|
fnOf,
|
|
7187
7480
|
joinFunctions,
|
|
7188
7481
|
joinAbs,
|
|
@@ -7205,6 +7498,22 @@ export {
|
|
|
7205
7498
|
mapElementFallback,
|
|
7206
7499
|
projectFlatMapResult,
|
|
7207
7500
|
asAbs,
|
|
7501
|
+
viewTemplateParts,
|
|
7502
|
+
knownPrefixOfViews,
|
|
7503
|
+
knownSuffixOfViews,
|
|
7504
|
+
allFixedTextOfViews,
|
|
7505
|
+
fixedLengthOfViews,
|
|
7506
|
+
formatTemplateNameViews,
|
|
7507
|
+
mergeAdjacentFixedViews,
|
|
7508
|
+
templateMatchesValue,
|
|
7509
|
+
decideStartsWith,
|
|
7510
|
+
decideEndsWith,
|
|
7511
|
+
decideIncludes,
|
|
7512
|
+
absTemplateViews,
|
|
7513
|
+
templatePartsOf,
|
|
7514
|
+
createTemplateAbs,
|
|
7515
|
+
isTemplateLike,
|
|
7516
|
+
concatString,
|
|
7208
7517
|
add,
|
|
7209
7518
|
sub,
|
|
7210
7519
|
mul,
|
|
@@ -7283,11 +7592,13 @@ export {
|
|
|
7283
7592
|
setAbsNodeCollector,
|
|
7284
7593
|
setAbsAssignCollector,
|
|
7285
7594
|
evalSource,
|
|
7595
|
+
callFunctionFull,
|
|
7286
7596
|
callFunction,
|
|
7287
7597
|
evalMethodBody,
|
|
7288
7598
|
evalNode,
|
|
7289
7599
|
applyAbsFn,
|
|
7290
7600
|
analyzeFn,
|
|
7601
|
+
analyzeFnFull,
|
|
7291
7602
|
evalProgramAbs,
|
|
7292
7603
|
collectAbsNodeTypes,
|
|
7293
7604
|
findAbsAtPosition,
|