funcity 0.2.0 → 0.3.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/index.cjs +416 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +416 -279
- package/dist/index.mjs.map +1 -1
- package/dist/parser.d.ts +3 -266
- package/dist/parser.d.ts.map +1 -1
- package/dist/reducer.d.ts +7 -81
- package/dist/reducer.d.ts.map +1 -1
- package/dist/scripting.d.ts +10 -108
- package/dist/scripting.d.ts.map +1 -1
- package/dist/standards.d.ts +10 -5
- package/dist/standards.d.ts.map +1 -1
- package/dist/tokenizer.d.ts +3 -122
- package/dist/tokenizer.d.ts.map +1 -1
- package/dist/types.d.ts +453 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +75 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,225 @@
|
|
|
1
|
+
const emptyLocation = {
|
|
2
|
+
line: 0,
|
|
3
|
+
column: 0
|
|
4
|
+
};
|
|
5
|
+
const emptyRange = {
|
|
6
|
+
start: emptyLocation,
|
|
7
|
+
end: emptyLocation
|
|
8
|
+
};
|
|
9
|
+
const specialFunctionMarker = /* @__PURE__ */ Symbol("$$special$$");
|
|
10
|
+
const makeFunCityFunction = (f) => {
|
|
11
|
+
f[specialFunctionMarker] = true;
|
|
12
|
+
return f;
|
|
13
|
+
};
|
|
14
|
+
const isFunCityFunction = (f) => {
|
|
15
|
+
var _a;
|
|
16
|
+
return (_a = f[specialFunctionMarker]) != null ? _a : false;
|
|
17
|
+
};
|
|
18
|
+
const isConditionalTrue = (v) => {
|
|
19
|
+
if (v === void 0 || v === null) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
switch (typeof v) {
|
|
23
|
+
case "boolean":
|
|
24
|
+
return v;
|
|
25
|
+
case "number":
|
|
26
|
+
case "bigint":
|
|
27
|
+
return v !== 0;
|
|
28
|
+
default:
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const asIterable = (v) => {
|
|
33
|
+
if (typeof v[Symbol.iterator] === "function") {
|
|
34
|
+
return v;
|
|
35
|
+
} else {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const combineVariables = (...variablesList) => {
|
|
40
|
+
const variables = /* @__PURE__ */ new Map();
|
|
41
|
+
const appendVariables = (vs) => vs.forEach((v, k) => variables.set(k, v));
|
|
42
|
+
const appendRecord = (vs) => Object.keys(vs).forEach((k) => variables.set(k, vs[k]));
|
|
43
|
+
variablesList.forEach((vs) => {
|
|
44
|
+
if (vs["forEach"] !== void 0) {
|
|
45
|
+
appendVariables(vs);
|
|
46
|
+
} else {
|
|
47
|
+
appendRecord(vs);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return variables;
|
|
51
|
+
};
|
|
52
|
+
const fromError = (error) => {
|
|
53
|
+
var _a;
|
|
54
|
+
if (error.message) {
|
|
55
|
+
return error.message;
|
|
56
|
+
} else if (typeof error.toString === "function") {
|
|
57
|
+
return (_a = error.toString()) != null ? _a : "unknown";
|
|
58
|
+
} else {
|
|
59
|
+
return "unknown";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const widerRange = (...ranges) => {
|
|
63
|
+
let start = emptyRange.start;
|
|
64
|
+
let end = emptyRange.end;
|
|
65
|
+
for (const range of ranges) {
|
|
66
|
+
if (range.start.line >= 1 && range.start.column >= 1) {
|
|
67
|
+
if (start.line === 0 || start.column === 0) {
|
|
68
|
+
start = range.start;
|
|
69
|
+
} else if (range.start.line < start.line) {
|
|
70
|
+
start = range.start;
|
|
71
|
+
} else if (range.start.line === start.line && range.start.column < start.column) {
|
|
72
|
+
start = range.start;
|
|
73
|
+
}
|
|
74
|
+
if (end.line === 0 || end.column === 0) {
|
|
75
|
+
end = range.end;
|
|
76
|
+
} else if (range.end.line > end.line) {
|
|
77
|
+
end = range.end;
|
|
78
|
+
} else if (range.end.line === end.line && range.end.column > end.column) {
|
|
79
|
+
end = range.end;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { start, end };
|
|
84
|
+
};
|
|
85
|
+
const locationEquals = (lhs, rhs) => lhs.line === rhs.line && lhs.column === rhs.column;
|
|
86
|
+
const getLocationString = (range) => locationEquals(range.start, range.end) ? `${range.start.line}:${range.start.column}` : `${range.start.line}:${range.start.column}:${range.end.line}:${range.end.column}`;
|
|
87
|
+
const printErrorString = (path, error) => {
|
|
88
|
+
switch (error.type) {
|
|
89
|
+
case "warning":
|
|
90
|
+
console.warn(
|
|
91
|
+
`${path}:${getLocationString(error.range)}: warning: ${error.description}`
|
|
92
|
+
);
|
|
93
|
+
break;
|
|
94
|
+
case "error":
|
|
95
|
+
console.error(
|
|
96
|
+
`${path}:${getLocationString(error.range)}: error: ${error.description}`
|
|
97
|
+
);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
};
|
|
102
|
+
const outputErrors = (path, errors) => {
|
|
103
|
+
let isError = false;
|
|
104
|
+
for (const error of errors) {
|
|
105
|
+
const result = printErrorString(path, error);
|
|
106
|
+
isError || (isError = result);
|
|
107
|
+
}
|
|
108
|
+
return isError;
|
|
109
|
+
};
|
|
110
|
+
const funcIds = /* @__PURE__ */ new WeakMap();
|
|
111
|
+
let nextId = 1;
|
|
112
|
+
const getFuncId = (fn) => {
|
|
113
|
+
const cached = funcIds.get(fn);
|
|
114
|
+
if (cached) {
|
|
115
|
+
return cached;
|
|
116
|
+
}
|
|
117
|
+
const id = nextId++;
|
|
118
|
+
funcIds.set(fn, id);
|
|
119
|
+
return id;
|
|
120
|
+
};
|
|
121
|
+
const convertToString = (v) => {
|
|
122
|
+
switch (v) {
|
|
123
|
+
case void 0:
|
|
124
|
+
return "(undefined)";
|
|
125
|
+
case null:
|
|
126
|
+
return "(null)";
|
|
127
|
+
default:
|
|
128
|
+
switch (typeof v) {
|
|
129
|
+
case "string":
|
|
130
|
+
return v;
|
|
131
|
+
case "boolean":
|
|
132
|
+
return v ? "true" : "false";
|
|
133
|
+
case "number":
|
|
134
|
+
case "bigint":
|
|
135
|
+
case "symbol":
|
|
136
|
+
return v.toString();
|
|
137
|
+
case "function":
|
|
138
|
+
if (v.name) {
|
|
139
|
+
return `fun<${v.name}:#${getFuncId(v)}>`;
|
|
140
|
+
} else {
|
|
141
|
+
return `fun<#${getFuncId(v)}>`;
|
|
142
|
+
}
|
|
143
|
+
default:
|
|
144
|
+
if (Array.isArray(v)) {
|
|
145
|
+
return JSON.stringify(v);
|
|
146
|
+
}
|
|
147
|
+
const iterable = asIterable(v);
|
|
148
|
+
if (iterable) {
|
|
149
|
+
const arr = Array.from(iterable);
|
|
150
|
+
return JSON.stringify(arr);
|
|
151
|
+
} else if (v instanceof Date) {
|
|
152
|
+
return v.toISOString();
|
|
153
|
+
} else if (v instanceof Error) {
|
|
154
|
+
return `${v.name}: ${v.message}`;
|
|
155
|
+
} else if (v instanceof URL) {
|
|
156
|
+
return v.origin;
|
|
157
|
+
} else {
|
|
158
|
+
return JSON.stringify(v);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const stringEscapeMap = {
|
|
164
|
+
f: "\f",
|
|
165
|
+
n: "\n",
|
|
166
|
+
r: "\r",
|
|
167
|
+
t: " ",
|
|
168
|
+
v: "\v",
|
|
169
|
+
"0": "\0",
|
|
170
|
+
"'": "'",
|
|
171
|
+
"\\": "\\"
|
|
172
|
+
};
|
|
1
173
|
const tokenizeString = (context) => {
|
|
2
174
|
const start = context.cursor.location("start");
|
|
3
175
|
context.cursor.skip(1);
|
|
4
|
-
let value =
|
|
5
|
-
|
|
176
|
+
let value = "";
|
|
177
|
+
let closed = false;
|
|
178
|
+
while (!context.cursor.eot()) {
|
|
179
|
+
const ch = context.cursor.getChar();
|
|
180
|
+
if (ch === "'") {
|
|
181
|
+
context.cursor.skip(1);
|
|
182
|
+
closed = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
if (ch === "\\") {
|
|
186
|
+
const escapeStart = context.cursor.location("start");
|
|
187
|
+
context.cursor.skip(1);
|
|
188
|
+
if (context.cursor.eot()) {
|
|
189
|
+
context.errors.push({
|
|
190
|
+
type: "error",
|
|
191
|
+
description: "invalid escape sequence: \\\\",
|
|
192
|
+
range: { start: escapeStart, end: context.cursor.location("end") }
|
|
193
|
+
});
|
|
194
|
+
value += "\\";
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
const escape = context.cursor.getChar();
|
|
198
|
+
const mapped = stringEscapeMap[escape];
|
|
199
|
+
if (mapped !== void 0) {
|
|
200
|
+
value += mapped;
|
|
201
|
+
context.cursor.skip(1);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
context.cursor.skip(1);
|
|
205
|
+
context.errors.push({
|
|
206
|
+
type: "error",
|
|
207
|
+
description: `invalid escape sequence: \\${escape}`,
|
|
208
|
+
range: { start: escapeStart, end: context.cursor.location("end") }
|
|
209
|
+
});
|
|
210
|
+
value += `\\${escape}`;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
value += ch;
|
|
6
214
|
context.cursor.skip(1);
|
|
7
|
-
}
|
|
215
|
+
}
|
|
216
|
+
if (!closed) {
|
|
8
217
|
const location = context.cursor.location("start");
|
|
9
218
|
context.errors.push({
|
|
10
219
|
type: "error",
|
|
11
220
|
description: "string close quote is not found",
|
|
12
221
|
range: { start: location, end: location }
|
|
13
222
|
});
|
|
14
|
-
value = "";
|
|
15
223
|
}
|
|
16
224
|
return {
|
|
17
225
|
kind: "string",
|
|
@@ -348,115 +556,6 @@ const runTokenizer = (script, errors) => {
|
|
|
348
556
|
}
|
|
349
557
|
return tokens;
|
|
350
558
|
};
|
|
351
|
-
const emptyLocation = {
|
|
352
|
-
line: 0,
|
|
353
|
-
column: 0
|
|
354
|
-
};
|
|
355
|
-
const emptyRange = {
|
|
356
|
-
start: emptyLocation,
|
|
357
|
-
end: emptyLocation
|
|
358
|
-
};
|
|
359
|
-
const specialFunctionMarker = /* @__PURE__ */ Symbol("$$special$$");
|
|
360
|
-
const makeSpecialFunction = (f) => {
|
|
361
|
-
f[specialFunctionMarker] = true;
|
|
362
|
-
return f;
|
|
363
|
-
};
|
|
364
|
-
const isSpecialFunction = (f) => {
|
|
365
|
-
var _a;
|
|
366
|
-
return (_a = f[specialFunctionMarker]) != null ? _a : false;
|
|
367
|
-
};
|
|
368
|
-
const isConditionalTrue = (v) => {
|
|
369
|
-
if (v === void 0 || v === null) {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
switch (typeof v) {
|
|
373
|
-
case "boolean":
|
|
374
|
-
return v;
|
|
375
|
-
case "number":
|
|
376
|
-
case "bigint":
|
|
377
|
-
return v !== 0;
|
|
378
|
-
default:
|
|
379
|
-
return true;
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
const asIterable = (v) => {
|
|
383
|
-
if (typeof v[Symbol.iterator] === "function") {
|
|
384
|
-
return v;
|
|
385
|
-
} else {
|
|
386
|
-
return void 0;
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
const combineVariables = (...variablesList) => {
|
|
390
|
-
const variables = /* @__PURE__ */ new Map();
|
|
391
|
-
const appendVariables = (vs) => vs.forEach((v, k) => variables.set(k, v));
|
|
392
|
-
const appendRecord = (vs) => Object.keys(vs).forEach((k) => variables.set(k, vs[k]));
|
|
393
|
-
variablesList.forEach((vs) => {
|
|
394
|
-
if (vs["forEach"] !== void 0) {
|
|
395
|
-
appendVariables(vs);
|
|
396
|
-
} else {
|
|
397
|
-
appendRecord(vs);
|
|
398
|
-
}
|
|
399
|
-
});
|
|
400
|
-
return variables;
|
|
401
|
-
};
|
|
402
|
-
const fromError = (error) => {
|
|
403
|
-
var _a;
|
|
404
|
-
if (error.message) {
|
|
405
|
-
return error.message;
|
|
406
|
-
} else if (typeof error.toString === "function") {
|
|
407
|
-
return (_a = error.toString()) != null ? _a : "unknown";
|
|
408
|
-
} else {
|
|
409
|
-
return "unknown";
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
const widerRange = (...ranges) => {
|
|
413
|
-
let start = emptyRange.start;
|
|
414
|
-
let end = emptyRange.end;
|
|
415
|
-
for (const range of ranges) {
|
|
416
|
-
if (range.start.line >= 1 && range.start.column >= 1) {
|
|
417
|
-
if (start.line === 0 || start.column === 0) {
|
|
418
|
-
start = range.start;
|
|
419
|
-
} else if (range.start.line < start.line) {
|
|
420
|
-
start = range.start;
|
|
421
|
-
} else if (range.start.line === start.line && range.start.column < start.column) {
|
|
422
|
-
start = range.start;
|
|
423
|
-
}
|
|
424
|
-
if (end.line === 0 || end.column === 0) {
|
|
425
|
-
end = range.end;
|
|
426
|
-
} else if (range.end.line > end.line) {
|
|
427
|
-
end = range.end;
|
|
428
|
-
} else if (range.end.line === end.line && range.end.column > end.column) {
|
|
429
|
-
end = range.end;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return { start, end };
|
|
434
|
-
};
|
|
435
|
-
const locationEquals = (lhs, rhs) => lhs.line === rhs.line && lhs.column === rhs.column;
|
|
436
|
-
const getLocationString = (range) => locationEquals(range.start, range.end) ? `${range.start.line}:${range.start.column}` : `${range.start.line}:${range.start.column}:${range.end.line}:${range.end.column}`;
|
|
437
|
-
const printErrorString = (path, error) => {
|
|
438
|
-
switch (error.type) {
|
|
439
|
-
case "warning":
|
|
440
|
-
console.warn(
|
|
441
|
-
`${path}:${getLocationString(error.range)}: warning: ${error.description}`
|
|
442
|
-
);
|
|
443
|
-
break;
|
|
444
|
-
case "error":
|
|
445
|
-
console.error(
|
|
446
|
-
`${path}:${getLocationString(error.range)}: error: ${error.description}`
|
|
447
|
-
);
|
|
448
|
-
return true;
|
|
449
|
-
}
|
|
450
|
-
return false;
|
|
451
|
-
};
|
|
452
|
-
const outputErrors = (path, errors) => {
|
|
453
|
-
let isError = false;
|
|
454
|
-
for (const error of errors) {
|
|
455
|
-
const result = printErrorString(path, error);
|
|
456
|
-
isError || (isError = result);
|
|
457
|
-
}
|
|
458
|
-
return isError;
|
|
459
|
-
};
|
|
460
559
|
const parseNumber = (cursor, _errors) => {
|
|
461
560
|
const token = cursor.takeToken();
|
|
462
561
|
return {
|
|
@@ -1197,38 +1296,6 @@ const parseBlock = (cursor, errors) => {
|
|
|
1197
1296
|
}
|
|
1198
1297
|
break;
|
|
1199
1298
|
}
|
|
1200
|
-
case "set": {
|
|
1201
|
-
cursor.skipToken();
|
|
1202
|
-
const args = parseStatementArguments(cursor, errors);
|
|
1203
|
-
if (args.length !== 2) {
|
|
1204
|
-
errors.push({
|
|
1205
|
-
type: "error",
|
|
1206
|
-
description: "Required `set` bind identity and expression",
|
|
1207
|
-
range: widerRange(
|
|
1208
|
-
token.range,
|
|
1209
|
-
...args.map((node) => node.range)
|
|
1210
|
-
)
|
|
1211
|
-
});
|
|
1212
|
-
break;
|
|
1213
|
-
}
|
|
1214
|
-
const bindNode = args[0];
|
|
1215
|
-
if (bindNode.kind !== "variable") {
|
|
1216
|
-
errors.push({
|
|
1217
|
-
type: "error",
|
|
1218
|
-
description: "Required `set` bind identity",
|
|
1219
|
-
range: bindNode.range
|
|
1220
|
-
});
|
|
1221
|
-
break;
|
|
1222
|
-
}
|
|
1223
|
-
const exprNode = args[1];
|
|
1224
|
-
pushNode(statementStates, {
|
|
1225
|
-
kind: "set",
|
|
1226
|
-
name: bindNode,
|
|
1227
|
-
expr: exprNode,
|
|
1228
|
-
range: widerRange(token.range, bindNode.range, exprNode.range)
|
|
1229
|
-
});
|
|
1230
|
-
break;
|
|
1231
|
-
}
|
|
1232
1299
|
default: {
|
|
1233
1300
|
const node = parseExpression(cursor, errors);
|
|
1234
1301
|
if (node) {
|
|
@@ -1371,6 +1438,7 @@ const fromLambda = (context, lambda) => {
|
|
|
1371
1438
|
};
|
|
1372
1439
|
};
|
|
1373
1440
|
const reduceExpressionNode = async (context, node) => {
|
|
1441
|
+
var _a;
|
|
1374
1442
|
switch (node.kind) {
|
|
1375
1443
|
case "number":
|
|
1376
1444
|
case "string": {
|
|
@@ -1380,6 +1448,7 @@ const reduceExpressionNode = async (context, node) => {
|
|
|
1380
1448
|
return traverseVariable(context, node);
|
|
1381
1449
|
}
|
|
1382
1450
|
case "apply": {
|
|
1451
|
+
(_a = context.abortSignal) == null ? void 0 : _a.throwIfAborted();
|
|
1383
1452
|
const func = await reduceExpressionNode(context, node.func);
|
|
1384
1453
|
if (typeof func !== "function") {
|
|
1385
1454
|
context.appendError({
|
|
@@ -1389,28 +1458,26 @@ const reduceExpressionNode = async (context, node) => {
|
|
|
1389
1458
|
});
|
|
1390
1459
|
return void 0;
|
|
1391
1460
|
}
|
|
1461
|
+
const args = isFunCityFunction(func) ? node.args : await Promise.all(
|
|
1462
|
+
node.args.map(async (argNode) => {
|
|
1463
|
+
const arg = await reduceExpressionNode(context, argNode);
|
|
1464
|
+
return arg;
|
|
1465
|
+
})
|
|
1466
|
+
);
|
|
1392
1467
|
const thisProxy = context.createFunctionContext(node);
|
|
1393
|
-
|
|
1394
|
-
const value = await func.call(thisProxy, ...node.args);
|
|
1395
|
-
return value;
|
|
1396
|
-
} else {
|
|
1397
|
-
const args = await Promise.all(
|
|
1398
|
-
node.args.map(async (argNode) => {
|
|
1399
|
-
try {
|
|
1400
|
-
const arg = await reduceExpressionNode(context, argNode);
|
|
1401
|
-
return arg;
|
|
1402
|
-
} catch (e) {
|
|
1403
|
-
context.appendError({
|
|
1404
|
-
type: "error",
|
|
1405
|
-
description: fromError(e),
|
|
1406
|
-
range: argNode.range
|
|
1407
|
-
});
|
|
1408
|
-
return void 0;
|
|
1409
|
-
}
|
|
1410
|
-
})
|
|
1411
|
-
);
|
|
1468
|
+
try {
|
|
1412
1469
|
const value = await func.call(thisProxy, ...args);
|
|
1413
1470
|
return value;
|
|
1471
|
+
} catch (e) {
|
|
1472
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
1473
|
+
throw e;
|
|
1474
|
+
}
|
|
1475
|
+
context.appendError({
|
|
1476
|
+
type: "error",
|
|
1477
|
+
description: fromError(e),
|
|
1478
|
+
range: node.range
|
|
1479
|
+
});
|
|
1480
|
+
return void 0;
|
|
1414
1481
|
}
|
|
1415
1482
|
}
|
|
1416
1483
|
case "lambda": {
|
|
@@ -1422,11 +1489,6 @@ const reduceExpressionNode = async (context, node) => {
|
|
|
1422
1489
|
);
|
|
1423
1490
|
return results;
|
|
1424
1491
|
}
|
|
1425
|
-
case "set": {
|
|
1426
|
-
const expr = await reduceExpressionNode(context, node.expr);
|
|
1427
|
-
context.setValue(node.name.name, expr);
|
|
1428
|
-
return void 0;
|
|
1429
|
-
}
|
|
1430
1492
|
case "scope": {
|
|
1431
1493
|
if (node.nodes.length === 0) {
|
|
1432
1494
|
return [];
|
|
@@ -1508,32 +1570,76 @@ const reduceNode = async (context, node) => {
|
|
|
1508
1570
|
}
|
|
1509
1571
|
}
|
|
1510
1572
|
};
|
|
1511
|
-
const
|
|
1512
|
-
let
|
|
1513
|
-
let
|
|
1514
|
-
|
|
1573
|
+
const createScopedReducerContext = (parent) => {
|
|
1574
|
+
let thisVars;
|
|
1575
|
+
let thisContext;
|
|
1576
|
+
const getValue = (name) => {
|
|
1577
|
+
var _a;
|
|
1578
|
+
(_a = parent.abortSignal) == null ? void 0 : _a.throwIfAborted();
|
|
1579
|
+
if (thisVars == null ? void 0 : thisVars.has(name)) {
|
|
1580
|
+
return { value: thisVars.get(name), isFound: true };
|
|
1581
|
+
} else {
|
|
1582
|
+
return parent.getValue(name);
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
const setValue = (name, value) => {
|
|
1586
|
+
var _a;
|
|
1587
|
+
(_a = parent.abortSignal) == null ? void 0 : _a.throwIfAborted();
|
|
1588
|
+
if (!thisVars) {
|
|
1589
|
+
thisVars = /* @__PURE__ */ new Map();
|
|
1590
|
+
}
|
|
1591
|
+
thisVars.set(name, value);
|
|
1592
|
+
};
|
|
1593
|
+
const createFunctionContext = (thisNode) => {
|
|
1594
|
+
const newContext = {
|
|
1595
|
+
thisNode,
|
|
1596
|
+
abortSignal: parent.abortSignal,
|
|
1597
|
+
getValue,
|
|
1598
|
+
setValue,
|
|
1599
|
+
isFailed: parent.isFailed,
|
|
1600
|
+
appendError: parent.appendError,
|
|
1601
|
+
reduce: (node) => {
|
|
1602
|
+
var _a;
|
|
1603
|
+
(_a = parent.abortSignal) == null ? void 0 : _a.throwIfAborted();
|
|
1604
|
+
return reduceExpressionNode(thisContext, node);
|
|
1605
|
+
}
|
|
1606
|
+
};
|
|
1607
|
+
return newContext;
|
|
1608
|
+
};
|
|
1609
|
+
thisContext = {
|
|
1610
|
+
abortSignal: parent.abortSignal,
|
|
1611
|
+
getValue,
|
|
1612
|
+
setValue,
|
|
1613
|
+
isFailed: parent.isFailed,
|
|
1614
|
+
appendError: parent.appendError,
|
|
1615
|
+
newScope: () => {
|
|
1616
|
+
var _a;
|
|
1617
|
+
(_a = parent.abortSignal) == null ? void 0 : _a.throwIfAborted();
|
|
1618
|
+
return createScopedReducerContext(thisContext);
|
|
1619
|
+
},
|
|
1620
|
+
createFunctionContext
|
|
1621
|
+
};
|
|
1622
|
+
return thisContext;
|
|
1623
|
+
};
|
|
1624
|
+
const createReducerContext = (variables, errors, signal) => {
|
|
1625
|
+
let thisVars;
|
|
1626
|
+
let thisContext;
|
|
1515
1627
|
const getValue = (name) => {
|
|
1516
|
-
|
|
1517
|
-
|
|
1628
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
1629
|
+
if (thisVars == null ? void 0 : thisVars.has(name)) {
|
|
1630
|
+
return { value: thisVars.get(name), isFound: true };
|
|
1631
|
+
} else if (variables.has(name)) {
|
|
1632
|
+
return { value: variables.get(name), isFound: true };
|
|
1518
1633
|
} else {
|
|
1519
1634
|
return { value: void 0, isFound: false };
|
|
1520
1635
|
}
|
|
1521
1636
|
};
|
|
1522
1637
|
const setValue = (name, value) => {
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
}
|
|
1527
|
-
mvs.set(name, value);
|
|
1528
|
-
if (variablesProxy !== void 0) {
|
|
1529
|
-
Object.defineProperty(variablesProxy, name, {
|
|
1530
|
-
get() {
|
|
1531
|
-
return vs.get(name);
|
|
1532
|
-
},
|
|
1533
|
-
configurable: true,
|
|
1534
|
-
enumerable: true
|
|
1535
|
-
});
|
|
1638
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
1639
|
+
if (!thisVars) {
|
|
1640
|
+
thisVars = /* @__PURE__ */ new Map();
|
|
1536
1641
|
}
|
|
1642
|
+
thisVars.set(name, value);
|
|
1537
1643
|
};
|
|
1538
1644
|
const appendError = (error) => {
|
|
1539
1645
|
errors.push(error);
|
|
@@ -1541,47 +1647,37 @@ const createReducerContext = (variables, errors) => {
|
|
|
1541
1647
|
const isFailed = () => {
|
|
1542
1648
|
return errors.some((error) => error.type === "error");
|
|
1543
1649
|
};
|
|
1544
|
-
const newScope = () => {
|
|
1545
|
-
const newContext = createReducerContext(vs, errors);
|
|
1546
|
-
return newContext;
|
|
1547
|
-
};
|
|
1548
|
-
let context;
|
|
1549
|
-
const reduceByProxy = (node) => reduceExpressionNode(context, node);
|
|
1550
|
-
const getVariablesFromProxy = () => {
|
|
1551
|
-
if (variablesProxy === void 0) {
|
|
1552
|
-
variablesProxy = {};
|
|
1553
|
-
for (const key of vs.keys()) {
|
|
1554
|
-
Object.defineProperty(variablesProxy, key, {
|
|
1555
|
-
get: () => vs.get(key),
|
|
1556
|
-
configurable: true,
|
|
1557
|
-
enumerable: true
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
return variablesProxy;
|
|
1562
|
-
};
|
|
1563
1650
|
const createFunctionContext = (thisNode) => {
|
|
1564
|
-
|
|
1565
|
-
get variables() {
|
|
1566
|
-
return getVariablesFromProxy();
|
|
1567
|
-
},
|
|
1651
|
+
const newContext = {
|
|
1568
1652
|
thisNode,
|
|
1653
|
+
abortSignal: signal,
|
|
1654
|
+
getValue,
|
|
1655
|
+
setValue,
|
|
1656
|
+
isFailed,
|
|
1569
1657
|
appendError,
|
|
1570
|
-
reduce:
|
|
1658
|
+
reduce: (node) => {
|
|
1659
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
1660
|
+
return reduceExpressionNode(thisContext, node);
|
|
1661
|
+
}
|
|
1571
1662
|
};
|
|
1663
|
+
return newContext;
|
|
1572
1664
|
};
|
|
1573
|
-
|
|
1665
|
+
thisContext = {
|
|
1666
|
+
abortSignal: signal,
|
|
1574
1667
|
getValue,
|
|
1575
1668
|
setValue,
|
|
1576
1669
|
appendError,
|
|
1577
1670
|
isFailed,
|
|
1578
|
-
newScope
|
|
1671
|
+
newScope: () => {
|
|
1672
|
+
signal == null ? void 0 : signal.throwIfAborted();
|
|
1673
|
+
return createScopedReducerContext(thisContext);
|
|
1674
|
+
},
|
|
1579
1675
|
createFunctionContext
|
|
1580
1676
|
};
|
|
1581
|
-
return
|
|
1677
|
+
return thisContext;
|
|
1582
1678
|
};
|
|
1583
|
-
async function runReducer(nodes, variables, errors) {
|
|
1584
|
-
const context = createReducerContext(variables, errors);
|
|
1679
|
+
async function runReducer(nodes, variables, errors, signal) {
|
|
1680
|
+
const context = createReducerContext(variables, errors, signal);
|
|
1585
1681
|
const resultList = [];
|
|
1586
1682
|
for (const node of nodes) {
|
|
1587
1683
|
const results = await reduceNode(context, node);
|
|
@@ -1593,7 +1689,15 @@ async function runReducer(nodes, variables, errors) {
|
|
|
1593
1689
|
}
|
|
1594
1690
|
return resultList;
|
|
1595
1691
|
}
|
|
1596
|
-
const _cond =
|
|
1692
|
+
const _cond = makeFunCityFunction(async function(arg0, arg1, arg2) {
|
|
1693
|
+
if (!arg0 || !arg1 || !arg2) {
|
|
1694
|
+
this.appendError({
|
|
1695
|
+
type: "error",
|
|
1696
|
+
description: "Required `cond` condition, true and false expressions",
|
|
1697
|
+
range: this.thisNode.range
|
|
1698
|
+
});
|
|
1699
|
+
return void 0;
|
|
1700
|
+
}
|
|
1597
1701
|
const cond = await this.reduce(arg0);
|
|
1598
1702
|
if (isConditionalTrue(cond)) {
|
|
1599
1703
|
return await this.reduce(arg1);
|
|
@@ -1601,6 +1705,27 @@ const _cond = makeSpecialFunction(async function(arg0, arg1, arg2) {
|
|
|
1601
1705
|
return await this.reduce(arg2);
|
|
1602
1706
|
}
|
|
1603
1707
|
});
|
|
1708
|
+
const _set = makeFunCityFunction(async function(arg0, arg1, ...rest) {
|
|
1709
|
+
if (!arg0 || !arg1 || rest.length !== 0) {
|
|
1710
|
+
this.appendError({
|
|
1711
|
+
type: "error",
|
|
1712
|
+
description: "Required `set` bind identity and expression",
|
|
1713
|
+
range: this.thisNode.range
|
|
1714
|
+
});
|
|
1715
|
+
return void 0;
|
|
1716
|
+
}
|
|
1717
|
+
if (arg0.kind !== "variable") {
|
|
1718
|
+
this.appendError({
|
|
1719
|
+
type: "error",
|
|
1720
|
+
description: "Required `set` bind identity",
|
|
1721
|
+
range: arg0.range
|
|
1722
|
+
});
|
|
1723
|
+
return void 0;
|
|
1724
|
+
}
|
|
1725
|
+
const value = await this.reduce(arg1);
|
|
1726
|
+
this.setValue(arg0.name, value);
|
|
1727
|
+
return void 0;
|
|
1728
|
+
});
|
|
1604
1729
|
const _typeof = async (arg0) => {
|
|
1605
1730
|
if (arg0 === null) {
|
|
1606
1731
|
return "null";
|
|
@@ -1614,54 +1739,33 @@ const _typeof = async (arg0) => {
|
|
|
1614
1739
|
return typeof arg0;
|
|
1615
1740
|
}
|
|
1616
1741
|
};
|
|
1617
|
-
const funcIds = /* @__PURE__ */ new WeakMap();
|
|
1618
|
-
let nextId = 1;
|
|
1619
|
-
const getFuncId = (fn) => {
|
|
1620
|
-
const cached = funcIds.get(fn);
|
|
1621
|
-
if (cached) return cached;
|
|
1622
|
-
const id = nextId++;
|
|
1623
|
-
funcIds.set(fn, id);
|
|
1624
|
-
return id;
|
|
1625
|
-
};
|
|
1626
1742
|
const _toString = async (...args) => {
|
|
1627
|
-
const results = args.map((arg0) =>
|
|
1628
|
-
switch (arg0) {
|
|
1629
|
-
case void 0:
|
|
1630
|
-
return "(undefined)";
|
|
1631
|
-
case null:
|
|
1632
|
-
return "(null)";
|
|
1633
|
-
default:
|
|
1634
|
-
switch (typeof arg0) {
|
|
1635
|
-
case "string":
|
|
1636
|
-
return arg0;
|
|
1637
|
-
case "boolean":
|
|
1638
|
-
return arg0 ? "true" : "false";
|
|
1639
|
-
case "number":
|
|
1640
|
-
case "bigint":
|
|
1641
|
-
case "symbol":
|
|
1642
|
-
return arg0.toString();
|
|
1643
|
-
case "function":
|
|
1644
|
-
if (arg0.name) {
|
|
1645
|
-
return `fun<${arg0.name}:#${getFuncId(arg0)}>`;
|
|
1646
|
-
} else {
|
|
1647
|
-
return `fun<#${getFuncId(arg0)}>`;
|
|
1648
|
-
}
|
|
1649
|
-
default:
|
|
1650
|
-
if (Array.isArray(arg0)) {
|
|
1651
|
-
return JSON.stringify(arg0);
|
|
1652
|
-
}
|
|
1653
|
-
const iterable = asIterable(arg0);
|
|
1654
|
-
if (iterable) {
|
|
1655
|
-
const arr = Array.from(iterable);
|
|
1656
|
-
return JSON.stringify(arr);
|
|
1657
|
-
} else {
|
|
1658
|
-
return JSON.stringify(arg0);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
});
|
|
1743
|
+
const results = args.map((arg0) => convertToString(arg0));
|
|
1663
1744
|
return results.join(",");
|
|
1664
1745
|
};
|
|
1746
|
+
const _toBoolean = async (arg0) => {
|
|
1747
|
+
const r = isConditionalTrue(arg0);
|
|
1748
|
+
return r;
|
|
1749
|
+
};
|
|
1750
|
+
const _toNumber = async (arg0) => {
|
|
1751
|
+
const r = Number(arg0);
|
|
1752
|
+
return r;
|
|
1753
|
+
};
|
|
1754
|
+
const _toBigInt = async (arg0) => {
|
|
1755
|
+
switch (typeof arg0) {
|
|
1756
|
+
case "number":
|
|
1757
|
+
case "bigint":
|
|
1758
|
+
case "string":
|
|
1759
|
+
case "boolean": {
|
|
1760
|
+
const r = BigInt(arg0);
|
|
1761
|
+
return r;
|
|
1762
|
+
}
|
|
1763
|
+
default: {
|
|
1764
|
+
const r = BigInt(await _toString(arg0));
|
|
1765
|
+
return r;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
};
|
|
1665
1769
|
const _add = async (arg0, ...args) => {
|
|
1666
1770
|
const r = args.reduce((v0, v) => v0 + Number(v), Number(arg0));
|
|
1667
1771
|
return r;
|
|
@@ -1759,20 +1863,40 @@ const _length = async (arg0) => {
|
|
|
1759
1863
|
}
|
|
1760
1864
|
return 0;
|
|
1761
1865
|
};
|
|
1762
|
-
const _and = async (...args)
|
|
1866
|
+
const _and = makeFunCityFunction(async function(...args) {
|
|
1763
1867
|
if (args.length === 0) {
|
|
1764
|
-
|
|
1868
|
+
this.appendError({
|
|
1869
|
+
type: "error",
|
|
1870
|
+
description: "empty arguments",
|
|
1871
|
+
range: this.thisNode.range
|
|
1872
|
+
});
|
|
1873
|
+
return void 0;
|
|
1765
1874
|
}
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1875
|
+
for (const arg of args) {
|
|
1876
|
+
const value = await this.reduce(arg);
|
|
1877
|
+
if (!isConditionalTrue(value)) {
|
|
1878
|
+
return false;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
return true;
|
|
1882
|
+
});
|
|
1883
|
+
const _or = makeFunCityFunction(async function(...args) {
|
|
1770
1884
|
if (args.length === 0) {
|
|
1771
|
-
|
|
1885
|
+
this.appendError({
|
|
1886
|
+
type: "error",
|
|
1887
|
+
description: "empty arguments",
|
|
1888
|
+
range: this.thisNode.range
|
|
1889
|
+
});
|
|
1890
|
+
return void 0;
|
|
1772
1891
|
}
|
|
1773
|
-
const
|
|
1774
|
-
|
|
1775
|
-
|
|
1892
|
+
for (const arg of args) {
|
|
1893
|
+
const value = await this.reduce(arg);
|
|
1894
|
+
if (isConditionalTrue(value)) {
|
|
1895
|
+
return true;
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
return false;
|
|
1899
|
+
});
|
|
1776
1900
|
const _not = async (arg0) => {
|
|
1777
1901
|
return !isConditionalTrue(arg0);
|
|
1778
1902
|
};
|
|
@@ -1934,13 +2058,24 @@ const _bind = async (arg0, ...args) => {
|
|
|
1934
2058
|
const predicate = arg0;
|
|
1935
2059
|
return predicate.bind(void 0, ...args);
|
|
1936
2060
|
};
|
|
2061
|
+
const _url = async (arg0, arg1) => {
|
|
2062
|
+
const url = new URL(
|
|
2063
|
+
convertToString(arg0),
|
|
2064
|
+
arg1 !== void 0 ? convertToString(arg1) : void 0
|
|
2065
|
+
);
|
|
2066
|
+
return url;
|
|
2067
|
+
};
|
|
1937
2068
|
const standardVariables = Object.freeze({
|
|
1938
2069
|
undefined: void 0,
|
|
1939
2070
|
null: null,
|
|
1940
2071
|
true: true,
|
|
1941
2072
|
false: false,
|
|
1942
2073
|
cond: _cond,
|
|
2074
|
+
set: _set,
|
|
1943
2075
|
toString: _toString,
|
|
2076
|
+
toBoolean: _toBoolean,
|
|
2077
|
+
toNumber: _toNumber,
|
|
2078
|
+
toBigInt: _toBigInt,
|
|
1944
2079
|
typeof: _typeof,
|
|
1945
2080
|
add: _add,
|
|
1946
2081
|
sub: _sub,
|
|
@@ -1972,30 +2107,32 @@ const standardVariables = Object.freeze({
|
|
|
1972
2107
|
match: _match,
|
|
1973
2108
|
replace: _replace,
|
|
1974
2109
|
regex: _regex,
|
|
1975
|
-
bind: _bind
|
|
2110
|
+
bind: _bind,
|
|
2111
|
+
url: _url
|
|
1976
2112
|
});
|
|
1977
2113
|
const buildCandidateVariables = (...variablesList) => {
|
|
1978
2114
|
return combineVariables(standardVariables, ...variablesList);
|
|
1979
2115
|
};
|
|
1980
|
-
const runScriptOnce = async (script, variables, errors = []) => {
|
|
2116
|
+
const runScriptOnce = async (script, variables, errors = [], signal) => {
|
|
1981
2117
|
const blocks = runTokenizer(script, errors);
|
|
1982
2118
|
const nodes = runParser(blocks, errors);
|
|
1983
|
-
const results = await runReducer(nodes, variables, errors);
|
|
1984
|
-
const text = results.join("");
|
|
2119
|
+
const results = await runReducer(nodes, variables, errors, signal);
|
|
2120
|
+
const text = results.map((result) => convertToString(result)).join("");
|
|
1985
2121
|
return text;
|
|
1986
2122
|
};
|
|
1987
2123
|
export {
|
|
1988
2124
|
asIterable,
|
|
1989
2125
|
buildCandidateVariables,
|
|
1990
2126
|
combineVariables,
|
|
2127
|
+
convertToString,
|
|
1991
2128
|
createParserCursor,
|
|
1992
2129
|
createReducerContext,
|
|
1993
2130
|
emptyLocation,
|
|
1994
2131
|
emptyRange,
|
|
1995
2132
|
fromError,
|
|
1996
2133
|
isConditionalTrue,
|
|
1997
|
-
|
|
1998
|
-
|
|
2134
|
+
isFunCityFunction,
|
|
2135
|
+
makeFunCityFunction,
|
|
1999
2136
|
outputErrors,
|
|
2000
2137
|
parseBlock,
|
|
2001
2138
|
parseExpression,
|