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 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 = context.cursor.getUntil("'");
7
- if (value !== void 0) {
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
- } else {
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
- if (isSpecialFunction(func)) {
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 createReducerContext = (variables, errors) => {
1514
- let vs = variables;
1515
- let mvs;
1516
- let variablesProxy;
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
- if (vs.has(name)) {
1519
- return { value: vs.get(name), isFound: true };
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
- if (!mvs) {
1526
- mvs = new Map(vs);
1527
- vs = mvs;
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
- return {
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: reduceByProxy
1660
+ reduce: (node) => {
1661
+ signal == null ? void 0 : signal.throwIfAborted();
1662
+ return reduceExpressionNode(thisContext, node);
1663
+ }
1573
1664
  };
1665
+ return newContext;
1574
1666
  };
1575
- context = {
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 context;
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 = makeSpecialFunction(async function(arg0, arg1, arg2) {
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
- throw new Error("empty arguments");
1870
+ this.appendError({
1871
+ type: "error",
1872
+ description: "empty arguments",
1873
+ range: this.thisNode.range
1874
+ });
1875
+ return void 0;
1767
1876
  }
1768
- const r = args.reduce((v0, v) => v0 && isConditionalTrue(v), true);
1769
- return r;
1770
- };
1771
- const _or = async (...args) => {
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
- throw new Error("empty arguments");
1887
+ this.appendError({
1888
+ type: "error",
1889
+ description: "empty arguments",
1890
+ range: this.thisNode.range
1891
+ });
1892
+ return void 0;
1774
1893
  }
1775
- const r = args.reduce((v0, v) => v0 || isConditionalTrue(v), false);
1776
- return r;
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.isSpecialFunction = isSpecialFunction;
1999
- exports.makeSpecialFunction = makeSpecialFunction;
2135
+ exports.isFunCityFunction = isFunCityFunction;
2136
+ exports.makeFunCityFunction = makeFunCityFunction;
2000
2137
  exports.outputErrors = outputErrors;
2001
2138
  exports.parseBlock = parseBlock;
2002
2139
  exports.parseExpression = parseExpression;