@nudojs/core 0.3.1 → 0.4.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.
@@ -39,6 +39,7 @@ __export(runtime_exports, {
39
39
  $neg: () => $neg,
40
40
  $not: () => $not,
41
41
  $obj: () => $obj,
42
+ $regex: () => $regex,
42
43
  $set: () => $set,
43
44
  $spread: () => $spread,
44
45
  $sub: () => $sub,
@@ -55,6 +56,8 @@ __export(runtime_exports, {
55
56
  isDefinitelyFalse: () => isDefinitelyFalse,
56
57
  isDefinitelyTrue: () => isDefinitelyTrue,
57
58
  isNudoThrow: () => isNudoThrow,
59
+ litTruth: () => litTruth,
60
+ namespaceNameOf: () => namespaceNameOf,
58
61
  withExecPhi: () => withExecPhi
59
62
  });
60
63
 
@@ -873,6 +876,9 @@ function isAnyLike(a) {
873
876
  if (a.shape.k === "unknown") return true;
874
877
  return false;
875
878
  }
879
+ function coercibleLit(v2) {
880
+ return v2 !== void 0 && (typeof v2 === "number" || typeof v2 === "string" || typeof v2 === "boolean" || v2 === null);
881
+ }
876
882
  function toNumberResult(a, b, op) {
877
883
  const term = a.term && b.term ? simplifyTerm(app(op, [a.term, b.term])) : void 0;
878
884
  return abs(
@@ -991,6 +997,9 @@ function sub(a, b, phi2 = pTrue) {
991
997
  if (typeof va === "number" && typeof vb === "number") {
992
998
  return numLit(va - vb);
993
999
  }
1000
+ if (coercibleLit(va) && coercibleLit(vb)) {
1001
+ return numLit(Number(va) - Number(vb));
1002
+ }
994
1003
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
995
1004
  const term = simplifyTerm(app("-", [a.term, b.term]));
996
1005
  const ab = numericBounds(a, phi2);
@@ -1023,6 +1032,9 @@ function mul(a, b, phi2 = pTrue) {
1023
1032
  if (typeof va === "number" && typeof vb === "number") {
1024
1033
  return numLit(va * vb);
1025
1034
  }
1035
+ if (coercibleLit(va) && coercibleLit(vb)) {
1036
+ return numLit(Number(va) * Number(vb));
1037
+ }
1026
1038
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1027
1039
  const term = simplifyTerm(app("*", [a.term, b.term]));
1028
1040
  if (b.term.op === "lit" && b.term.value === 0 || a.term.op === "lit" && a.term.value === 0) {
@@ -1089,6 +1101,9 @@ function div(a, b, phi2 = pTrue) {
1089
1101
  }
1090
1102
  return numLit(va / vb);
1091
1103
  }
1104
+ if (coercibleLit(va) && coercibleLit(vb)) {
1105
+ return numLit(Number(va) / Number(vb));
1106
+ }
1092
1107
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1093
1108
  const term = simplifyTerm(app("/", [a.term, b.term]));
1094
1109
  if (b.term.op === "lit" && typeof b.term.value === "number" && b.term.value !== 0) {
@@ -1131,6 +1146,9 @@ function mod(a, b, phi2 = pTrue) {
1131
1146
  }
1132
1147
  return numLit(va % vb);
1133
1148
  }
1149
+ if (coercibleLit(va) && coercibleLit(vb)) {
1150
+ return numLit(Number(va) % Number(vb));
1151
+ }
1134
1152
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1135
1153
  const term = simplifyTerm(app("%", [a.term, b.term]));
1136
1154
  if (b.term.op === "lit" && typeof b.term.value === "number" && b.term.value !== 0) {
@@ -1981,159 +1999,484 @@ function primOf(a) {
1981
1999
  return void 0;
1982
2000
  }
1983
2001
 
1984
- // src/algebra/exec/calls.ts
1985
- var calls_exports = {};
1986
- __export(calls_exports, {
1987
- $callNamed: () => $callNamed,
1988
- getAbsOrigin: () => getAbsOrigin,
1989
- getBCallCollector: () => getBCallCollector,
1990
- noteMemberDispatchMiss: () => noteMemberDispatchMiss,
1991
- notePrimMemberMissing: () => notePrimMemberMissing,
1992
- noteUnknownMemberMissing: () => noteUnknownMemberMissing,
1993
- recordMemberDiag: () => recordMemberDiag,
1994
- setBCallCollector: () => setBCallCollector,
1995
- setMemberDiagCollector: () => setMemberDiagCollector,
1996
- tagAbsOrigin: () => tagAbsOrigin
1997
- });
1998
-
1999
- // src/algebra/parse-source.ts
2000
- import { parse as babelParse } from "@babel/parser";
2001
-
2002
- // src/strip-types.ts
2003
- var REMOVE = Symbol("nudo.strip.remove");
2004
- var SKIP_KEYS = /* @__PURE__ */ new Set([
2005
- "loc",
2006
- "start",
2007
- "end",
2008
- "range",
2009
- "leadingComments",
2010
- "trailingComments",
2011
- "innerComments",
2012
- "comments",
2013
- "tokens",
2014
- "extra"
2015
- ]);
2016
- function transformValue(value) {
2017
- if (Array.isArray(value)) {
2018
- let changed = false;
2019
- const out = [];
2020
- for (const el of value) {
2021
- if (el === null || el === void 0) {
2022
- out.push(el);
2023
- continue;
2002
+ // src/algebra/builtins.ts
2003
+ function numPrim(conf = "path") {
2004
+ return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
2005
+ }
2006
+ function strPrim(conf = "path") {
2007
+ return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
2008
+ }
2009
+ function boolPrim(conf = "partial") {
2010
+ return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
2011
+ }
2012
+ function evalMathMethod(name, args) {
2013
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2014
+ const a1 = args[1] ? litValue(args[1]) : void 0;
2015
+ switch (name) {
2016
+ case "abs":
2017
+ if (typeof a0 === "number") return numLit(Math.abs(a0));
2018
+ return numPrim();
2019
+ case "floor":
2020
+ if (typeof a0 === "number") return numLit(Math.floor(a0));
2021
+ return numPrim();
2022
+ case "ceil":
2023
+ if (typeof a0 === "number") return numLit(Math.ceil(a0));
2024
+ return numPrim();
2025
+ case "round":
2026
+ if (typeof a0 === "number") return numLit(Math.round(a0));
2027
+ return numPrim();
2028
+ case "sqrt":
2029
+ if (typeof a0 === "number") return numLit(Math.sqrt(a0));
2030
+ return numPrim();
2031
+ case "min": {
2032
+ const lits = args.map(litValue);
2033
+ if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2034
+ return numLit(Math.min(...lits));
2024
2035
  }
2025
- const r = transformValue(el);
2026
- if (r === REMOVE) {
2027
- changed = true;
2028
- } else {
2029
- if (r !== el) changed = true;
2030
- out.push(r);
2036
+ return numPrim();
2037
+ }
2038
+ case "max": {
2039
+ const lits = args.map(litValue);
2040
+ if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2041
+ return numLit(Math.max(...lits));
2031
2042
  }
2043
+ return numPrim();
2032
2044
  }
2033
- return changed ? out : value;
2034
- }
2035
- if (typeof value !== "object" || value === null) return value;
2036
- if (typeof value.type !== "string") return value;
2037
- return transformNode(value);
2038
- }
2039
- function isTsDeclareLike(node) {
2040
- return node.declare === true;
2041
- }
2042
- function isTypeOnlyDeclaration(decl) {
2043
- switch (decl.type) {
2044
- case "TSInterfaceDeclaration":
2045
- case "TSTypeAliasDeclaration":
2046
- case "TSEnumDeclaration":
2047
- case "TSDeclareFunction":
2048
- return true;
2049
- case "VariableDeclaration":
2050
- case "ClassDeclaration":
2051
- return isTsDeclareLike(decl);
2045
+ case "pow":
2046
+ if (typeof a0 === "number" && typeof a1 === "number") return numLit(Math.pow(a0, a1));
2047
+ return numPrim();
2048
+ case "sign":
2049
+ if (typeof a0 === "number") return numLit(Math.sign(a0));
2050
+ return numPrim();
2052
2051
  default:
2053
- return false;
2052
+ return void 0;
2054
2053
  }
2055
2054
  }
2056
- function isTypeOnlyStatement(node) {
2057
- const anyNode = node;
2058
- switch (node.type) {
2059
- case "TSInterfaceDeclaration":
2060
- case "TSTypeAliasDeclaration":
2061
- case "TSEnumDeclaration":
2062
- case "TSDeclareFunction":
2063
- return true;
2064
- case "TSModuleDeclaration":
2065
- return isTsDeclareLike(node);
2066
- case "VariableDeclaration":
2067
- case "ClassDeclaration":
2068
- return isTsDeclareLike(node);
2069
- case "ImportDeclaration":
2070
- if (anyNode.importKind === "type") return true;
2071
- {
2072
- const specs = anyNode.specifiers;
2073
- if (specs && specs.length > 0 && specs.every((s) => s.importKind === "type" || s.importKind === "typeof")) {
2074
- return true;
2075
- }
2055
+ function evalObjectMethod(name, args) {
2056
+ const a0 = args[0];
2057
+ switch (name) {
2058
+ case "keys": {
2059
+ if (a0?.shape.k === "obj") {
2060
+ const keys = Object.keys(a0.shape.slots).map(
2061
+ (k) => strLit(k)
2062
+ );
2063
+ return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
2076
2064
  }
2077
- return false;
2078
- case "ExportNamedDeclaration": {
2079
- if (anyNode.exportKind === "type") return true;
2080
- const decl = node.declaration;
2081
- if (decl && isTypeOnlyDeclaration(decl)) return true;
2082
- {
2083
- const specs = anyNode.specifiers;
2084
- if (!decl && specs && specs.length > 0 && specs.every((s) => s.exportKind === "type")) return true;
2065
+ return abs({ k: "arr", element: strPrim("path") }, void 0, void 0, "partial");
2066
+ }
2067
+ case "values": {
2068
+ if (a0?.shape.k === "obj") {
2069
+ const slots = a0.shape.slots;
2070
+ const vals = Object.values(slots).map((s) => s.value);
2071
+ return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
2085
2072
  }
2086
- return false;
2073
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2074
+ }
2075
+ case "entries": {
2076
+ if (a0?.shape.k === "obj") {
2077
+ const slots = a0.shape.slots;
2078
+ const entries = Object.entries(slots).map(
2079
+ ([, s]) => abs({ k: "tuple", elements: [strPrim("exact"), s.value] }, void 0, void 0, "exact")
2080
+ );
2081
+ return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
2082
+ }
2083
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2084
+ }
2085
+ case "assign": {
2086
+ if (!args.length) return unknown;
2087
+ let acc = args[0];
2088
+ for (let i = 1; i < args.length; i++) {
2089
+ acc = { ...acc };
2090
+ if (acc.shape.k === "obj" && args[i].shape.k === "obj") {
2091
+ const base = acc.shape.slots;
2092
+ const over = args[i].shape.slots;
2093
+ acc = abs({ k: "obj", slots: { ...base, ...over } }, void 0, void 0, confJoin(acc.conf, args[i].conf));
2094
+ }
2095
+ }
2096
+ return acc;
2087
2097
  }
2088
- case "ExportAllDeclaration":
2089
- return anyNode.exportKind === "type";
2090
- case "ExportDefaultDeclaration":
2091
- return isTypeOnlyDeclaration(node.declaration);
2092
- // ---- 类成员 ----
2093
- case "TSIndexSignature":
2094
- case "TSDeclareMethod":
2095
- return true;
2096
- case "ClassProperty":
2097
- case "ClassPrivateProperty":
2098
- return isTsDeclareLike(node) || node.abstract === true;
2099
2098
  default:
2100
- return false;
2099
+ return void 0;
2101
2100
  }
2102
2101
  }
2103
- function deleteTypeSyntaxFields(node) {
2104
- const tp = node.typeParameters;
2105
- if (tp && typeof tp.type === "string" && tp.type.startsWith("TSTypeParameter")) {
2106
- delete node.typeParameters;
2107
- }
2108
- const ta = node.typeAnnotation;
2109
- if (ta && ta.type === "TSTypeAnnotation") delete node.typeAnnotation;
2110
- const rt = node.returnType;
2111
- if (rt && (rt.type === "TSTypeAnnotation" || rt.type === "TSTypePredicate")) delete node.returnType;
2112
- if (node.optional === true && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern" || node.type === "RestElement")) {
2113
- delete node.optional;
2114
- }
2115
- if ("implements" in node) delete node.implements;
2116
- if ("superTypeParameters" in node) delete node.superTypeParameters;
2102
+ function evalJsonMethod(name, args) {
2103
+ if (name === "stringify") return strPrim("partial");
2104
+ if (name === "parse") return unknown;
2105
+ return void 0;
2117
2106
  }
2118
- function unwrapExpression(node) {
2119
- switch (node.type) {
2120
- case "TSAsExpression":
2121
- // 含 as const
2122
- case "TSSatisfiesExpression":
2123
- case "TSTypeAssertion":
2124
- case "TSNonNullExpression":
2125
- case "TSInstantiationExpression":
2126
- return node.expression;
2107
+ function evalNumberStatic(name, args) {
2108
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2109
+ switch (name) {
2110
+ case "isInteger":
2111
+ if (typeof a0 === "number") return boolLit(Number.isInteger(a0));
2112
+ return boolPrim();
2113
+ case "isNaN":
2114
+ if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2115
+ return boolPrim();
2116
+ case "isFinite":
2117
+ if (typeof a0 === "number") return boolLit(Number.isFinite(a0));
2118
+ return boolPrim();
2119
+ case "parseInt":
2120
+ case "parseFloat":
2121
+ if (typeof a0 === "string" || typeof a0 === "number") {
2122
+ const n = name === "parseInt" ? parseInt(String(a0), 10) : parseFloat(String(a0));
2123
+ return numLit(n);
2124
+ }
2125
+ return numPrim();
2126
+ case "MAX_SAFE_INTEGER":
2127
+ return numLit(Number.MAX_SAFE_INTEGER);
2127
2128
  default:
2128
- return null;
2129
+ return void 0;
2129
2130
  }
2130
2131
  }
2131
- function transformNode(node) {
2132
- if (isTypeOnlyStatement(node)) return REMOVE;
2133
- deleteTypeSyntaxFields(node);
2134
- if (node.type === "ImportDeclaration") {
2135
- node.specifiers = node.specifiers.filter(
2136
- (s) => !(s.importKind === "type" || s.importKind === "typeof")
2132
+ function evalGlobalFn(name, args) {
2133
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2134
+ switch (name) {
2135
+ case "parseInt":
2136
+ if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseInt(String(a0), 10));
2137
+ return numPrim();
2138
+ case "parseFloat":
2139
+ if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
2140
+ return numPrim();
2141
+ case "isNaN":
2142
+ if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2143
+ return boolPrim();
2144
+ case "Number":
2145
+ if (typeof a0 === "number") return numLit(a0);
2146
+ if (typeof a0 === "string") return numLit(Number(a0));
2147
+ if (typeof a0 === "boolean") return numLit(a0 ? 1 : 0);
2148
+ return numPrim();
2149
+ case "String":
2150
+ if (a0 !== void 0) return strLit(String(a0));
2151
+ return strPrim();
2152
+ case "Boolean":
2153
+ if (a0 !== void 0) return boolLit(Boolean(a0));
2154
+ return boolPrim();
2155
+ default:
2156
+ return void 0;
2157
+ }
2158
+ }
2159
+ function evalArrayStatic(name, args) {
2160
+ const a0 = args[0];
2161
+ switch (name) {
2162
+ case "isArray": {
2163
+ if (!a0) return boolLit(false);
2164
+ const k = a0.shape.k;
2165
+ return boolLit(k === "arr" || k === "tuple");
2166
+ }
2167
+ case "from":
2168
+ case "of":
2169
+ return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
2170
+ default:
2171
+ return void 0;
2172
+ }
2173
+ }
2174
+ function evalDateCtor(args) {
2175
+ return abs(
2176
+ { k: "brand", name: "Date", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2177
+ void 0,
2178
+ void 0,
2179
+ "path"
2180
+ );
2181
+ }
2182
+ function evalDateStatic(name, _args) {
2183
+ if (name === "now") return numLit(Date.now());
2184
+ return void 0;
2185
+ }
2186
+ function evalDateMethod(name, _recv, _args) {
2187
+ switch (name) {
2188
+ case "getTime":
2189
+ case "valueOf":
2190
+ return numPrim("path");
2191
+ case "toISOString":
2192
+ case "toString":
2193
+ return strPrim("path");
2194
+ default:
2195
+ return void 0;
2196
+ }
2197
+ }
2198
+ function evalRegExpCtor(_args) {
2199
+ return abs(
2200
+ { k: "brand", name: "RegExp", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2201
+ void 0,
2202
+ void 0,
2203
+ "path"
2204
+ );
2205
+ }
2206
+ function evalRegExpMethod(name, _recv, _args) {
2207
+ switch (name) {
2208
+ case "test":
2209
+ return boolPrim();
2210
+ case "exec":
2211
+ return unknown;
2212
+ default:
2213
+ return void 0;
2214
+ }
2215
+ }
2216
+ function evalPromiseCtor(_args) {
2217
+ return abs(
2218
+ { k: "eff", eff: "promise", inner: unknown },
2219
+ void 0,
2220
+ void 0,
2221
+ "partial"
2222
+ );
2223
+ }
2224
+ function evalPromiseStatic(name, args) {
2225
+ switch (name) {
2226
+ case "resolve": {
2227
+ const inner = args[0] ?? unknown;
2228
+ if (inner.shape.k === "eff" && inner.shape.eff === "promise") return inner;
2229
+ return abs({ k: "eff", eff: "promise", inner }, void 0, void 0, "path");
2230
+ }
2231
+ case "reject":
2232
+ return abs({ k: "eff", eff: "promise", inner: unknown }, void 0, void 0, "partial");
2233
+ case "all": {
2234
+ const a0 = args[0];
2235
+ if (a0?.shape.k === "arr" && a0.shape.element.shape.k === "eff") {
2236
+ return abs(
2237
+ { k: "eff", eff: "promise", inner: abs({ k: "arr", element: a0.shape.element.shape.inner }, void 0, void 0, "path") },
2238
+ void 0,
2239
+ void 0,
2240
+ "path"
2241
+ );
2242
+ }
2243
+ return abs({ k: "eff", eff: "promise", inner: abs({ k: "arr", element: unknown }, void 0, void 0, "partial") }, void 0, void 0, "partial");
2244
+ }
2245
+ default:
2246
+ return void 0;
2247
+ }
2248
+ }
2249
+ function evalNamespaceCall(ns, method, args) {
2250
+ switch (ns) {
2251
+ case "Math":
2252
+ return evalMathMethod(method, args);
2253
+ case "Object":
2254
+ return evalObjectMethod(method, args);
2255
+ case "JSON":
2256
+ return evalJsonMethod(method, args);
2257
+ case "Number":
2258
+ return evalNumberStatic(method, args);
2259
+ case "Array":
2260
+ return evalArrayStatic(method, args);
2261
+ case "Date":
2262
+ return evalDateStatic(method, args);
2263
+ case "Promise":
2264
+ return evalPromiseStatic(method, args);
2265
+ default:
2266
+ return void 0;
2267
+ }
2268
+ }
2269
+ function evalBuiltinNew(className, args) {
2270
+ switch (className) {
2271
+ case "Date":
2272
+ return evalDateCtor(args);
2273
+ case "RegExp":
2274
+ return evalRegExpCtor(args);
2275
+ case "Promise":
2276
+ return evalPromiseCtor(args);
2277
+ case "Map":
2278
+ return abs(
2279
+ { k: "brand", name: "Map", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2280
+ void 0,
2281
+ void 0,
2282
+ "path"
2283
+ );
2284
+ case "Set":
2285
+ return abs(
2286
+ { k: "brand", name: "Set", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2287
+ void 0,
2288
+ void 0,
2289
+ "path"
2290
+ );
2291
+ default:
2292
+ return void 0;
2293
+ }
2294
+ }
2295
+ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
2296
+ if (brandName === "Date") return evalDateMethod(method, recv, args);
2297
+ if (brandName === "RegExp") return evalRegExpMethod(method, recv, args);
2298
+ if (brandName === "Map") {
2299
+ switch (method) {
2300
+ case "get":
2301
+ return unknown;
2302
+ case "has":
2303
+ return boolPrim();
2304
+ case "set":
2305
+ return recv;
2306
+ case "size":
2307
+ return numPrim("path");
2308
+ default:
2309
+ return void 0;
2310
+ }
2311
+ }
2312
+ if (brandName === "Set") {
2313
+ switch (method) {
2314
+ case "has":
2315
+ return boolPrim();
2316
+ case "add":
2317
+ return recv;
2318
+ case "size":
2319
+ return numPrim("path");
2320
+ default:
2321
+ return void 0;
2322
+ }
2323
+ }
2324
+ return void 0;
2325
+ }
2326
+
2327
+ // src/algebra/exec/calls.ts
2328
+ var calls_exports = {};
2329
+ __export(calls_exports, {
2330
+ $callNamed: () => $callNamed,
2331
+ getAbsOrigin: () => getAbsOrigin,
2332
+ getBCallCollector: () => getBCallCollector,
2333
+ noteMemberDispatchMiss: () => noteMemberDispatchMiss,
2334
+ notePrimMemberMissing: () => notePrimMemberMissing,
2335
+ noteUnknownMemberMissing: () => noteUnknownMemberMissing,
2336
+ recordMemberDiag: () => recordMemberDiag,
2337
+ setBCallCollector: () => setBCallCollector,
2338
+ setMemberDiagCollector: () => setMemberDiagCollector,
2339
+ tagAbsOrigin: () => tagAbsOrigin
2340
+ });
2341
+
2342
+ // src/algebra/parse-source.ts
2343
+ import { parse as babelParse } from "@babel/parser";
2344
+
2345
+ // src/strip-types.ts
2346
+ var REMOVE = Symbol("nudo.strip.remove");
2347
+ var SKIP_KEYS = /* @__PURE__ */ new Set([
2348
+ "loc",
2349
+ "start",
2350
+ "end",
2351
+ "range",
2352
+ "leadingComments",
2353
+ "trailingComments",
2354
+ "innerComments",
2355
+ "comments",
2356
+ "tokens",
2357
+ "extra"
2358
+ ]);
2359
+ function transformValue(value) {
2360
+ if (Array.isArray(value)) {
2361
+ let changed = false;
2362
+ const out = [];
2363
+ for (const el of value) {
2364
+ if (el === null || el === void 0) {
2365
+ out.push(el);
2366
+ continue;
2367
+ }
2368
+ const r = transformValue(el);
2369
+ if (r === REMOVE) {
2370
+ changed = true;
2371
+ } else {
2372
+ if (r !== el) changed = true;
2373
+ out.push(r);
2374
+ }
2375
+ }
2376
+ return changed ? out : value;
2377
+ }
2378
+ if (typeof value !== "object" || value === null) return value;
2379
+ if (typeof value.type !== "string") return value;
2380
+ return transformNode(value);
2381
+ }
2382
+ function isTsDeclareLike(node) {
2383
+ return node.declare === true;
2384
+ }
2385
+ function isTypeOnlyDeclaration(decl) {
2386
+ switch (decl.type) {
2387
+ case "TSInterfaceDeclaration":
2388
+ case "TSTypeAliasDeclaration":
2389
+ case "TSEnumDeclaration":
2390
+ case "TSDeclareFunction":
2391
+ return true;
2392
+ case "VariableDeclaration":
2393
+ case "ClassDeclaration":
2394
+ return isTsDeclareLike(decl);
2395
+ default:
2396
+ return false;
2397
+ }
2398
+ }
2399
+ function isTypeOnlyStatement(node) {
2400
+ const anyNode = node;
2401
+ switch (node.type) {
2402
+ case "TSInterfaceDeclaration":
2403
+ case "TSTypeAliasDeclaration":
2404
+ case "TSEnumDeclaration":
2405
+ case "TSDeclareFunction":
2406
+ return true;
2407
+ case "TSModuleDeclaration":
2408
+ return isTsDeclareLike(node);
2409
+ case "VariableDeclaration":
2410
+ case "ClassDeclaration":
2411
+ return isTsDeclareLike(node);
2412
+ case "ImportDeclaration":
2413
+ if (anyNode.importKind === "type") return true;
2414
+ {
2415
+ const specs = anyNode.specifiers;
2416
+ if (specs && specs.length > 0 && specs.every((s) => s.importKind === "type" || s.importKind === "typeof")) {
2417
+ return true;
2418
+ }
2419
+ }
2420
+ return false;
2421
+ case "ExportNamedDeclaration": {
2422
+ if (anyNode.exportKind === "type") return true;
2423
+ const decl = node.declaration;
2424
+ if (decl && isTypeOnlyDeclaration(decl)) return true;
2425
+ {
2426
+ const specs = anyNode.specifiers;
2427
+ if (!decl && specs && specs.length > 0 && specs.every((s) => s.exportKind === "type")) return true;
2428
+ }
2429
+ return false;
2430
+ }
2431
+ case "ExportAllDeclaration":
2432
+ return anyNode.exportKind === "type";
2433
+ case "ExportDefaultDeclaration":
2434
+ return isTypeOnlyDeclaration(node.declaration);
2435
+ // ---- 类成员 ----
2436
+ case "TSIndexSignature":
2437
+ case "TSDeclareMethod":
2438
+ return true;
2439
+ case "ClassProperty":
2440
+ case "ClassPrivateProperty":
2441
+ return isTsDeclareLike(node) || node.abstract === true;
2442
+ default:
2443
+ return false;
2444
+ }
2445
+ }
2446
+ function deleteTypeSyntaxFields(node) {
2447
+ const tp = node.typeParameters;
2448
+ if (tp && typeof tp.type === "string" && tp.type.startsWith("TSTypeParameter")) {
2449
+ delete node.typeParameters;
2450
+ }
2451
+ const ta = node.typeAnnotation;
2452
+ if (ta && ta.type === "TSTypeAnnotation") delete node.typeAnnotation;
2453
+ const rt = node.returnType;
2454
+ if (rt && (rt.type === "TSTypeAnnotation" || rt.type === "TSTypePredicate")) delete node.returnType;
2455
+ if (node.optional === true && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern" || node.type === "RestElement")) {
2456
+ delete node.optional;
2457
+ }
2458
+ if ("implements" in node) delete node.implements;
2459
+ if ("superTypeParameters" in node) delete node.superTypeParameters;
2460
+ }
2461
+ function unwrapExpression(node) {
2462
+ switch (node.type) {
2463
+ case "TSAsExpression":
2464
+ // 含 as const
2465
+ case "TSSatisfiesExpression":
2466
+ case "TSTypeAssertion":
2467
+ case "TSNonNullExpression":
2468
+ case "TSInstantiationExpression":
2469
+ return node.expression;
2470
+ default:
2471
+ return null;
2472
+ }
2473
+ }
2474
+ function transformNode(node) {
2475
+ if (isTypeOnlyStatement(node)) return REMOVE;
2476
+ deleteTypeSyntaxFields(node);
2477
+ if (node.type === "ImportDeclaration") {
2478
+ node.specifiers = node.specifiers.filter(
2479
+ (s) => !(s.importKind === "type" || s.importKind === "typeof")
2137
2480
  );
2138
2481
  } else if (node.type === "ExportNamedDeclaration") {
2139
2482
  if (node.specifiers) {
@@ -2616,483 +2959,158 @@ function substShape(s, map, cache, visiting) {
2616
2959
  case "brand":
2617
2960
  return { ...s, shape: substAbsInner(s.shape, map, cache, visiting) };
2618
2961
  case "eff":
2619
- return { ...s, inner: substAbsInner(s.inner, map, cache, visiting) };
2620
- case "arr":
2621
- return { ...s, element: substAbsInner(s.element, map, cache, visiting) };
2622
- case "tuple": {
2623
- const elements = s.elements.map(
2624
- (e) => substAbsInner(e, map, cache, visiting)
2625
- );
2626
- const next = { k: "tuple", elements };
2627
- if (s.rest) next.rest = substAbsInner(s.rest, map, cache, visiting);
2628
- return next;
2629
- }
2630
- case "fn": {
2631
- const next = { k: "fn", params: s.params };
2632
- if (s.name !== void 0) next.name = s.name;
2633
- if (s.paramTypes) {
2634
- next.paramTypes = s.paramTypes.map(
2635
- (p) => substAbsInner(p, map, cache, visiting)
2636
- );
2637
- }
2638
- if (s.returnType !== void 0) {
2639
- next.returnType = substAbsInner(s.returnType, map, cache, visiting);
2640
- }
2641
- return next;
2642
- }
2643
- case "sum":
2644
- return {
2645
- ...s,
2646
- members: s.members.map((m) => substAbsInner(m, map, cache, visiting))
2647
- };
2648
- case "obj": {
2649
- const slots = {};
2650
- for (const [k, slot] of Object.entries(s.slots)) {
2651
- const nextSlot = { value: substAbsInner(slot.value, map, cache, visiting) };
2652
- if (slot.optional) nextSlot.optional = true;
2653
- if (slot.readonly) nextSlot.readonly = true;
2654
- slots[k] = nextSlot;
2655
- }
2656
- const next = { k: "obj", slots };
2657
- if (s.index) {
2658
- next.index = {
2659
- key: substAbsInner(s.index.key, map, cache, visiting),
2660
- value: substAbsInner(s.index.value, map, cache, visiting)
2661
- };
2662
- }
2663
- if (s.open) next.open = true;
2664
- return next;
2665
- }
2666
- }
2667
- }
2668
- function substAbsInner(a, map, cache, visiting) {
2669
- if (a.term?.op === "var" && map.has(a.term.id)) {
2670
- const repl = map.get(a.term.id);
2671
- return {
2672
- shape: repl.shape,
2673
- term: repl.term,
2674
- pred: repl.pred,
2675
- conf: confJoin(a.conf, repl.conf)
2676
- };
2677
- }
2678
- const hit = cache.get(a);
2679
- if (hit !== void 0) return hit;
2680
- if (visiting.has(a)) return a;
2681
- visiting.add(a);
2682
- const shape = substShape(a.shape, map, cache, visiting);
2683
- const term = a.term ? substTermAbs(a.term, map) : void 0;
2684
- let pred = a.pred;
2685
- let conf = a.conf;
2686
- if (a.pred) {
2687
- const r = substPredAbs(a.pred, map);
2688
- pred = r.pred;
2689
- if (r.dropped) conf = confJoin(conf, "partial");
2690
- }
2691
- visiting.delete(a);
2692
- const result = abs(shape, term, pred, conf);
2693
- cache.set(a, result);
2694
- return result;
2695
- }
2696
- function substAbs(a, map) {
2697
- if (map.size === 0) return a;
2698
- return substAbsInner(a, map, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
2699
- }
2700
- function instantiateReturn(fn, args) {
2701
- const shape = fn.shape;
2702
- if (!shape || shape.k !== "fn") return unknown;
2703
- const src = getFnImpl(fn)?.relation ?? {
2704
- paramTypes: shape.paramTypes ?? [],
2705
- returnType: shape.returnType ?? unknown
2706
- };
2707
- const map = /* @__PURE__ */ new Map();
2708
- src.paramTypes.forEach((p, i) => {
2709
- if (p.term?.op !== "var") return;
2710
- const id = p.term.id;
2711
- if (map.has(id)) return;
2712
- map.set(id, args[i] ?? unknown);
2713
- });
2714
- return substAbs(src.returnType, map);
2715
- }
2716
- var applyCallbackHost;
2717
- function setApplyCallbackHost(fn) {
2718
- applyCallbackHost = fn;
2719
- }
2720
- function applyCallbackAbs(cb, args, env, phi2, budget) {
2721
- if (!applyCallbackHost) {
2722
- if (cb && typeof cb === "object" && "shape" in cb) {
2723
- const a = cb;
2724
- const impl = getFnImpl(a);
2725
- if (impl?.relation) return instantiateReturn(a, args);
2726
- if (isRelFn(a)) return instantiateReturn(a, args);
2727
- }
2728
- return unknown;
2729
- }
2730
- return applyCallbackHost(cb, args, env, phi2, budget);
2731
- }
2732
- function undefAbs() {
2733
- return abs(
2734
- { k: "unknown" },
2735
- { op: "lit", value: void 0 },
2736
- pTrue,
2737
- "exact"
2738
- );
2739
- }
2740
- function mapElementFallback(cbAbs, elem, out) {
2741
- if (out.shape.k !== "unknown" || elem.term?.op !== "var") return out;
2742
- const slot = cbAbs?.shape.k === "fn" ? cbAbs.shape.returnType : void 0;
2743
- return slot ?? out;
2744
- }
2745
- function projectFlatMapResult(arrConf, mapped) {
2746
- const flatEls = [];
2747
- let anyUnknown = false;
2748
- for (const m of mapped) {
2749
- if (m.shape.k === "arr") flatEls.push(m.shape.element);
2750
- else if (m.shape.k === "tuple") flatEls.push(...m.shape.elements);
2751
- else anyUnknown = true;
2752
- }
2753
- if (anyUnknown || flatEls.length === 0) return unknown;
2754
- const first = flatEls[0];
2755
- const sameIdentity = flatEls.every((e) => {
2756
- if (e.shape.k !== first.shape.k) return false;
2757
- if (!e.term && !first.term) return true;
2758
- if (!e.term || !first.term) return false;
2759
- return termToString(e.term) === termToString(first.term);
2760
- });
2761
- const el = sameIdentity ? first : flatEls.reduce((a, b) => joinAbs(a, b));
2762
- return abs(
2763
- { k: "arr", element: el },
2764
- void 0,
2765
- void 0,
2766
- confJoin(arrConf, "path")
2767
- );
2768
- }
2769
- function asAbs(v2) {
2770
- if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
2771
- return void 0;
2772
- }
2773
-
2774
- // src/algebra/builtins.ts
2775
- function numPrim(conf = "path") {
2776
- return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
2777
- }
2778
- function strPrim(conf = "path") {
2779
- return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
2780
- }
2781
- function boolPrim(conf = "partial") {
2782
- return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
2783
- }
2784
- function evalMathMethod(name, args) {
2785
- const a0 = args[0] ? litValue(args[0]) : void 0;
2786
- const a1 = args[1] ? litValue(args[1]) : void 0;
2787
- switch (name) {
2788
- case "abs":
2789
- if (typeof a0 === "number") return numLit(Math.abs(a0));
2790
- return numPrim();
2791
- case "floor":
2792
- if (typeof a0 === "number") return numLit(Math.floor(a0));
2793
- return numPrim();
2794
- case "ceil":
2795
- if (typeof a0 === "number") return numLit(Math.ceil(a0));
2796
- return numPrim();
2797
- case "round":
2798
- if (typeof a0 === "number") return numLit(Math.round(a0));
2799
- return numPrim();
2800
- case "sqrt":
2801
- if (typeof a0 === "number") return numLit(Math.sqrt(a0));
2802
- return numPrim();
2803
- case "min": {
2804
- const lits = args.map(litValue);
2805
- if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2806
- return numLit(Math.min(...lits));
2807
- }
2808
- return numPrim();
2809
- }
2810
- case "max": {
2811
- const lits = args.map(litValue);
2812
- if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2813
- return numLit(Math.max(...lits));
2814
- }
2815
- return numPrim();
2816
- }
2817
- case "pow":
2818
- if (typeof a0 === "number" && typeof a1 === "number") return numLit(Math.pow(a0, a1));
2819
- return numPrim();
2820
- case "sign":
2821
- if (typeof a0 === "number") return numLit(Math.sign(a0));
2822
- return numPrim();
2823
- default:
2824
- return void 0;
2825
- }
2826
- }
2827
- function evalObjectMethod(name, args) {
2828
- const a0 = args[0];
2829
- switch (name) {
2830
- case "keys": {
2831
- if (a0?.shape.k === "obj") {
2832
- const keys = Object.keys(a0.shape.slots).map(
2833
- (k) => strLit(k)
2962
+ return { ...s, inner: substAbsInner(s.inner, map, cache, visiting) };
2963
+ case "arr":
2964
+ return { ...s, element: substAbsInner(s.element, map, cache, visiting) };
2965
+ case "tuple": {
2966
+ const elements = s.elements.map(
2967
+ (e) => substAbsInner(e, map, cache, visiting)
2968
+ );
2969
+ const next = { k: "tuple", elements };
2970
+ if (s.rest) next.rest = substAbsInner(s.rest, map, cache, visiting);
2971
+ return next;
2972
+ }
2973
+ case "fn": {
2974
+ const next = { k: "fn", params: s.params };
2975
+ if (s.name !== void 0) next.name = s.name;
2976
+ if (s.paramTypes) {
2977
+ next.paramTypes = s.paramTypes.map(
2978
+ (p) => substAbsInner(p, map, cache, visiting)
2834
2979
  );
2835
- return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
2836
2980
  }
2837
- return abs({ k: "arr", element: strPrim("path") }, void 0, void 0, "partial");
2838
- }
2839
- case "values": {
2840
- if (a0?.shape.k === "obj") {
2841
- const slots = a0.shape.slots;
2842
- const vals = Object.values(slots).map((s) => s.value);
2843
- return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
2981
+ if (s.returnType !== void 0) {
2982
+ next.returnType = substAbsInner(s.returnType, map, cache, visiting);
2844
2983
  }
2845
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2984
+ return next;
2846
2985
  }
2847
- case "entries": {
2848
- if (a0?.shape.k === "obj") {
2849
- const slots = a0.shape.slots;
2850
- const entries = Object.entries(slots).map(
2851
- ([, s]) => abs({ k: "tuple", elements: [strPrim("exact"), s.value] }, void 0, void 0, "exact")
2852
- );
2853
- return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
2986
+ case "sum":
2987
+ return {
2988
+ ...s,
2989
+ members: s.members.map((m) => substAbsInner(m, map, cache, visiting))
2990
+ };
2991
+ case "obj": {
2992
+ const slots = {};
2993
+ for (const [k, slot] of Object.entries(s.slots)) {
2994
+ const nextSlot = { value: substAbsInner(slot.value, map, cache, visiting) };
2995
+ if (slot.optional) nextSlot.optional = true;
2996
+ if (slot.readonly) nextSlot.readonly = true;
2997
+ slots[k] = nextSlot;
2854
2998
  }
2855
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2856
- }
2857
- case "assign": {
2858
- if (!args.length) return unknown;
2859
- let acc = args[0];
2860
- for (let i = 1; i < args.length; i++) {
2861
- acc = { ...acc };
2862
- if (acc.shape.k === "obj" && args[i].shape.k === "obj") {
2863
- const base = acc.shape.slots;
2864
- const over = args[i].shape.slots;
2865
- acc = abs({ k: "obj", slots: { ...base, ...over } }, void 0, void 0, confJoin(acc.conf, args[i].conf));
2866
- }
2999
+ const next = { k: "obj", slots };
3000
+ if (s.index) {
3001
+ next.index = {
3002
+ key: substAbsInner(s.index.key, map, cache, visiting),
3003
+ value: substAbsInner(s.index.value, map, cache, visiting)
3004
+ };
2867
3005
  }
2868
- return acc;
3006
+ if (s.open) next.open = true;
3007
+ return next;
2869
3008
  }
2870
- default:
2871
- return void 0;
2872
- }
2873
- }
2874
- function evalJsonMethod(name, args) {
2875
- if (name === "stringify") return strPrim("partial");
2876
- if (name === "parse") return unknown;
2877
- return void 0;
2878
- }
2879
- function evalNumberStatic(name, args) {
2880
- const a0 = args[0] ? litValue(args[0]) : void 0;
2881
- switch (name) {
2882
- case "isInteger":
2883
- if (typeof a0 === "number") return boolLit(Number.isInteger(a0));
2884
- return boolPrim();
2885
- case "isNaN":
2886
- if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2887
- return boolPrim();
2888
- case "isFinite":
2889
- if (typeof a0 === "number") return boolLit(Number.isFinite(a0));
2890
- return boolPrim();
2891
- case "parseInt":
2892
- case "parseFloat":
2893
- if (typeof a0 === "string" || typeof a0 === "number") {
2894
- const n = name === "parseInt" ? parseInt(String(a0), 10) : parseFloat(String(a0));
2895
- return numLit(n);
2896
- }
2897
- return numPrim();
2898
- case "MAX_SAFE_INTEGER":
2899
- return numLit(Number.MAX_SAFE_INTEGER);
2900
- default:
2901
- return void 0;
2902
- }
2903
- }
2904
- function evalGlobalFn(name, args) {
2905
- const a0 = args[0] ? litValue(args[0]) : void 0;
2906
- switch (name) {
2907
- case "parseInt":
2908
- if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseInt(String(a0), 10));
2909
- return numPrim();
2910
- case "parseFloat":
2911
- if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
2912
- return numPrim();
2913
- case "isNaN":
2914
- if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2915
- return boolPrim();
2916
- case "Number":
2917
- if (typeof a0 === "number") return numLit(a0);
2918
- if (typeof a0 === "string") return numLit(Number(a0));
2919
- if (typeof a0 === "boolean") return numLit(a0 ? 1 : 0);
2920
- return numPrim();
2921
- case "String":
2922
- if (a0 !== void 0) return strLit(String(a0));
2923
- return strPrim();
2924
- case "Boolean":
2925
- if (a0 !== void 0) return boolLit(Boolean(a0));
2926
- return boolPrim();
2927
- default:
2928
- return void 0;
2929
3009
  }
2930
3010
  }
2931
- function evalArrayStatic(name, args) {
2932
- const a0 = args[0];
2933
- switch (name) {
2934
- case "isArray": {
2935
- if (!a0) return boolLit(false);
2936
- const k = a0.shape.k;
2937
- return boolLit(k === "arr" || k === "tuple");
2938
- }
2939
- case "from":
2940
- case "of":
2941
- return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
2942
- default:
2943
- return void 0;
3011
+ function substAbsInner(a, map, cache, visiting) {
3012
+ if (a.term?.op === "var" && map.has(a.term.id)) {
3013
+ const repl = map.get(a.term.id);
3014
+ return {
3015
+ shape: repl.shape,
3016
+ term: repl.term,
3017
+ pred: repl.pred,
3018
+ conf: confJoin(a.conf, repl.conf)
3019
+ };
2944
3020
  }
2945
- }
2946
- function evalDateCtor(args) {
2947
- return abs(
2948
- { k: "brand", name: "Date", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2949
- void 0,
2950
- void 0,
2951
- "path"
2952
- );
2953
- }
2954
- function evalDateStatic(name, _args) {
2955
- if (name === "now") return numLit(Date.now());
2956
- return void 0;
2957
- }
2958
- function evalDateMethod(name, _recv, _args) {
2959
- switch (name) {
2960
- case "getTime":
2961
- case "valueOf":
2962
- return numPrim("path");
2963
- case "toISOString":
2964
- case "toString":
2965
- return strPrim("path");
2966
- default:
2967
- return void 0;
3021
+ const hit = cache.get(a);
3022
+ if (hit !== void 0) return hit;
3023
+ if (visiting.has(a)) return a;
3024
+ visiting.add(a);
3025
+ const shape = substShape(a.shape, map, cache, visiting);
3026
+ const term = a.term ? substTermAbs(a.term, map) : void 0;
3027
+ let pred = a.pred;
3028
+ let conf = a.conf;
3029
+ if (a.pred) {
3030
+ const r = substPredAbs(a.pred, map);
3031
+ pred = r.pred;
3032
+ if (r.dropped) conf = confJoin(conf, "partial");
2968
3033
  }
3034
+ visiting.delete(a);
3035
+ const result = abs(shape, term, pred, conf);
3036
+ cache.set(a, result);
3037
+ return result;
2969
3038
  }
2970
- function evalRegExpCtor(_args) {
2971
- return abs(
2972
- { k: "brand", name: "RegExp", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2973
- void 0,
2974
- void 0,
2975
- "path"
2976
- );
3039
+ function substAbs(a, map) {
3040
+ if (map.size === 0) return a;
3041
+ return substAbsInner(a, map, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
2977
3042
  }
2978
- function evalRegExpMethod(name, _recv, _args) {
2979
- switch (name) {
2980
- case "test":
2981
- return boolPrim();
2982
- case "exec":
2983
- return unknown;
2984
- default:
2985
- return void 0;
2986
- }
3043
+ function instantiateReturn(fn, args) {
3044
+ const shape = fn.shape;
3045
+ if (!shape || shape.k !== "fn") return unknown;
3046
+ const src = getFnImpl(fn)?.relation ?? {
3047
+ paramTypes: shape.paramTypes ?? [],
3048
+ returnType: shape.returnType ?? unknown
3049
+ };
3050
+ const map = /* @__PURE__ */ new Map();
3051
+ src.paramTypes.forEach((p, i) => {
3052
+ if (p.term?.op !== "var") return;
3053
+ const id = p.term.id;
3054
+ if (map.has(id)) return;
3055
+ map.set(id, args[i] ?? unknown);
3056
+ });
3057
+ return substAbs(src.returnType, map);
2987
3058
  }
2988
- function evalPromiseCtor(_args) {
2989
- return abs(
2990
- { k: "eff", eff: "promise", inner: unknown },
2991
- void 0,
2992
- void 0,
2993
- "partial"
2994
- );
3059
+ var applyCallbackHost;
3060
+ function setApplyCallbackHost(fn) {
3061
+ applyCallbackHost = fn;
2995
3062
  }
2996
- function evalPromiseStatic(name, args) {
2997
- switch (name) {
2998
- case "resolve": {
2999
- const inner = args[0] ?? unknown;
3000
- if (inner.shape.k === "eff" && inner.shape.eff === "promise") return inner;
3001
- return abs({ k: "eff", eff: "promise", inner }, void 0, void 0, "path");
3002
- }
3003
- case "reject":
3004
- return abs({ k: "eff", eff: "promise", inner: unknown }, void 0, void 0, "partial");
3005
- case "all": {
3006
- const a0 = args[0];
3007
- if (a0?.shape.k === "arr" && a0.shape.element.shape.k === "eff") {
3008
- return abs(
3009
- { k: "eff", eff: "promise", inner: abs({ k: "arr", element: a0.shape.element.shape.inner }, void 0, void 0, "path") },
3010
- void 0,
3011
- void 0,
3012
- "path"
3013
- );
3014
- }
3015
- return abs({ k: "eff", eff: "promise", inner: abs({ k: "arr", element: unknown }, void 0, void 0, "partial") }, void 0, void 0, "partial");
3063
+ function applyCallbackAbs(cb, args, env, phi2, budget) {
3064
+ if (!applyCallbackHost) {
3065
+ if (cb && typeof cb === "object" && "shape" in cb) {
3066
+ const a = cb;
3067
+ const impl = getFnImpl(a);
3068
+ if (impl?.relation) return instantiateReturn(a, args);
3069
+ if (isRelFn(a)) return instantiateReturn(a, args);
3016
3070
  }
3017
- default:
3018
- return void 0;
3071
+ return unknown;
3019
3072
  }
3073
+ return applyCallbackHost(cb, args, env, phi2, budget);
3020
3074
  }
3021
- function evalNamespaceCall(ns, method, args) {
3022
- switch (ns) {
3023
- case "Math":
3024
- return evalMathMethod(method, args);
3025
- case "Object":
3026
- return evalObjectMethod(method, args);
3027
- case "JSON":
3028
- return evalJsonMethod(method, args);
3029
- case "Number":
3030
- return evalNumberStatic(method, args);
3031
- case "Array":
3032
- return evalArrayStatic(method, args);
3033
- case "Date":
3034
- return evalDateStatic(method, args);
3035
- case "Promise":
3036
- return evalPromiseStatic(method, args);
3037
- default:
3038
- return void 0;
3039
- }
3075
+ function undefAbs() {
3076
+ return abs(
3077
+ { k: "unknown" },
3078
+ { op: "lit", value: void 0 },
3079
+ pTrue,
3080
+ "exact"
3081
+ );
3040
3082
  }
3041
- function evalBuiltinNew(className, args) {
3042
- switch (className) {
3043
- case "Date":
3044
- return evalDateCtor(args);
3045
- case "RegExp":
3046
- return evalRegExpCtor(args);
3047
- case "Promise":
3048
- return evalPromiseCtor(args);
3049
- case "Map":
3050
- return abs(
3051
- { k: "brand", name: "Map", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
3052
- void 0,
3053
- void 0,
3054
- "path"
3055
- );
3056
- case "Set":
3057
- return abs(
3058
- { k: "brand", name: "Set", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
3059
- void 0,
3060
- void 0,
3061
- "path"
3062
- );
3063
- default:
3064
- return void 0;
3065
- }
3083
+ function mapElementFallback(cbAbs, elem, out) {
3084
+ if (out.shape.k !== "unknown" || elem.term?.op !== "var") return out;
3085
+ const slot = cbAbs?.shape.k === "fn" ? cbAbs.shape.returnType : void 0;
3086
+ return slot ?? out;
3066
3087
  }
3067
- function evalBuiltinInstanceMethod(brandName, method, recv, args) {
3068
- if (brandName === "Date") return evalDateMethod(method, recv, args);
3069
- if (brandName === "RegExp") return evalRegExpMethod(method, recv, args);
3070
- if (brandName === "Map") {
3071
- switch (method) {
3072
- case "get":
3073
- return unknown;
3074
- case "has":
3075
- return boolPrim();
3076
- case "set":
3077
- return recv;
3078
- case "size":
3079
- return numPrim("path");
3080
- default:
3081
- return void 0;
3082
- }
3083
- }
3084
- if (brandName === "Set") {
3085
- switch (method) {
3086
- case "has":
3087
- return boolPrim();
3088
- case "add":
3089
- return recv;
3090
- case "size":
3091
- return numPrim("path");
3092
- default:
3093
- return void 0;
3094
- }
3088
+ function projectFlatMapResult(arrConf, mapped) {
3089
+ const flatEls = [];
3090
+ let anyUnknown = false;
3091
+ for (const m of mapped) {
3092
+ if (m.shape.k === "arr") flatEls.push(m.shape.element);
3093
+ else if (m.shape.k === "tuple") flatEls.push(...m.shape.elements);
3094
+ else anyUnknown = true;
3095
3095
  }
3096
+ if (anyUnknown || flatEls.length === 0) return unknown;
3097
+ const first = flatEls[0];
3098
+ const sameIdentity = flatEls.every((e) => {
3099
+ if (e.shape.k !== first.shape.k) return false;
3100
+ if (!e.term && !first.term) return true;
3101
+ if (!e.term || !first.term) return false;
3102
+ return termToString(e.term) === termToString(first.term);
3103
+ });
3104
+ const el = sameIdentity ? first : flatEls.reduce((a, b) => joinAbs(a, b));
3105
+ return abs(
3106
+ { k: "arr", element: el },
3107
+ void 0,
3108
+ void 0,
3109
+ confJoin(arrConf, "path")
3110
+ );
3111
+ }
3112
+ function asAbs(v2) {
3113
+ if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
3096
3114
  return void 0;
3097
3115
  }
3098
3116
 
@@ -4661,6 +4679,7 @@ function evalVarDecl(node, env, phi2, budget) {
4661
4679
  for (const d of node.declarations) {
4662
4680
  if (d.id.type !== "Identifier" || !d.init) continue;
4663
4681
  const r = evalNode(d.init, local, phi2, budget);
4682
+ recordAbsNode(d.id, r.value);
4664
4683
  local = withVar(local, d.id.name, r.value);
4665
4684
  }
4666
4685
  return { value: unknown, phi: phi2, env: local };
@@ -4814,6 +4833,15 @@ function $call(fn, args) {
4814
4833
 
4815
4834
  // src/algebra/exec/calls.ts
4816
4835
  var bCallCollector = null;
4836
+ var GLOBAL_FNS = /* @__PURE__ */ new Set([
4837
+ "parseInt",
4838
+ "parseFloat",
4839
+ "isNaN",
4840
+ "isFinite",
4841
+ "Number",
4842
+ "String",
4843
+ "Boolean"
4844
+ ]);
4817
4845
  function setBCallCollector(collector) {
4818
4846
  bCallCollector = collector;
4819
4847
  }
@@ -4832,7 +4860,8 @@ function $callNamed(name, fn, args, loc, argLocs) {
4832
4860
  if (loc) pushCallLoc({ line: loc[0], column: loc[1] });
4833
4861
  try {
4834
4862
  if (typeof fn === "function") {
4835
- result = fn(...args);
4863
+ const g = GLOBAL_FNS.has(name) && fn === globalThis[name] ? evalGlobalFn(name, args) : void 0;
4864
+ result = g ?? fn(...args);
4836
4865
  } else if (fn && typeof fn === "object" && "shape" in fn) {
4837
4866
  result = $call(fn, args);
4838
4867
  }
@@ -4955,12 +4984,32 @@ function litAbsFromJs(v2) {
4955
4984
  }
4956
4985
  return unknown;
4957
4986
  }
4987
+ function litTruth(a) {
4988
+ if (a.term?.op === "lit") {
4989
+ return Boolean(a.term.value);
4990
+ }
4991
+ switch (a.shape.k) {
4992
+ case "obj":
4993
+ case "arr":
4994
+ case "tuple":
4995
+ case "fn":
4996
+ case "brand":
4997
+ case "eff":
4998
+ return true;
4999
+ case "prim":
5000
+ return a.shape.type === "symbol" || a.shape.type === "bigint" ? true : void 0;
5001
+ case "never":
5002
+ return false;
5003
+ default:
5004
+ return void 0;
5005
+ }
5006
+ }
4958
5007
  function isDefinitelyTrue(a) {
4959
- return litValue(a) === true;
5008
+ return litTruth(a) === true;
4960
5009
  }
4961
5010
  function isDefinitelyFalse(a) {
4962
- const lv = litValue(a);
4963
- if (lv === false) return true;
5011
+ const t = litTruth(a);
5012
+ if (t === false) return true;
4964
5013
  if (a.shape.k === "never") return true;
4965
5014
  return false;
4966
5015
  }
@@ -5031,17 +5080,31 @@ function $idx(a, i) {
5031
5080
  if (a.shape.k === "sum") {
5032
5081
  return a.shape.members.map((m) => $idx(m, i)).reduce((x, y) => joinAbs(x, y));
5033
5082
  }
5083
+ const sv = litValue(a);
5084
+ if (typeof sv === "string") {
5085
+ if (typeof iv === "number" && Number.isInteger(iv)) {
5086
+ if (iv >= 0 && iv < sv.length) {
5087
+ return abs(
5088
+ { k: "prim", type: "string" },
5089
+ { op: "lit", value: sv[iv] },
5090
+ pTrue,
5091
+ "exact"
5092
+ );
5093
+ }
5094
+ return undef();
5095
+ }
5096
+ return unknown;
5097
+ }
5034
5098
  return unknown;
5035
5099
  }
5036
5100
  function $idxSet(a, i, value) {
5037
5101
  const iv = litValue(i);
5038
- if (a.shape.k === "tuple" && typeof iv === "number" && Number.isInteger(iv)) {
5102
+ if (a.shape.k === "tuple" && typeof iv === "number" && Number.isInteger(iv) && iv >= 0) {
5039
5103
  const els = [...a.shape.elements];
5040
- if (iv >= 0 && iv < els.length) {
5041
- els[iv] = asAbsVal(value);
5042
- const next = abs({ k: "tuple", elements: els }, void 0, void 0, a.conf);
5043
- return next;
5044
- }
5104
+ while (els.length < iv) els.push(undef());
5105
+ els[iv] = asAbsVal(value);
5106
+ const next = abs({ k: "tuple", elements: els }, void 0, void 0, a.conf);
5107
+ return next;
5045
5108
  }
5046
5109
  return a;
5047
5110
  }
@@ -5057,6 +5120,15 @@ function $len(a) {
5057
5120
  if (a.shape.k === "arr") {
5058
5121
  return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
5059
5122
  }
5123
+ const sv = litValue(a);
5124
+ if (typeof sv === "string") {
5125
+ return abs(
5126
+ { k: "prim", type: "number" },
5127
+ { op: "lit", value: sv.length },
5128
+ pTrue,
5129
+ "exact"
5130
+ );
5131
+ }
5060
5132
  return unknown;
5061
5133
  }
5062
5134
  function $obj(slots) {
@@ -5116,7 +5188,52 @@ function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
5116
5188
  ));
5117
5189
  }
5118
5190
  }
5191
+ function namespaceNameOf(v2) {
5192
+ if (typeof v2 !== "object" && typeof v2 !== "function") return void 0;
5193
+ if (v2 === Math) return "Math";
5194
+ if (v2 === Number) return "Number";
5195
+ if (v2 === JSON) return "JSON";
5196
+ if (v2 === Object) return "Object";
5197
+ if (v2 === Array) return "Array";
5198
+ if (v2 === Date) return "Date";
5199
+ if (v2 === Promise) return "Promise";
5200
+ return void 0;
5201
+ }
5202
+ function $regex(pattern, flags = "") {
5203
+ const litStr = (v2) => abs({ k: "prim", type: "string" }, { op: "lit", value: v2 }, pTrue, "exact");
5204
+ return abs(
5205
+ {
5206
+ k: "brand",
5207
+ name: "RegExp",
5208
+ shape: objOf({
5209
+ source: { value: litStr(pattern) },
5210
+ flags: { value: litStr(flags) }
5211
+ })
5212
+ },
5213
+ void 0,
5214
+ void 0,
5215
+ "exact"
5216
+ );
5217
+ }
5119
5218
  function $get(o, key, opts) {
5219
+ if (!o || typeof o !== "object" || !("shape" in o)) {
5220
+ const ns = namespaceNameOf(o);
5221
+ if (ns) {
5222
+ try {
5223
+ const raw = o[key];
5224
+ if (typeof raw === "function") {
5225
+ return absFunction([`${ns}.${key}`], {
5226
+ body: noBody,
5227
+ apply: (args) => evalNamespaceCall(ns, key, args) ?? unknown
5228
+ });
5229
+ }
5230
+ return $lit(raw);
5231
+ } catch {
5232
+ return unknown;
5233
+ }
5234
+ }
5235
+ return unknown;
5236
+ }
5120
5237
  if (o.shape.k === "brand") return $get(o.shape.shape, key, opts);
5121
5238
  if (isObj(o)) {
5122
5239
  const slot = o.shape.slots[key];
@@ -5302,6 +5419,77 @@ var BIN_OPS = {
5302
5419
  "===": "$eq",
5303
5420
  "!==": "$ne"
5304
5421
  };
5422
+ var COMPOUND_OPS = {
5423
+ "+=": "$add",
5424
+ "-=": "$sub",
5425
+ "*=": "$mul",
5426
+ "/=": "$div",
5427
+ "%=": "$mod"
5428
+ };
5429
+ function memberPathOf(m, opts) {
5430
+ const layers = [];
5431
+ let cur = m;
5432
+ let rootSrc = null;
5433
+ while (cur.type === "MemberExpression") {
5434
+ const mm = cur;
5435
+ const k = mm.property;
5436
+ if (mm.computed) {
5437
+ if (k.type === "NumericLiteral") {
5438
+ const key = `$lit(${k.value})`;
5439
+ layers.unshift({
5440
+ get: (b) => `$idx(${b}, ${key})`,
5441
+ set: (b, v2) => `$idxSet(${b}, ${key}, ${v2})`
5442
+ });
5443
+ } else if (k.type === "StringLiteral") {
5444
+ const key = JSON.stringify(k.value);
5445
+ layers.unshift({
5446
+ get: (b) => `$get(${b}, ${key})`,
5447
+ set: (b, v2) => `$set(${b}, ${key}, ${v2})`
5448
+ });
5449
+ } else if (isExpression(k)) {
5450
+ const key = transpileExpression(k, opts);
5451
+ layers.unshift({
5452
+ get: (b) => `$idx(${b}, ${key})`,
5453
+ set: (b, v2) => `$idxSet(${b}, ${key}, ${v2})`
5454
+ });
5455
+ } else {
5456
+ return null;
5457
+ }
5458
+ } else if (k.type === "Identifier") {
5459
+ const key = JSON.stringify(k.name);
5460
+ layers.unshift({
5461
+ get: (b) => `$get(${b}, ${key})`,
5462
+ set: (b, v2) => `$set(${b}, ${key}, ${v2})`
5463
+ });
5464
+ } else {
5465
+ return null;
5466
+ }
5467
+ cur = mm.object;
5468
+ }
5469
+ if (cur.type === "Identifier") {
5470
+ rootSrc = cur.name;
5471
+ } else if (cur.type === "ThisExpression" && opts.thisParam) {
5472
+ rootSrc = opts.thisParam;
5473
+ } else {
5474
+ return null;
5475
+ }
5476
+ return { rootSrc, layers };
5477
+ }
5478
+ function readPathSrc(p) {
5479
+ return p.layers.reduce((acc, l) => l.get(acc), p.rootSrc);
5480
+ }
5481
+ function setPathSrc(p, valSrc) {
5482
+ let acc = valSrc;
5483
+ for (let i = p.layers.length - 1; i >= 0; i--) {
5484
+ const l = p.layers[i];
5485
+ const base = i === 0 ? p.rootSrc : readPrefix(p, i - 1);
5486
+ acc = l.set(base, acc);
5487
+ }
5488
+ return acc;
5489
+ }
5490
+ function readPrefix(p, j) {
5491
+ return p.layers.slice(0, j + 1).reduce((acc, l) => l.get(acc), p.rootSrc);
5492
+ }
5305
5493
  function transpileSource(source, opts = {}) {
5306
5494
  const file = parseSource(source);
5307
5495
  return transpileFile(file, { ...opts, source: opts.source ?? source });
@@ -5310,7 +5498,7 @@ function transpileFile(file, opts = {}) {
5310
5498
  const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
5311
5499
  const lines = [
5312
5500
  `// nudo B-path transpile \u2014 values are Abs; operators are overloaded calls`,
5313
- `import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $idx, $idxSet, $len, $call, $throw, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal } from ${JSON.stringify(runtime)};`,
5501
+ `import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $idx, $idxSet, $len, $call, $throw, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex } from ${JSON.stringify(runtime)};`,
5314
5502
  ``
5315
5503
  ];
5316
5504
  for (const stmt of file.program.body) {
@@ -5329,34 +5517,24 @@ function stmtReturns(stmt) {
5329
5517
  }
5330
5518
  return false;
5331
5519
  }
5332
- function stmtAlwaysExits(stmt) {
5333
- return stmtReturns(stmt) && stmt.type !== "ExpressionStatement";
5334
- }
5335
- function foldEarlyReturns(stmts) {
5336
- for (let i = stmts.length - 2; i >= 0; i--) {
5520
+ function transpileFnBodyStmts(stmts, depth, opts) {
5521
+ for (let i = 0; i < stmts.length; i++) {
5337
5522
  const stmt = stmts[i];
5338
5523
  if (stmt.type !== "IfStatement" || stmt.alternate != null) continue;
5339
5524
  if (!stmtReturns(stmt.consequent)) continue;
5340
- const tail = stmts.slice(i + 1);
5341
- if (tail.length === 0 || !tail.every(stmtAlwaysExits)) continue;
5342
- const alt = {
5343
- type: "BlockStatement",
5344
- body: tail,
5345
- directives: [],
5346
- start: stmt.consequent.start,
5347
- end: stmt.consequent.end,
5348
- loc: stmt.consequent.loc
5349
- };
5350
- const rewritten = {
5351
- ...stmt,
5352
- alternate: alt
5353
- };
5354
- return foldEarlyReturns([...stmts.slice(0, i), rewritten]);
5355
- }
5356
- return stmts;
5357
- }
5358
- function transpileFnBodyStmts(stmts, depth, opts) {
5359
- return foldEarlyReturns(stmts).map((s) => transpileStatement(s, depth, opts)).join("\n");
5525
+ const rest = stmts.slice(i + 1);
5526
+ if (rest.length === 0) continue;
5527
+ const head = stmts.slice(0, i).map((s) => transpileStatement(s, depth, opts)).join("\n");
5528
+ const test = transpileExpression(stmt.test, opts);
5529
+ const cons = transpileBlockAsThunk(stmt.consequent, depth, opts);
5530
+ const altBody = transpileFnBodyStmts(rest, depth + 1, opts);
5531
+ const promoted = `${indent(depth)}return $fork(${test}, ${cons}, () => {
5532
+ ${altBody}
5533
+ ${indent(depth)}});`;
5534
+ return head ? `${head}
5535
+ ${promoted}` : promoted;
5536
+ }
5537
+ return stmts.map((s) => transpileStatement(s, depth, opts)).join("\n");
5360
5538
  }
5361
5539
  function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
5362
5540
  if (pattern.type === "Identifier") {
@@ -5422,13 +5600,55 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
5422
5600
  });
5423
5601
  }
5424
5602
  }
5603
+ function emitParamBinding(params, pad, opts) {
5604
+ const sig = [];
5605
+ const prologue = [];
5606
+ let rest;
5607
+ params.forEach((p, i) => {
5608
+ if (p.type === "Identifier") {
5609
+ sig.push(p.name);
5610
+ return;
5611
+ }
5612
+ if (p.type === "RestElement") {
5613
+ if (p.argument.type === "Identifier") {
5614
+ rest = p.argument.name;
5615
+ return;
5616
+ }
5617
+ const ph2 = `_rest${i}`;
5618
+ rest = ph2;
5619
+ emitDestructure(p.argument, ph2, "const", pad, opts, prologue, { n: 0 });
5620
+ return;
5621
+ }
5622
+ const ph = `_p${i}`;
5623
+ sig.push(ph);
5624
+ if (p.type === "AssignmentPattern") {
5625
+ const def = transpileExpression(p.right, opts);
5626
+ if (p.left.type === "Identifier") {
5627
+ prologue.push(`${pad}const ${p.left.name} = $orDefault(${ph}, () => ${def});`);
5628
+ } else {
5629
+ const t = `_pd${i}`;
5630
+ prologue.push(`${pad}const ${t} = $orDefault(${ph}, () => ${def});`);
5631
+ emitDestructure(p.left, t, "const", pad, opts, prologue, { n: 0 });
5632
+ }
5633
+ return;
5634
+ }
5635
+ if (p.type === "ObjectPattern" || p.type === "ArrayPattern") {
5636
+ emitDestructure(p, ph, "const", pad, opts, prologue, { n: 0 });
5637
+ }
5638
+ });
5639
+ return { sig, rest, prologue };
5640
+ }
5425
5641
  function transpileStatement(stmt, depth, opts) {
5426
5642
  const pad = indent(depth);
5427
5643
  switch (stmt.type) {
5428
5644
  case "ExportNamedDeclaration": {
5429
5645
  const decl = stmt.declaration;
5430
5646
  if (!decl) return `${pad}/* export specifiers skipped */`;
5431
- return transpileStatement(decl, depth, opts);
5647
+ const inner = transpileStatement(decl, depth, opts);
5648
+ if (depth === 0 && decl.type === "VariableDeclaration" && !pad) {
5649
+ return `export ${inner}`;
5650
+ }
5651
+ return inner;
5432
5652
  }
5433
5653
  case "ImportDeclaration": {
5434
5654
  const specs = stmt.specifiers.map((s) => {
@@ -5455,19 +5675,16 @@ function transpileStatement(stmt, depth, opts) {
5455
5675
  }
5456
5676
  case "FunctionDeclaration": {
5457
5677
  if (!stmt.id) return `${pad}// <anonymous fn skipped>`;
5458
- const paramParts = stmt.params.map((p) => {
5459
- if (p.type === "Identifier") return { kind: "id", name: p.name };
5460
- if (p.type === "RestElement" && p.argument.type === "Identifier") {
5461
- return { kind: "rest", name: p.argument.name };
5462
- }
5463
- return { kind: "id", name: "_" };
5464
- });
5465
- const named = paramParts.filter((p) => p.kind === "id" && p.name !== "_").map((p) => p.name);
5466
- const rest = paramParts.find((p) => p.kind === "rest");
5467
- const paramsSig = rest ? [...named, `...${rest.name}`] : named;
5678
+ const { sig, rest, prologue } = emitParamBinding(
5679
+ stmt.params,
5680
+ indent(depth + 2),
5681
+ opts
5682
+ );
5683
+ const named = sig;
5684
+ const paramsSig = rest ? [...named, `...${rest}`] : named;
5468
5685
  const params = paramsSig.join(", ");
5469
- const bodyStmts = stmt.body.type === "BlockStatement" ? transpileFnBodyStmts(stmt.body.body, depth + 2, opts) : `${indent(depth + 2)}return ${transpileExpression(stmt.body, opts)};`;
5470
- const restBind = rest ? `${indent(depth + 1)}const ${rest.name} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
5686
+ const bodyStmts = stmt.body.type === "BlockStatement" ? [...prologue, transpileFnBodyStmts(stmt.body.body, depth + 2, opts)].join("\n") : `${indent(depth + 2)}return ${transpileExpression(stmt.body, opts)};`;
5687
+ const restBind = rest ? `${indent(depth + 1)}const ${rest} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
5471
5688
  ` : "";
5472
5689
  if (stmt.generator) {
5473
5690
  return [
@@ -5509,7 +5726,7 @@ function transpileStatement(stmt, depth, opts) {
5509
5726
  case "ExpressionStatement":
5510
5727
  return `${pad}${transpileExpression(stmt.expression, opts)};`;
5511
5728
  case "VariableDeclaration": {
5512
- const kw = stmt.kind === "const" ? "const" : "let";
5729
+ const kw = "let";
5513
5730
  const asVar = matchAsOverride(stmt, opts);
5514
5731
  const lines = [];
5515
5732
  let tmpSeq = 0;
@@ -5562,7 +5779,7 @@ function transpileStatement(stmt, depth, opts) {
5562
5779
  ].join("\n");
5563
5780
  }
5564
5781
  case "BlockStatement":
5565
- return stmt.body.map((s) => transpileStatement(s, depth, opts)).join("\n");
5782
+ return transpileFnBodyStmts(stmt.body, depth, opts);
5566
5783
  case "SwitchStatement": {
5567
5784
  const disc = transpileExpression(stmt.discriminant, opts);
5568
5785
  const arms = [];
@@ -5822,6 +6039,15 @@ function transpileExpression(expr, opts = {}) {
5822
6039
  const r = transpileExpression(expr.right, opts);
5823
6040
  return op === "&&" ? `$fork(${l}, () => ${r}, () => ${l})` : `$fork(${l}, () => ${l}, () => ${r})`;
5824
6041
  }
6042
+ case "ConditionalExpression": {
6043
+ const test = transpileExpression(expr.test, opts);
6044
+ const c = transpileExpression(expr.consequent, opts);
6045
+ const a = transpileExpression(expr.alternate, opts);
6046
+ return `$fork(${test}, () => ${c}, () => ${a})`;
6047
+ }
6048
+ case "RegExpLiteral": {
6049
+ return `$regex(${JSON.stringify(expr.pattern)}${expr.flags ? `, ${JSON.stringify(expr.flags)}` : ""})`;
6050
+ }
5825
6051
  case "BinaryExpression": {
5826
6052
  const fn = BIN_OPS[expr.operator];
5827
6053
  if (!fn) return `/* unsupported ${expr.operator} */ $lit(undefined)`;
@@ -5837,6 +6063,14 @@ function transpileExpression(expr, opts = {}) {
5837
6063
  if (expr.operator === "+") return arg;
5838
6064
  return `/* unary ${expr.operator} */ $lit(undefined)`;
5839
6065
  }
6066
+ case "UpdateExpression": {
6067
+ const arg = expr.argument;
6068
+ if (arg.type === "Identifier") {
6069
+ const fn = expr.operator === "++" ? "$add" : "$sub";
6070
+ return `${arg.name} = ${fn}(${arg.name}, $lit(1))`;
6071
+ }
6072
+ return `/* update ${expr.operator} */ $lit(undefined)`;
6073
+ }
5840
6074
  case "AwaitExpression": {
5841
6075
  const arg = transpileExpression(expr.argument, opts);
5842
6076
  return `$await(${arg})`;
@@ -5938,19 +6172,23 @@ function transpileExpression(expr, opts = {}) {
5938
6172
  return acc ?? `$arr([])`;
5939
6173
  }
5940
6174
  case "AssignmentExpression": {
5941
- if (expr.operator !== "=") return `/* assign ${expr.operator} */ $lit(undefined)`;
6175
+ const compoundFn = COMPOUND_OPS[expr.operator];
5942
6176
  const right = transpileExpression(expr.right, opts);
5943
6177
  if (expr.left.type === "MemberExpression") {
5944
- if (!expr.left.computed && expr.left.object.type === "ThisExpression" && expr.left.property.type === "Identifier" && opts.thisParam) {
5945
- return `${opts.thisParam} = $set(${opts.thisParam}, ${JSON.stringify(expr.left.property.name)}, ${right})`;
6178
+ const m = expr.left;
6179
+ const path = memberPathOf(m, opts);
6180
+ if (path) {
6181
+ const valSrc = compoundFn ? `${compoundFn}(${readPathSrc(path)}, ${right})` : right;
6182
+ const writeSrc = setPathSrc(path, valSrc);
6183
+ return `${path.rootSrc} = ${writeSrc}`;
5946
6184
  }
5947
- if (!expr.left.computed && expr.left.property.type === "Identifier") {
5948
- const obj2 = transpileExpression(expr.left.object, opts);
5949
- return `$set(${obj2}, ${JSON.stringify(expr.left.property.name)}, ${right})`;
6185
+ if (!m.computed && m.property.type === "Identifier") {
6186
+ const obj2 = transpileExpression(m.object, opts);
6187
+ return `$set(${obj2}, ${JSON.stringify(m.property.name)}, ${right})`;
5950
6188
  }
5951
- if (expr.left.computed) {
5952
- const obj2 = transpileExpression(expr.left.object, opts);
5953
- const k = expr.left.property;
6189
+ if (m.computed) {
6190
+ const obj2 = transpileExpression(m.object, opts);
6191
+ const k = m.property;
5954
6192
  if (k.type === "NumericLiteral") {
5955
6193
  return `$idxSet(${obj2}, $lit(${k.value}), ${right})`;
5956
6194
  }
@@ -5961,11 +6199,15 @@ function transpileExpression(expr, opts = {}) {
5961
6199
  return `$idxSet(${obj2}, ${transpileExpression(k, opts)}, ${right})`;
5962
6200
  }
5963
6201
  }
6202
+ return `/* assign */ $lit(undefined)`;
5964
6203
  }
5965
6204
  if (expr.left.type === "Identifier") {
6205
+ if (compoundFn) {
6206
+ return `${expr.left.name} = ${compoundFn}(${expr.left.name}, ${right})`;
6207
+ }
5966
6208
  return `${expr.left.name} = ${right}`;
5967
6209
  }
5968
- return `/* assign */ $lit(undefined)`;
6210
+ return compoundFn ? `/* assign ${expr.operator} */ $lit(undefined)` : `/* assign */ $lit(undefined)`;
5969
6211
  }
5970
6212
  case "CallExpression":
5971
6213
  case "OptionalCallExpression": {
@@ -6020,16 +6262,11 @@ function transpileExpression(expr, opts = {}) {
6020
6262
  case "ArrowFunctionExpression":
6021
6263
  case "FunctionExpression": {
6022
6264
  const fn = expr;
6023
- const paramParts = fn.params.map((p) => {
6024
- if (p.type === "Identifier") return p.name;
6025
- if (p.type === "RestElement" && p.argument?.type === "Identifier") {
6026
- return `...${p.argument.name}`;
6027
- }
6028
- return "_p";
6029
- });
6030
- const nameList = `[${paramParts.map((p) => JSON.stringify(p.startsWith("...") ? p.slice(3) : p)).join(", ")}]`;
6265
+ const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
6266
+ const paramParts = rest ? [...sig, `...${rest}`] : sig;
6267
+ const nameList = `[${sig.map((p) => JSON.stringify(p)).join(", ")}]`;
6031
6268
  if (fn.body.type === "BlockStatement") {
6032
- const inner = transpileFnBodyStmts(fn.body.body, 1, opts);
6269
+ const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1, opts)].join("\n");
6033
6270
  if (fn.async) {
6034
6271
  return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => {
6035
6272
  ${inner}
@@ -6040,6 +6277,13 @@ ${inner}
6040
6277
  })`;
6041
6278
  }
6042
6279
  const bodySrc = transpileExpression(fn.body, opts);
6280
+ if (prologue.length > 0) {
6281
+ const thunk = fn.async ? `$async(() => ${bodySrc})` : bodySrc;
6282
+ return `$fnVal(${nameList}, (${paramParts.join(", ")}) => {
6283
+ ${prologue.join("\n")}
6284
+ return ${thunk};
6285
+ })`;
6286
+ }
6043
6287
  if (fn.async) {
6044
6288
  return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => ${bodySrc}))`;
6045
6289
  }
@@ -6128,6 +6372,21 @@ function findCtor(startName) {
6128
6372
  }
6129
6373
  function $new(cls, args) {
6130
6374
  if (typeof cls === "function") {
6375
+ if (cls === Array) {
6376
+ if (args.length === 1) {
6377
+ const n = litValue(args[0]);
6378
+ if (typeof n === "number" && Number.isInteger(n) && n >= 0 && n <= 4096) {
6379
+ const els = Array.from({ length: n }, () => undefAbs());
6380
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6381
+ }
6382
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
6383
+ }
6384
+ return abs({ k: "tuple", elements: args.map((a) => asAbs(a) ?? unknown) }, void 0, void 0, "exact");
6385
+ }
6386
+ if (cls === RegExp) {
6387
+ const p = args[0] ? litValue(args[0]) : void 0;
6388
+ if (typeof p === "string") return $regex(p, args[1] ? String(litValue(args[1]) ?? "") : "");
6389
+ }
6131
6390
  const name = cls.name || "Object";
6132
6391
  const shape = objOf({});
6133
6392
  return abs({ k: "brand", name, shape }, void 0, void 0, "path");
@@ -6168,12 +6427,82 @@ function $super(thisVal, childName, args) {
6168
6427
  }
6169
6428
  return after ?? thisVal;
6170
6429
  }
6430
+ function execRegexBrand(re, method, args) {
6431
+ if (re.shape.k !== "brand" || re.shape.name !== "RegExp") return void 0;
6432
+ if (method !== "exec" && method !== "test" && method !== "toString") return void 0;
6433
+ const inner = re.shape.shape;
6434
+ const patAbs = inner.shape.k === "obj" ? inner.shape.slots["source"]?.value : void 0;
6435
+ const flagsAbs = inner.shape.k === "obj" ? inner.shape.slots["flags"]?.value : void 0;
6436
+ const pat = patAbs ? litValue(patAbs) : void 0;
6437
+ if (typeof pat !== "string") return void 0;
6438
+ const flagsV = flagsAbs ? litValue(flagsAbs) : void 0;
6439
+ const flags = typeof flagsV === "string" ? flagsV : "";
6440
+ if (method === "toString") return strLit(`/${pat}/${flags}`);
6441
+ const subject = args[0] ? litValue(args[0]) : void 0;
6442
+ if (typeof subject !== "string") {
6443
+ return method === "test" ? abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial") : void 0;
6444
+ }
6445
+ let reReal;
6446
+ try {
6447
+ reReal = new RegExp(pat, flags);
6448
+ } catch {
6449
+ return void 0;
6450
+ }
6451
+ const m = reReal.exec(subject);
6452
+ if (method === "test") return boolLit(reReal.test(subject));
6453
+ if (!m) {
6454
+ return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
6455
+ }
6456
+ const els = m.map((g) => g === void 0 ? undefAbs() : strLit(g));
6457
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6458
+ }
6459
+ function stringRegexMethod(recv, method, args) {
6460
+ if (method !== "match" && method !== "search") return void 0;
6461
+ const re = args[0];
6462
+ if (!re || re.shape.k !== "brand" || re.shape.name !== "RegExp") return void 0;
6463
+ const inner = re.shape.shape;
6464
+ const patAbs = inner.shape.k === "obj" ? inner.shape.slots["source"]?.value : void 0;
6465
+ const flagsAbs = inner.shape.k === "obj" ? inner.shape.slots["flags"]?.value : void 0;
6466
+ const pat = patAbs ? litValue(patAbs) : void 0;
6467
+ const sv = litValue(recv);
6468
+ if (typeof pat !== "string" || typeof sv !== "string") return void 0;
6469
+ const flagsV = flagsAbs ? litValue(flagsAbs) : void 0;
6470
+ const flags = typeof flagsV === "string" ? flagsV : "";
6471
+ let reReal;
6472
+ try {
6473
+ reReal = new RegExp(pat, flags);
6474
+ } catch {
6475
+ return void 0;
6476
+ }
6477
+ if (method === "search") {
6478
+ const idx = sv.search(reReal);
6479
+ return abs({ k: "prim", type: "number" }, { op: "lit", value: idx }, void 0, "exact");
6480
+ }
6481
+ if (flags.includes("g")) {
6482
+ const all = sv.match(reReal) ?? [];
6483
+ return abs({ k: "tuple", elements: all.map((s) => strLit(s)) }, void 0, void 0, "exact");
6484
+ }
6485
+ const m = reReal.exec(sv);
6486
+ if (!m) {
6487
+ return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
6488
+ }
6489
+ const els = m.map((g) => g === void 0 ? undefAbs() : strLit(g));
6490
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6491
+ }
6171
6492
  function $invoke(thisVal, method, args, loc) {
6493
+ if (!thisVal || typeof thisVal !== "object" || !("shape" in thisVal)) {
6494
+ const ns = namespaceNameOf(thisVal);
6495
+ return (ns ? evalNamespaceCall(ns, method, args) : void 0) ?? unknown;
6496
+ }
6172
6497
  if (thisVal.shape.k === "sum") {
6173
6498
  const results = thisVal.shape.members.filter((m) => memberLikelyHasMethod(m, method)).map((m) => $invoke(m, method, args, loc));
6174
6499
  if (results.length === 0) return unknown;
6175
6500
  return results.reduce((a, b) => joinAbs(a, b));
6176
6501
  }
6502
+ {
6503
+ const reR = execRegexBrand(thisVal, method, args);
6504
+ if (reR !== void 0) return reR;
6505
+ }
6177
6506
  const brandName = thisVal.shape.k === "brand" ? thisVal.shape.name : void 0;
6178
6507
  if (brandName) {
6179
6508
  const m = findMethod(brandName, method);
@@ -6186,6 +6515,10 @@ function $invoke(thisVal, method, args, loc) {
6186
6515
  const arrR = invokeArrMethod(thisVal, method, args);
6187
6516
  if (arrR !== void 0) return arrR;
6188
6517
  }
6518
+ {
6519
+ const sm = stringRegexMethod(thisVal, method, args);
6520
+ if (sm !== void 0) return sm;
6521
+ }
6189
6522
  {
6190
6523
  const viaTable = callAbsMethod(thisVal, method, args);
6191
6524
  if (viaTable) return viaTable;
@@ -6280,6 +6613,18 @@ function invokeArrMethod(arr, method, args) {
6280
6613
  if (method === "join") {
6281
6614
  return abs({ k: "prim", type: "string" }, void 0, void 0, "path");
6282
6615
  }
6616
+ if (method === "fill" && args.length >= 1) {
6617
+ const v2 = asAbs(args[0]) ?? unknown;
6618
+ if (shape.k === "tuple") {
6619
+ return abs(
6620
+ { k: "tuple", elements: shape.elements.map(() => v2) },
6621
+ void 0,
6622
+ void 0,
6623
+ confJoin(arr.conf, v2.conf)
6624
+ );
6625
+ }
6626
+ return abs({ k: "arr", element: v2 }, void 0, void 0, confJoin(arr.conf, v2.conf));
6627
+ }
6283
6628
  if (method === "includes") {
6284
6629
  return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
6285
6630
  }
@@ -6328,6 +6673,7 @@ function $thisSet(thisVal, key, value) {
6328
6673
  return unknown;
6329
6674
  }
6330
6675
  function $orDefault(v2, dflt) {
6676
+ if (v2 === void 0) return asAbsVal(dflt());
6331
6677
  if (litValue(v2) === void 0 && v2.shape.k !== "never") {
6332
6678
  if (v2.term?.op === "lit" && v2.term.value === void 0) return asAbsVal(dflt());
6333
6679
  if (v2.shape.k === "unknown" && v2.term?.op === "lit") return asAbsVal(dflt());
@@ -6382,7 +6728,7 @@ var RUNTIME_IMPORT_RE = /^import\s*\{[^}]+\}\s*from\s*"[^"]+";\s*$/m;
6382
6728
  function rewriteUserImports(js) {
6383
6729
  js = js.replace(
6384
6730
  /^import\s*\{\s*\*\s+as\s+([A-Za-z_$][\w$]*)\s*\}\s*from\s*["']([^"']+)["'];\s*$/gm,
6385
- (_all, local, spec) => `const ${local} = __nudoBindNamespace(${JSON.stringify(spec)});`
6731
+ (_all, local, spec) => `let ${local} = __nudoBindNamespace(${JSON.stringify(spec)});`
6386
6732
  );
6387
6733
  js = js.replace(
6388
6734
  /^import\s*["']([^"']+)["'];\s*$/gm,
@@ -6395,7 +6741,7 @@ function rewriteUserImports(js) {
6395
6741
  return parts.map((p) => {
6396
6742
  const [imported, local] = p.split(/\s+as\s+/).map((x) => x.trim());
6397
6743
  const bind = local ?? imported;
6398
- return `const ${bind} = __nudoBindImport(${JSON.stringify(spec)}, ${JSON.stringify(imported)});`;
6744
+ return `let ${bind} = __nudoBindImport(${JSON.stringify(spec)}, ${JSON.stringify(imported)});`;
6399
6745
  }).join("\n");
6400
6746
  }
6401
6747
  );
@@ -6540,8 +6886,8 @@ ${js}`;
6540
6886
  }
6541
6887
  const exportFns = [...js.matchAll(/^export function (\w+)/gm)].map((m) => m[1]);
6542
6888
  js = js.replace(/^export function /gm, "function ");
6543
- const exportConsts = [...js.matchAll(/^export const (\w+)/gm)].map((m) => m[1]);
6544
- js = js.replace(/^export const /gm, "const ");
6889
+ const exportConsts = [...js.matchAll(/^export (?:const|let) (\w+)/gm)].map((m) => m[1]);
6890
+ js = js.replace(/^export (?:const|let) /gm, "let ");
6545
6891
  const names = [.../* @__PURE__ */ new Set([...exportFns, ...exportConsts])];
6546
6892
  const argNames = [
6547
6893
  ...runtimeArgNames(),
@@ -6595,6 +6941,17 @@ function callTranspiledExportFull(exports, name, args) {
6595
6941
  }
6596
6942
  }
6597
6943
  if (isAbsVal(fn)) {
6944
+ if (fn.shape.k === "fn") {
6945
+ try {
6946
+ const r = $call(fn, args);
6947
+ return { result: r, throws: never };
6948
+ } catch (e) {
6949
+ if (isNudoThrow(e)) {
6950
+ return { result: never, throws: e.absValue };
6951
+ }
6952
+ return { result: unknown, throws: never };
6953
+ }
6954
+ }
6598
6955
  return { result: fn, throws: never };
6599
6956
  }
6600
6957
  return { result: unknown, throws: never };
@@ -6805,6 +7162,7 @@ export {
6805
7162
  asAbsVal,
6806
7163
  $fnVal,
6807
7164
  $lit,
7165
+ litTruth,
6808
7166
  isDefinitelyTrue,
6809
7167
  isDefinitelyFalse,
6810
7168
  $fork,
@@ -6820,6 +7178,8 @@ export {
6820
7178
  $concat,
6821
7179
  $elems,
6822
7180
  $forOf,
7181
+ namespaceNameOf,
7182
+ $regex,
6823
7183
  $get,
6824
7184
  $set,
6825
7185
  $while,