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