@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.
- package/dist/{chunk-BU4A6XJ3.js → chunk-N7E2A7IK.js} +1027 -667
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +7 -1
- package/dist/{index-CVYjXnwU.d.ts → index-DgyudAkw.d.ts} +13 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -2
- package/package.json +1 -1
|
@@ -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/
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
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
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
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
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
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
|
|
2052
|
+
return void 0;
|
|
2054
2053
|
}
|
|
2055
2054
|
}
|
|
2056
|
-
function
|
|
2057
|
-
const
|
|
2058
|
-
switch (
|
|
2059
|
-
case "
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
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
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
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
|
|
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
|
|
2099
|
+
return void 0;
|
|
2101
2100
|
}
|
|
2102
2101
|
}
|
|
2103
|
-
function
|
|
2104
|
-
|
|
2105
|
-
if (
|
|
2106
|
-
|
|
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
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
case "
|
|
2125
|
-
|
|
2126
|
-
return
|
|
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
|
|
2129
|
+
return void 0;
|
|
2129
2130
|
}
|
|
2130
2131
|
}
|
|
2131
|
-
function
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
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
|
-
|
|
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
|
|
2984
|
+
return next;
|
|
2846
2985
|
}
|
|
2847
|
-
case "
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
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
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
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
|
-
|
|
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
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
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
|
-
|
|
2947
|
-
return
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
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
|
|
2971
|
-
return
|
|
2972
|
-
|
|
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
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
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
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
void 0,
|
|
2992
|
-
void 0,
|
|
2993
|
-
"partial"
|
|
2994
|
-
);
|
|
3059
|
+
var applyCallbackHost;
|
|
3060
|
+
function setApplyCallbackHost(fn) {
|
|
3061
|
+
applyCallbackHost = fn;
|
|
2995
3062
|
}
|
|
2996
|
-
function
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
const
|
|
3000
|
-
|
|
3001
|
-
|
|
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
|
-
|
|
3018
|
-
return void 0;
|
|
3071
|
+
return unknown;
|
|
3019
3072
|
}
|
|
3073
|
+
return applyCallbackHost(cb, args, env, phi2, budget);
|
|
3020
3074
|
}
|
|
3021
|
-
function
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
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
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
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
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
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
|
-
|
|
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
|
|
5008
|
+
return litTruth(a) === true;
|
|
4960
5009
|
}
|
|
4961
5010
|
function isDefinitelyFalse(a) {
|
|
4962
|
-
const
|
|
4963
|
-
if (
|
|
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
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
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
|
|
5333
|
-
|
|
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
|
|
5341
|
-
if (
|
|
5342
|
-
const
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
}
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
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
|
-
|
|
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
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
6175
|
+
const compoundFn = COMPOUND_OPS[expr.operator];
|
|
5942
6176
|
const right = transpileExpression(expr.right, opts);
|
|
5943
6177
|
if (expr.left.type === "MemberExpression") {
|
|
5944
|
-
|
|
5945
|
-
|
|
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 (!
|
|
5948
|
-
const obj2 = transpileExpression(
|
|
5949
|
-
return `$set(${obj2}, ${JSON.stringify(
|
|
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 (
|
|
5952
|
-
const obj2 = transpileExpression(
|
|
5953
|
-
const k =
|
|
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
|
|
6024
|
-
|
|
6025
|
-
|
|
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) => `
|
|
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 `
|
|
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, "
|
|
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,
|