funcity 1.3.0 → 1.5.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.
Files changed (43) hide show
  1. package/dist/compile-cache-D9XyNhoC.cjs +4869 -0
  2. package/dist/compile-cache-D9XyNhoC.cjs.map +1 -0
  3. package/dist/compile-cache-uzGiV-kt.js +4713 -0
  4. package/dist/compile-cache-uzGiV-kt.js.map +1 -0
  5. package/dist/index.cjs +155 -3374
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.mjs +129 -3379
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/node.cjs +160 -147
  10. package/dist/node.cjs.map +1 -1
  11. package/dist/node.mjs +121 -127
  12. package/dist/node.mjs.map +1 -1
  13. package/dist/src/compile-cache.d.ts +61 -0
  14. package/dist/src/compile-cache.d.ts.map +1 -0
  15. package/dist/src/dcodegen.d.ts +131 -0
  16. package/dist/src/dcodegen.d.ts.map +1 -0
  17. package/dist/src/index.d.ts +22 -0
  18. package/dist/src/index.d.ts.map +1 -0
  19. package/dist/src/node.d.ts +12 -0
  20. package/dist/src/node.d.ts.map +1 -0
  21. package/dist/src/parser.d.ts +46 -0
  22. package/dist/src/parser.d.ts.map +1 -0
  23. package/dist/src/reducer.d.ts +43 -0
  24. package/dist/src/reducer.d.ts.map +1 -0
  25. package/dist/src/scripting.d.ts +28 -0
  26. package/dist/src/scripting.d.ts.map +1 -0
  27. package/dist/src/tokenizer.d.ts +28 -0
  28. package/dist/src/tokenizer.d.ts.map +1 -0
  29. package/dist/src/types.d.ts +754 -0
  30. package/dist/src/types.d.ts.map +1 -0
  31. package/dist/src/utils.d.ts +86 -0
  32. package/dist/src/utils.d.ts.map +1 -0
  33. package/dist/src/variables/fetch-variables.d.ts +26 -0
  34. package/dist/src/variables/fetch-variables.d.ts.map +1 -0
  35. package/dist/src/variables/nodejs-variables.d.ts +26 -0
  36. package/dist/src/variables/nodejs-variables.d.ts.map +1 -0
  37. package/dist/src/variables/object-variables.d.ts +37 -0
  38. package/dist/src/variables/object-variables.d.ts.map +1 -0
  39. package/dist/src/variables/standard-variables.d.ts +122 -0
  40. package/dist/src/variables/standard-variables.d.ts.map +1 -0
  41. package/package.json +12 -11
  42. package/dist/index.d.ts +0 -987
  43. package/dist/node.d.ts +0 -447
@@ -0,0 +1,4869 @@
1
+ /*!
2
+ * name: funcity
3
+ * version: 1.5.0
4
+ * description: A functional language interpreter with text processing
5
+ * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
+ * license: MIT
7
+ * repository.url: https://github.com/kekyo/funcity
8
+ * git.commit.hash: e583c1a43f3a2b29f8bbbb7b7ad0cc199b0a0fca
9
+ */
10
+
11
+ /*!
12
+ * name: funcity
13
+ * version: 1.5.0
14
+ * description: A functional language interpreter with text processing
15
+ * author: Kouji Matsui (@kekyo@mi.kekyo.net)
16
+ * license: MIT
17
+ * repository.url: https://github.com/kekyo/funcity
18
+ * git.commit.hash: e583c1a43f3a2b29f8bbbb7b7ad0cc199b0a0fca
19
+ */
20
+ const require_node = require("./node.cjs");
21
+ //#region \0@oxc-project+runtime@0.121.0/helpers/typeof.js
22
+ function _typeof$1(o) {
23
+ "@babel/helpers - typeof";
24
+ return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
25
+ return typeof o;
26
+ } : function(o) {
27
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
28
+ }, _typeof$1(o);
29
+ }
30
+ //#endregion
31
+ //#region \0@oxc-project+runtime@0.121.0/helpers/toPrimitive.js
32
+ function toPrimitive(t, r) {
33
+ if ("object" != _typeof$1(t) || !t) return t;
34
+ var e = t[Symbol.toPrimitive];
35
+ if (void 0 !== e) {
36
+ var i = e.call(t, r || "default");
37
+ if ("object" != _typeof$1(i)) return i;
38
+ throw new TypeError("@@toPrimitive must return a primitive value.");
39
+ }
40
+ return ("string" === r ? String : Number)(t);
41
+ }
42
+ //#endregion
43
+ //#region \0@oxc-project+runtime@0.121.0/helpers/toPropertyKey.js
44
+ function toPropertyKey(t) {
45
+ var i = toPrimitive(t, "string");
46
+ return "symbol" == _typeof$1(i) ? i : i + "";
47
+ }
48
+ //#endregion
49
+ //#region \0@oxc-project+runtime@0.121.0/helpers/defineProperty.js
50
+ function _defineProperty(e, r, t) {
51
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
52
+ value: t,
53
+ enumerable: !0,
54
+ configurable: !0,
55
+ writable: !0
56
+ }) : e[r] = t, e;
57
+ }
58
+ //#endregion
59
+ //#region src/types.ts
60
+ /**
61
+ * Reducer running error.
62
+ */
63
+ var FunCityReducerError = class FunCityReducerError extends Error {
64
+ constructor(info) {
65
+ super(info.description);
66
+ _defineProperty(
67
+ this,
68
+ /**
69
+ * Error information.
70
+ */
71
+ "info",
72
+ void 0
73
+ );
74
+ this.name = "FunCityReducerError";
75
+ this.info = info;
76
+ Object.setPrototypeOf(this, FunCityReducerError.prototype);
77
+ }
78
+ };
79
+ //#endregion
80
+ //#region src/tokenizer.ts
81
+ var createRange = (context, start, end) => ({
82
+ sourceId: context.sourceId,
83
+ start,
84
+ end
85
+ });
86
+ /**
87
+ * Tokenize the string value.
88
+ * @param context Tokenizer context
89
+ * @returns String token
90
+ */
91
+ var stringEscapeMap = {
92
+ f: "\f",
93
+ n: "\n",
94
+ r: "\r",
95
+ t: " ",
96
+ v: "\v",
97
+ "0": "\0",
98
+ "'": "'",
99
+ "\"": "\"",
100
+ "`": "`",
101
+ "{": "{",
102
+ "}": "}",
103
+ "\\": "\\"
104
+ };
105
+ var tokenizeString = (context, quoteSymbol) => {
106
+ const start = context.cursor.location("start");
107
+ context.cursor.skip(quoteSymbol.length);
108
+ let value = "";
109
+ let templateTokens;
110
+ let textStart;
111
+ const appendText = (text, startLocation) => {
112
+ if (value.length === 0) textStart = startLocation !== null && startLocation !== void 0 ? startLocation : context.cursor.location("start");
113
+ value += text;
114
+ };
115
+ const flushTextToken = () => {
116
+ if (!templateTokens || value.length === 0 || !textStart) return;
117
+ templateTokens.push({
118
+ kind: "text",
119
+ text: value,
120
+ range: createRange(context, textStart, context.cursor.location("end"))
121
+ });
122
+ value = "";
123
+ textStart = void 0;
124
+ };
125
+ let closed = false;
126
+ while (!context.cursor.eot()) {
127
+ if (context.cursor.assert(quoteSymbol)) {
128
+ if (templateTokens) flushTextToken();
129
+ context.cursor.skip(quoteSymbol.length);
130
+ closed = true;
131
+ break;
132
+ }
133
+ if (context.cursor.assert("{{")) {
134
+ if (!templateTokens) templateTokens = [];
135
+ flushTextToken();
136
+ const tokens = tokenizeCodeBlock(context);
137
+ templateTokens.push(...tokens);
138
+ continue;
139
+ }
140
+ const ch = context.cursor.getChar();
141
+ if (ch === "\\") {
142
+ const escapeStart = context.cursor.location("start");
143
+ context.cursor.skip(1);
144
+ if (context.cursor.eot()) {
145
+ context.logs.push({
146
+ type: "error",
147
+ description: "invalid escape sequence: \\\\",
148
+ range: createRange(context, escapeStart, context.cursor.location("end"))
149
+ });
150
+ appendText("\\", escapeStart);
151
+ break;
152
+ }
153
+ const escape = context.cursor.getChar();
154
+ const mapped = stringEscapeMap[escape];
155
+ if (mapped !== void 0) {
156
+ appendText(mapped, escapeStart);
157
+ context.cursor.skip(1);
158
+ continue;
159
+ }
160
+ context.cursor.skip(1);
161
+ context.logs.push({
162
+ type: "error",
163
+ description: `invalid escape sequence: \\${escape}`,
164
+ range: createRange(context, escapeStart, context.cursor.location("end"))
165
+ });
166
+ appendText(`\\${escape}`, escapeStart);
167
+ continue;
168
+ }
169
+ appendText(ch);
170
+ context.cursor.skip(1);
171
+ }
172
+ if (!closed) {
173
+ const location = context.cursor.location("start");
174
+ context.logs.push({
175
+ type: "error",
176
+ description: "string close quote is not found",
177
+ range: createRange(context, location, location)
178
+ });
179
+ }
180
+ if (templateTokens) {
181
+ flushTextToken();
182
+ return {
183
+ kind: "template",
184
+ tokens: templateTokens,
185
+ range: createRange(context, start, context.cursor.location("end"))
186
+ };
187
+ }
188
+ return {
189
+ kind: "string",
190
+ value,
191
+ range: createRange(context, start, context.cursor.location("end"))
192
+ };
193
+ };
194
+ var firstNumericChars = "0123456789-+";
195
+ var numericCharsWithDot = "0123456789.";
196
+ var numericChars = "0123456789";
197
+ /**
198
+ * Tokenize the number (numeric) value.
199
+ * @param context Tokenizer context
200
+ * @returns Number token
201
+ */
202
+ var tokenizeNumber = (context) => {
203
+ const start = context.cursor.location("start");
204
+ let index = 1;
205
+ while (true) {
206
+ if (context.cursor.eot()) return {
207
+ kind: "number",
208
+ value: Number(context.cursor.getRangeAndSkip(index)),
209
+ range: createRange(context, start, context.cursor.location("end"))
210
+ };
211
+ const ch = context.cursor.getChar(index);
212
+ if (numericCharsWithDot.indexOf(ch) < 0) {
213
+ if (ch === ".") break;
214
+ return {
215
+ kind: "number",
216
+ value: Number(context.cursor.getRangeAndSkip(index)),
217
+ range: createRange(context, start, context.cursor.location("end"))
218
+ };
219
+ }
220
+ index++;
221
+ }
222
+ while (true) {
223
+ if (context.cursor.eot()) return {
224
+ kind: "number",
225
+ value: Number(context.cursor.getRangeAndSkip(index)),
226
+ range: createRange(context, start, context.cursor.location("end"))
227
+ };
228
+ const ch = context.cursor.getChar(index);
229
+ if (numericChars.indexOf(ch) < 0) return {
230
+ kind: "number",
231
+ value: Number(context.cursor.getRangeAndSkip(index)),
232
+ range: createRange(context, start, context.cursor.location("end"))
233
+ };
234
+ index++;
235
+ }
236
+ };
237
+ var firstVariableChars = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
238
+ var variableChars = "_-?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
239
+ /**
240
+ * Tokenize the identity (variable name).
241
+ * @param context Tokenizer context
242
+ * @returns Identity token
243
+ */
244
+ var tokenizeIdentity = (context) => {
245
+ const start = context.cursor.location("start");
246
+ let index = 1;
247
+ while (true) {
248
+ if (context.cursor.eot()) break;
249
+ const ch = context.cursor.getChar(index);
250
+ if (variableChars.indexOf(ch) < 0) break;
251
+ if (ch === "?") {
252
+ if (context.cursor.getChar(index + 1) === ".") break;
253
+ index++;
254
+ break;
255
+ }
256
+ index++;
257
+ }
258
+ return {
259
+ kind: "identity",
260
+ name: context.cursor.getRangeAndSkip(index),
261
+ range: createRange(context, start, context.cursor.location("end"))
262
+ };
263
+ };
264
+ var tokenizeCodeTokens = (context, stopOnClose, finalizeUnknownOnEot, closeSymbol = "}}") => {
265
+ const tokens = [];
266
+ let unknownStartLocation;
267
+ const finalizeUnknown = () => {
268
+ if (unknownStartLocation) {
269
+ context.logs.push({
270
+ type: "warning",
271
+ description: "unknown words",
272
+ range: createRange(context, unknownStartLocation, context.cursor.location("end"))
273
+ });
274
+ unknownStartLocation = void 0;
275
+ }
276
+ };
277
+ while (!context.cursor.eot()) {
278
+ if (stopOnClose && context.cursor.assert(closeSymbol)) {
279
+ finalizeUnknown();
280
+ return {
281
+ tokens,
282
+ closed: true
283
+ };
284
+ }
285
+ const ch = context.cursor.getChar();
286
+ if (ch === "\\") {
287
+ const next = context.cursor.getChar(1);
288
+ if (next === "\n") {
289
+ context.cursor.skip(2);
290
+ continue;
291
+ }
292
+ if (next === "\r" && context.cursor.getChar(2) === "\n") {
293
+ context.cursor.skip(3);
294
+ continue;
295
+ }
296
+ if (next === "{" || next === "}") {
297
+ context.cursor.skip(2);
298
+ continue;
299
+ }
300
+ }
301
+ if (ch === "/" && context.cursor.getChar(1) === "/") {
302
+ finalizeUnknown();
303
+ context.cursor.skip(2);
304
+ while (!context.cursor.eot()) {
305
+ const commentCh = context.cursor.getChar();
306
+ if (commentCh === "\n" || commentCh === "\r") break;
307
+ context.cursor.skip(1);
308
+ }
309
+ continue;
310
+ }
311
+ if (ch === "'" || ch === "\"" || ch === "`") {
312
+ finalizeUnknown();
313
+ let quoteCount = 1;
314
+ while (context.cursor.getChar(quoteCount) === ch) quoteCount++;
315
+ const quoteLength = quoteCount >= 3 ? quoteCount : 1;
316
+ tokens.push(tokenizeString(context, ch.repeat(quoteLength)));
317
+ } else if (firstNumericChars.indexOf(ch) >= 0) {
318
+ finalizeUnknown();
319
+ tokens.push(tokenizeNumber(context));
320
+ } else if (ch === "(") {
321
+ finalizeUnknown();
322
+ const location = context.cursor.location("start");
323
+ tokens.push({
324
+ kind: "open",
325
+ symbol: "(",
326
+ range: createRange(context, location, location)
327
+ });
328
+ context.cursor.skip(1);
329
+ } else if (ch === ")") {
330
+ finalizeUnknown();
331
+ const location = context.cursor.location("start");
332
+ tokens.push({
333
+ kind: "close",
334
+ symbol: ")",
335
+ range: createRange(context, location, location)
336
+ });
337
+ context.cursor.skip(1);
338
+ } else if (ch === "[") {
339
+ finalizeUnknown();
340
+ const location = context.cursor.location("start");
341
+ tokens.push({
342
+ kind: "open",
343
+ symbol: "[",
344
+ range: createRange(context, location, location)
345
+ });
346
+ context.cursor.skip(1);
347
+ } else if (ch === "]") {
348
+ finalizeUnknown();
349
+ const location = context.cursor.location("start");
350
+ tokens.push({
351
+ kind: "close",
352
+ symbol: "]",
353
+ range: createRange(context, location, location)
354
+ });
355
+ context.cursor.skip(1);
356
+ } else if (ch === "?" && context.cursor.getChar(1) === ".") {
357
+ finalizeUnknown();
358
+ const start = context.cursor.location("start");
359
+ context.cursor.skip(2);
360
+ tokens.push({
361
+ kind: "dot",
362
+ optional: true,
363
+ range: createRange(context, start, context.cursor.location("end"))
364
+ });
365
+ } else if (ch === ".") {
366
+ finalizeUnknown();
367
+ const location = context.cursor.location("start");
368
+ tokens.push({
369
+ kind: "dot",
370
+ optional: false,
371
+ range: createRange(context, location, location)
372
+ });
373
+ context.cursor.skip(1);
374
+ } else if (firstVariableChars.indexOf(ch) >= 0) {
375
+ finalizeUnknown();
376
+ tokens.push(tokenizeIdentity(context));
377
+ } else if (ch === "\n") {
378
+ finalizeUnknown();
379
+ const location = context.cursor.location("start");
380
+ tokens.push({
381
+ kind: "eol",
382
+ source: "newline",
383
+ range: createRange(context, location, location)
384
+ });
385
+ context.cursor.skip(1);
386
+ } else if (ch === ";") {
387
+ finalizeUnknown();
388
+ const location = context.cursor.location("start");
389
+ tokens.push({
390
+ kind: "eol",
391
+ source: "semicolon",
392
+ range: createRange(context, location, location)
393
+ });
394
+ context.cursor.skip(1);
395
+ } else if (ch === "\r") {
396
+ finalizeUnknown();
397
+ context.cursor.skip(1);
398
+ } else if (ch === " ") {
399
+ finalizeUnknown();
400
+ context.cursor.skip(1);
401
+ } else {
402
+ if (!unknownStartLocation) unknownStartLocation = context.cursor.location("start");
403
+ context.cursor.skip(1);
404
+ }
405
+ context.cursor.skipChars(" ");
406
+ }
407
+ if (finalizeUnknownOnEot) finalizeUnknown();
408
+ return {
409
+ tokens,
410
+ closed: false
411
+ };
412
+ };
413
+ /**
414
+ * Tokenize code block.
415
+ * @param context Tokenizer context
416
+ * @returns The token list
417
+ */
418
+ var tokenizeCodeBlock = (context) => {
419
+ const openStart = context.cursor.location("start");
420
+ let openCount = 0;
421
+ while (context.cursor.getChar(openCount) === "{") openCount++;
422
+ const openSymbol = "{".repeat(openCount);
423
+ const closeSymbol = "}".repeat(openCount);
424
+ context.cursor.skip(openCount);
425
+ const tokens = [{
426
+ kind: "open",
427
+ symbol: openSymbol,
428
+ range: createRange(context, openStart, context.cursor.location("end"))
429
+ }];
430
+ const result = tokenizeCodeTokens(context, true, false, closeSymbol);
431
+ tokens.push(...result.tokens);
432
+ if (result.closed) {
433
+ const location = context.cursor.location("start");
434
+ context.cursor.skip(openCount);
435
+ tokens.push({
436
+ kind: "close",
437
+ symbol: closeSymbol,
438
+ range: createRange(context, location, context.cursor.location("end"))
439
+ });
440
+ return tokens;
441
+ }
442
+ const causeLocation = context.cursor.location("start");
443
+ context.logs.push({
444
+ type: "error",
445
+ description: `required code block closer: \`${closeSymbol}\``,
446
+ range: createRange(context, causeLocation, causeLocation)
447
+ });
448
+ return tokens;
449
+ };
450
+ /**
451
+ * Create a tonenizer cursor.
452
+ * @param script - Input script text
453
+ * @returns Tonenizer cursor
454
+ */
455
+ var createTokenizerCursor = (script) => {
456
+ let currentIndex = 0;
457
+ let rawLine = 0;
458
+ let rawColumn = 0;
459
+ let lastLine = 0;
460
+ let lastColumn = 0;
461
+ const eot = () => currentIndex >= script.length;
462
+ const getChar = (index) => script[(index !== null && index !== void 0 ? index : 0) + currentIndex];
463
+ const skip = (length) => {
464
+ let lastch = "\0";
465
+ while (length > 0) {
466
+ lastColumn = rawColumn;
467
+ lastLine = rawLine;
468
+ const ch = script[currentIndex];
469
+ if (ch === "\r") {
470
+ rawColumn = 0;
471
+ rawLine++;
472
+ } else if (ch === "\n") {
473
+ rawColumn = 0;
474
+ if (lastch !== "\r") rawLine++;
475
+ } else rawColumn++;
476
+ currentIndex++;
477
+ length--;
478
+ lastch = ch;
479
+ }
480
+ };
481
+ const skipChars = (ch) => {
482
+ while (!eot()) {
483
+ if (getChar() !== ch) return true;
484
+ skip(1);
485
+ }
486
+ return false;
487
+ };
488
+ const skipUntil = (word) => {
489
+ while (!eot()) {
490
+ if (script.indexOf(word, currentIndex) === currentIndex) {
491
+ skip(word.length);
492
+ return true;
493
+ }
494
+ skip(1);
495
+ }
496
+ return false;
497
+ };
498
+ const assert = (word) => {
499
+ if (script.length - currentIndex < word.length) return false;
500
+ if (script.substring(currentIndex, currentIndex + word.length) === word) return true;
501
+ return false;
502
+ };
503
+ const getRangeAndSkip = (length) => {
504
+ const result = script.substring(currentIndex, currentIndex + length);
505
+ skip(result.length);
506
+ return result;
507
+ };
508
+ const getUntil = (word) => {
509
+ if (currentIndex >= script.length) return;
510
+ const index = script.indexOf(word, currentIndex);
511
+ if (index >= 0) {
512
+ const result = script.substring(currentIndex, index);
513
+ skip(index - currentIndex);
514
+ return result;
515
+ } else {
516
+ const result = script.substring(currentIndex, script.length);
517
+ skip(script.length - currentIndex);
518
+ return result;
519
+ }
520
+ };
521
+ const location = (type) => type === "end" ? {
522
+ line: lastLine + 1,
523
+ column: lastColumn + 1
524
+ } : {
525
+ line: rawLine + 1,
526
+ column: rawColumn + 1
527
+ };
528
+ return {
529
+ eot,
530
+ getChar,
531
+ skip,
532
+ skipChars,
533
+ skipUntil,
534
+ assert,
535
+ getRangeAndSkip,
536
+ getUntil,
537
+ location
538
+ };
539
+ };
540
+ /**
541
+ * Run the tokenizer for code expressions only.
542
+ * @param script - Input script text
543
+ * @param logs - Will be stored detected warnings/logs into it
544
+ * @param sourceId - Source identifier (file path, URL, etc)
545
+ * @returns The token list
546
+ */
547
+ var runCodeTokenizer = (script, logs, sourceId) => {
548
+ return tokenizeCodeTokens({
549
+ cursor: createTokenizerCursor(script),
550
+ sourceId,
551
+ logs
552
+ }, false, true).tokens;
553
+ };
554
+ /**
555
+ * Run the tokenizer.
556
+ * @param script - Input script text
557
+ * @param logs - Will be stored detected warnings/logs into it
558
+ * @param sourceId - Source identifier (file path, URL, etc)
559
+ * @returns The token list
560
+ */
561
+ var runTokenizer = (script, logs, sourceId) => {
562
+ const context = {
563
+ cursor: createTokenizerCursor(script),
564
+ sourceId,
565
+ logs
566
+ };
567
+ const tokens = [];
568
+ const readTextBlock = () => {
569
+ if (context.cursor.eot()) return;
570
+ let text = "";
571
+ while (!context.cursor.eot()) {
572
+ if (context.cursor.assert("{{")) return text;
573
+ const ch = context.cursor.getChar();
574
+ if (ch === "\\") {
575
+ const next = context.cursor.getChar(1);
576
+ if (next === "{" || next === "}") {
577
+ text += next;
578
+ context.cursor.skip(2);
579
+ continue;
580
+ }
581
+ }
582
+ text += ch;
583
+ context.cursor.skip(1);
584
+ }
585
+ return text;
586
+ };
587
+ while (!context.cursor.eot()) {
588
+ const start = context.cursor.location("start");
589
+ const text = readTextBlock();
590
+ if (text) tokens.push({
591
+ kind: "text",
592
+ text,
593
+ range: createRange(context, start, context.cursor.location("end"))
594
+ });
595
+ else tokens.push(...tokenizeCodeBlock(context));
596
+ }
597
+ return tokens;
598
+ };
599
+ //#endregion
600
+ //#region src/utils.ts
601
+ /**
602
+ * Empty location with zeroed coordinates.
603
+ */
604
+ var emptyLocation = {
605
+ line: 0,
606
+ column: 0
607
+ };
608
+ /**
609
+ * Empty range with zeroed coordinates.
610
+ */
611
+ var emptyRange = {
612
+ sourceId: "unknown.fc",
613
+ start: emptyLocation,
614
+ end: emptyLocation
615
+ };
616
+ var specialFunctionMarker = Symbol("$$special$$");
617
+ /**
618
+ * Mark a function as a funcity special function.
619
+ * @param f - Target function.
620
+ * @returns The same function with a marker.
621
+ */
622
+ var makeFunCityFunction = (f) => {
623
+ f[specialFunctionMarker] = true;
624
+ return f;
625
+ };
626
+ /**
627
+ * Check whether a function is marked as funcity special function.
628
+ * @param f - Target function.
629
+ * @returns True when marked.
630
+ */
631
+ var isFunCityFunction = (f) => {
632
+ var _f$specialFunctionMar;
633
+ return (_f$specialFunctionMar = f[specialFunctionMarker]) !== null && _f$specialFunctionMar !== void 0 ? _f$specialFunctionMar : false;
634
+ };
635
+ /**
636
+ * Evaluate value with the interpreter's conditional semantics.
637
+ * @param v - Target value.
638
+ * @returns True when the value should be treated as truthy.
639
+ */
640
+ var isConditionalTrue = (v) => {
641
+ if (v === void 0 || v === null) return false;
642
+ switch (typeof v) {
643
+ case "boolean": return v;
644
+ case "number":
645
+ case "bigint": return v !== 0;
646
+ default: return true;
647
+ }
648
+ };
649
+ /**
650
+ * Cast a value to iterable when it has a default iterator.
651
+ * @param v - Target value.
652
+ * @returns Iterable instance or undefined when not iterable.
653
+ */
654
+ var asIterable = (v) => {
655
+ if (typeof v[Symbol.iterator] === "function") return v;
656
+ else return;
657
+ };
658
+ /**
659
+ * Combine variable maps or records into a single variable map.
660
+ * @param variablesList - Variable sources to merge.
661
+ * @returns Combined variable map.
662
+ */
663
+ var combineVariables = (...variablesList) => {
664
+ const variables = /* @__PURE__ */ new Map();
665
+ const appendVariables = (vs) => vs.forEach((v, k) => variables.set(k, v));
666
+ const appendRecord = (vs) => Object.keys(vs).forEach((k) => variables.set(k, vs[k]));
667
+ variablesList.forEach((vs) => {
668
+ if (vs["forEach"] !== void 0) appendVariables(vs);
669
+ else appendRecord(vs);
670
+ });
671
+ return variables;
672
+ };
673
+ /**
674
+ * Convert an error object into a human-readable message.
675
+ * @param error - Error object.
676
+ * @returns Error message.
677
+ */
678
+ var fromError = (error) => {
679
+ if (error.message) return error.message;
680
+ else if (typeof error.toString === "function") {
681
+ var _error$toString;
682
+ return (_error$toString = error.toString()) !== null && _error$toString !== void 0 ? _error$toString : "unknown";
683
+ } else return "unknown";
684
+ };
685
+ /**
686
+ * Check whether a value is promise-like.
687
+ * @param value - Target value.
688
+ * @returns True when the value has a `then` method.
689
+ */
690
+ var isPromiseLike = (value) => {
691
+ if (value === null || value === void 0) return false;
692
+ return typeof value.then === "function";
693
+ };
694
+ var widerRange = (...args) => {
695
+ var _primarySourceId;
696
+ const lastArg = args[args.length - 1];
697
+ const logs = Array.isArray(lastArg) ? lastArg : void 0;
698
+ const ranges = Array.isArray(lastArg) ? args.slice(0, -1) : args;
699
+ let start = emptyRange.start;
700
+ let end = emptyRange.end;
701
+ let primarySourceId;
702
+ const sourceIds = /* @__PURE__ */ new Set();
703
+ for (const range of ranges) if (range.start.line >= 1 && range.start.column >= 1) {
704
+ if (!primarySourceId) primarySourceId = range.sourceId;
705
+ sourceIds.add(range.sourceId);
706
+ if (start.line === 0 || start.column === 0) start = range.start;
707
+ else if (range.start.line < start.line) start = range.start;
708
+ else if (range.start.line === start.line && range.start.column < start.column) start = range.start;
709
+ if (end.line === 0 || end.column === 0) end = range.end;
710
+ else if (range.end.line > end.line) end = range.end;
711
+ else if (range.end.line === end.line && range.end.column > end.column) end = range.end;
712
+ }
713
+ const combinedRange = {
714
+ sourceId: (_primarySourceId = primarySourceId) !== null && _primarySourceId !== void 0 ? _primarySourceId : emptyRange.sourceId,
715
+ start,
716
+ end
717
+ };
718
+ if (sourceIds.size >= 2 && logs) logs.push({
719
+ type: "error",
720
+ description: "Range sourceId mismatch",
721
+ range: combinedRange
722
+ });
723
+ return combinedRange;
724
+ };
725
+ var locationEquals = (lhs, rhs) => lhs.line === rhs.line && lhs.column === rhs.column;
726
+ var 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}`;
727
+ var printErrorString = (error, writer) => {
728
+ const sourceId = error.range.sourceId;
729
+ switch (error.type) {
730
+ case "warning":
731
+ writer.warn(`${sourceId}:${getLocationString(error.range)}: warning: ${error.description}`);
732
+ break;
733
+ case "error":
734
+ writer.error(`${sourceId}:${getLocationString(error.range)}: error: ${error.description}`);
735
+ return true;
736
+ }
737
+ return false;
738
+ };
739
+ /**
740
+ * Output error list and return whether any error-level entry exists.
741
+ * @param logs - Errors to output.
742
+ * @param writer - Writer interface.
743
+ * @returns True when an error-level entry exists.
744
+ */
745
+ var outputErrors = (logs, writer) => {
746
+ const _writer = writer !== null && writer !== void 0 ? writer : console;
747
+ let isError = false;
748
+ for (const error of logs) {
749
+ const result = printErrorString(error, _writer);
750
+ isError || (isError = result);
751
+ }
752
+ return isError;
753
+ };
754
+ var iterToString = (iter, getFuncId) => {
755
+ const strs = [];
756
+ for (const item of iter) {
757
+ const str = internalConvertToString(item, getFuncId);
758
+ strs.push(str);
759
+ }
760
+ return `[${strs.join(" ")}]`;
761
+ };
762
+ var internalConvertToString = (v, getFuncId) => {
763
+ switch (v) {
764
+ case void 0: return "(undefined)";
765
+ case null: return "(null)";
766
+ default: switch (typeof v) {
767
+ case "string": return v;
768
+ case "boolean": return v ? "true" : "false";
769
+ case "number":
770
+ case "bigint":
771
+ case "symbol": return v.toString();
772
+ case "function": if (v.name) return `fun<${v.name}:#${getFuncId(v)}>`;
773
+ else return `fun<#${getFuncId(v)}>`;
774
+ default:
775
+ if (Array.isArray(v)) return iterToString(v, getFuncId);
776
+ const iterable = asIterable(v);
777
+ if (iterable) return iterToString(iterable, getFuncId);
778
+ else if (v instanceof Date) return v.toISOString();
779
+ else if (v instanceof Error) return `${v.name}: ${v.message}`;
780
+ else if (v instanceof URL) return v.origin;
781
+ else return JSON.stringify(v);
782
+ }
783
+ }
784
+ };
785
+ var internalCreateFunctionIdGenerator = () => {
786
+ const funcIds = /* @__PURE__ */ new WeakMap();
787
+ let nextId = 1;
788
+ const getFuncId = (fn) => {
789
+ const cached = funcIds.get(fn);
790
+ if (cached) return cached;
791
+ const id = nextId++;
792
+ funcIds.set(fn, id);
793
+ return id;
794
+ };
795
+ return getFuncId;
796
+ };
797
+ var getGlobalFuncId = internalCreateFunctionIdGenerator();
798
+ /**
799
+ * Convert to string.
800
+ * @param v Target instance
801
+ * @returns String
802
+ */
803
+ var convertToString = (v) => internalConvertToString(v, getGlobalFuncId);
804
+ //#endregion
805
+ //#region src/parser.ts
806
+ var parseNumber = (cursor, _errors) => {
807
+ const token = cursor.takeToken();
808
+ return {
809
+ kind: "number",
810
+ value: token.value,
811
+ range: token.range
812
+ };
813
+ };
814
+ var parseString = (cursor, _errors) => {
815
+ const token = cursor.takeToken();
816
+ return {
817
+ kind: "string",
818
+ value: token.value,
819
+ range: token.range
820
+ };
821
+ };
822
+ var parseTemplate = (cursor, logs) => {
823
+ const token = cursor.takeToken();
824
+ return {
825
+ kind: "template",
826
+ blocks: parseBlockCore(createParserCursor(token.tokens), logs, "script"),
827
+ range: token.range
828
+ };
829
+ };
830
+ var parseIdentity = (cursor, _errors) => {
831
+ const token = cursor.takeToken();
832
+ return {
833
+ kind: "variable",
834
+ name: token.name,
835
+ range: token.range
836
+ };
837
+ };
838
+ var unitKind = "'()'";
839
+ var combineIntoScopeMultipleExpressions = (expressionList, logs, ...outerRanges) => {
840
+ switch (expressionList.length) {
841
+ case 0: return;
842
+ case 1: return expressionList[0];
843
+ default: return {
844
+ kind: "scope",
845
+ nodes: expressionList,
846
+ range: widerRange(...expressionList.map((node) => node.range), ...outerRanges, logs)
847
+ };
848
+ }
849
+ };
850
+ var parseDotChain = (cursor, logs, baseNode) => {
851
+ const segments = [];
852
+ const ranges = [baseNode.range];
853
+ while (true) {
854
+ const dotToken = cursor.peekToken();
855
+ if (!dotToken || dotToken.kind !== "dot") break;
856
+ const actualDotToken = cursor.takeToken();
857
+ ranges.push(actualDotToken.range);
858
+ const nextToken = cursor.peekToken();
859
+ if (!nextToken) {
860
+ logs.push({
861
+ type: "error",
862
+ description: "Could not find member identity after dot",
863
+ range: actualDotToken.range
864
+ });
865
+ break;
866
+ }
867
+ if (nextToken.kind !== "identity") {
868
+ logs.push({
869
+ type: "error",
870
+ description: "Required member identity after dot",
871
+ range: widerRange(actualDotToken.range, nextToken.range, logs)
872
+ });
873
+ break;
874
+ }
875
+ const memberToken = cursor.takeToken();
876
+ segments.push({
877
+ name: memberToken.name,
878
+ optional: actualDotToken.optional,
879
+ range: memberToken.range,
880
+ operatorRange: actualDotToken.range
881
+ });
882
+ ranges.push(memberToken.range);
883
+ }
884
+ if (segments.length === 0) return baseNode;
885
+ return {
886
+ kind: "dot",
887
+ base: baseNode,
888
+ segments,
889
+ range: widerRange(...ranges, logs)
890
+ };
891
+ };
892
+ var parsePartialExpression = (cursor, logs) => {
893
+ const token = cursor.peekToken();
894
+ if (!token) return;
895
+ switch (token.kind) {
896
+ case "number": return parseDotChain(cursor, logs, parseNumber(cursor, logs));
897
+ case "string": return parseDotChain(cursor, logs, parseString(cursor, logs));
898
+ case "template": return parseDotChain(cursor, logs, parseTemplate(cursor, logs));
899
+ case "identity": return parseDotChain(cursor, logs, parseIdentity(cursor, logs));
900
+ case "dot": {
901
+ const dotToken = cursor.takeToken();
902
+ logs.push({
903
+ type: "error",
904
+ description: "Invalid dot at this location",
905
+ range: dotToken.range
906
+ });
907
+ return;
908
+ }
909
+ case "open":
910
+ cursor.skipToken();
911
+ switch (token.symbol) {
912
+ case "(": {
913
+ const innerNodes = parseMultipleApplicationExpressions(cursor, logs);
914
+ const closeToken = cursor.peekToken();
915
+ let range;
916
+ if (!closeToken) {
917
+ range = widerRange(token.range, ...innerNodes.map((node) => node.range), logs);
918
+ logs.push({
919
+ type: "error",
920
+ description: "Could not find close parenthesis",
921
+ range: widerRange(token.range, ...innerNodes.map((node) => node.range), logs)
922
+ });
923
+ } else {
924
+ cursor.skipToken();
925
+ range = widerRange(token.range, ...innerNodes.map((node) => node.range), closeToken.range, logs);
926
+ if (closeToken.kind !== "close" || closeToken.symbol !== ")") logs.push({
927
+ type: "error",
928
+ description: `Mismatched close parenthesis`,
929
+ range
930
+ });
931
+ }
932
+ if (innerNodes.length === 0) return {
933
+ kind: unitKind,
934
+ range
935
+ };
936
+ else {
937
+ const node = combineIntoScopeMultipleExpressions(innerNodes, logs, range);
938
+ return node ? parseDotChain(cursor, logs, node) : node;
939
+ }
940
+ }
941
+ case "[": {
942
+ const itemNodes = parseListExpression(cursor, logs);
943
+ const closeToken = cursor.peekToken();
944
+ let range;
945
+ if (!closeToken) {
946
+ range = widerRange(token.range, ...itemNodes.map((node) => node.range), logs);
947
+ logs.push({
948
+ type: "error",
949
+ description: "Could not find close bracket",
950
+ range
951
+ });
952
+ } else {
953
+ cursor.skipToken();
954
+ range = widerRange(token.range, ...itemNodes.map((node) => node.range), closeToken.range, logs);
955
+ if (closeToken.kind !== "close" || closeToken.symbol !== "]") logs.push({
956
+ type: "error",
957
+ description: `Mismatched close bracket`,
958
+ range
959
+ });
960
+ }
961
+ return parseDotChain(cursor, logs, {
962
+ kind: "list",
963
+ items: itemNodes,
964
+ range
965
+ });
966
+ }
967
+ default:
968
+ logs.push({
969
+ type: "error",
970
+ description: `Invalid open parenthesis/bracket`,
971
+ range: token.range
972
+ });
973
+ return;
974
+ }
975
+ }
976
+ };
977
+ var normalizePartialUnitNode = (node, logs) => {
978
+ if (node.kind === unitKind) {
979
+ logs.push({
980
+ type: "error",
981
+ description: `Invalid ${unitKind} at this location`,
982
+ range: node.range
983
+ });
984
+ return {
985
+ kind: "variable",
986
+ name: "undefined",
987
+ range: node.range
988
+ };
989
+ } else return node;
990
+ };
991
+ var finalizeApplicationException = (partialNodes, logs) => {
992
+ if (partialNodes.length === 0) return;
993
+ if (partialNodes.length === 1) return normalizePartialUnitNode(partialNodes[0], logs);
994
+ const func = partialNodes[0];
995
+ if (func.kind === unitKind) {
996
+ logs.push({
997
+ type: "error",
998
+ description: `Invalid ${unitKind} at this location`,
999
+ range: func.range
1000
+ });
1001
+ return;
1002
+ }
1003
+ const arg0 = partialNodes[1];
1004
+ if (arg0.kind === unitKind) return {
1005
+ kind: "apply",
1006
+ func,
1007
+ args: [],
1008
+ range: widerRange(func.range, arg0.range, logs)
1009
+ };
1010
+ const args = partialNodes.slice(1).map((node) => normalizePartialUnitNode(node, logs));
1011
+ return {
1012
+ kind: "apply",
1013
+ func,
1014
+ args,
1015
+ range: widerRange(func.range, ...args.map((node) => node.range), logs)
1016
+ };
1017
+ };
1018
+ var parseMultipleApplicationExpressions = (cursor, logs) => {
1019
+ const expressionList = [];
1020
+ const partialNodes = [];
1021
+ while (true) {
1022
+ const token = cursor.peekToken();
1023
+ if (!token) break;
1024
+ switch (token.kind) {
1025
+ case "eol": {
1026
+ cursor.skipToken();
1027
+ const expr = finalizeApplicationException(partialNodes, logs);
1028
+ if (expr) expressionList.push(expr);
1029
+ partialNodes.length = 0;
1030
+ continue;
1031
+ }
1032
+ }
1033
+ const partialNode = parsePartialExpression(cursor, logs);
1034
+ if (!partialNode) break;
1035
+ partialNodes.push(partialNode);
1036
+ }
1037
+ const expr = finalizeApplicationException(partialNodes, logs);
1038
+ if (expr) expressionList.push(expr);
1039
+ return expressionList;
1040
+ };
1041
+ var parseListExpression = (cursor, logs) => {
1042
+ const itemNodes = [];
1043
+ while (true) {
1044
+ const token = cursor.peekToken();
1045
+ if (!token) break;
1046
+ switch (token.kind) {
1047
+ case "eol":
1048
+ cursor.skipToken();
1049
+ if (token.source === "semicolon") logs.push({
1050
+ type: "error",
1051
+ description: "Semicolon is not allowed in list expression",
1052
+ range: token.range
1053
+ });
1054
+ continue;
1055
+ }
1056
+ const partialNode = parsePartialExpression(cursor, logs);
1057
+ if (!partialNode) break;
1058
+ itemNodes.push(normalizePartialUnitNode(partialNode, logs));
1059
+ }
1060
+ return itemNodes;
1061
+ };
1062
+ var drainEndOfLineAndPeek = (cursor) => {
1063
+ let token = cursor.peekToken();
1064
+ while (token) {
1065
+ if (token.kind === "eol") cursor.skipToken();
1066
+ else break;
1067
+ token = cursor.peekToken();
1068
+ }
1069
+ return token;
1070
+ };
1071
+ /**
1072
+ * Parse expression in the single line.
1073
+ * @param cursor - Parser cursor
1074
+ * @param logs - Will be stored detected warnings/logs into it
1075
+ * @returns Parsed expression node when available
1076
+ */
1077
+ var parseExpression = (cursor, logs) => {
1078
+ let token = drainEndOfLineAndPeek(cursor);
1079
+ if (!token) return;
1080
+ const partialNodes = [];
1081
+ while (true) {
1082
+ const partialNode = parsePartialExpression(cursor, logs);
1083
+ if (!partialNode) break;
1084
+ partialNodes.push(partialNode);
1085
+ token = cursor.peekToken();
1086
+ if (!token) break;
1087
+ if (token.kind === "eol") {
1088
+ cursor.skipToken();
1089
+ token = cursor.peekToken();
1090
+ break;
1091
+ }
1092
+ }
1093
+ drainEndOfLineAndPeek(cursor);
1094
+ return finalizeApplicationException(partialNodes, logs);
1095
+ };
1096
+ var createBranchState = () => ({
1097
+ blocks: [],
1098
+ exprBuffer: []
1099
+ });
1100
+ var getBranchState = (statementState) => {
1101
+ switch (statementState.kind) {
1102
+ case "root": return statementState.branch;
1103
+ case "if": switch (statementState.currentBlock) {
1104
+ case "then": return statementState.then;
1105
+ case "else": return statementState.else;
1106
+ case "elseif": {
1107
+ var _statementState$curre;
1108
+ const elseIf = statementState.elseIfs[(_statementState$curre = statementState.currentElseIfIndex) !== null && _statementState$curre !== void 0 ? _statementState$curre : -1];
1109
+ return elseIf ? elseIf.then : statementState.else;
1110
+ }
1111
+ }
1112
+ case "while":
1113
+ case "for": return statementState.repeat;
1114
+ }
1115
+ };
1116
+ var flushExpressions = (branch, logs) => {
1117
+ if (branch.exprBuffer.length === 0) return;
1118
+ if (branch.exprBuffer.length === 1) branch.blocks.push(branch.exprBuffer[0]);
1119
+ else branch.blocks.push({
1120
+ kind: "scope",
1121
+ nodes: branch.exprBuffer,
1122
+ range: widerRange(...branch.exprBuffer.map((node) => node.range), logs)
1123
+ });
1124
+ branch.exprBuffer = [];
1125
+ };
1126
+ var flushCurrentBranch = (statementStates, logs) => {
1127
+ const statementState = statementStates[statementStates.length - 1];
1128
+ flushExpressions(getBranchState(statementState), logs);
1129
+ };
1130
+ var flushStatementState = (statementState, logs) => {
1131
+ switch (statementState.kind) {
1132
+ case "root":
1133
+ flushExpressions(statementState.branch, logs);
1134
+ break;
1135
+ case "if":
1136
+ flushExpressions(statementState.then, logs);
1137
+ flushExpressions(statementState.else, logs);
1138
+ statementState.elseIfs.forEach((elseIf) => flushExpressions(elseIf.then, logs));
1139
+ break;
1140
+ case "while":
1141
+ case "for":
1142
+ flushExpressions(statementState.repeat, logs);
1143
+ break;
1144
+ }
1145
+ };
1146
+ var pushExpressionNode = (statementStates, node) => {
1147
+ const statementState = statementStates[statementStates.length - 1];
1148
+ getBranchState(statementState).exprBuffer.push(node);
1149
+ };
1150
+ var pushBlockNode = (statementStates, node, logs) => {
1151
+ const statementState = statementStates[statementStates.length - 1];
1152
+ const branch = getBranchState(statementState);
1153
+ flushExpressions(branch, logs);
1154
+ branch.blocks.push(node);
1155
+ };
1156
+ var pushNode = (statementStates, node, logs) => {
1157
+ switch (node.kind) {
1158
+ case "text":
1159
+ case "if":
1160
+ case "while":
1161
+ case "for":
1162
+ pushBlockNode(statementStates, node, logs);
1163
+ break;
1164
+ default:
1165
+ pushExpressionNode(statementStates, node);
1166
+ break;
1167
+ }
1168
+ };
1169
+ var parseStatementArguments = (cursor, logs) => {
1170
+ const args = [];
1171
+ while (true) {
1172
+ const token = cursor.peekToken();
1173
+ if (!token) break;
1174
+ if (token.kind === "eol") {
1175
+ cursor.skipToken();
1176
+ break;
1177
+ }
1178
+ const partialNode = parsePartialExpression(cursor, logs);
1179
+ if (!partialNode) break;
1180
+ args.push(normalizePartialUnitNode(partialNode, logs));
1181
+ }
1182
+ return args;
1183
+ };
1184
+ var parseBlockCore = (cursor, logs, mode) => {
1185
+ const isRepeatedSymbol = (symbol, ch, minLength) => {
1186
+ if (symbol.length < minLength) return false;
1187
+ for (let index = 0; index < symbol.length; index++) if (symbol[index] !== ch) return false;
1188
+ return true;
1189
+ };
1190
+ const isCodeBlockOpenSymbol = (symbol) => isRepeatedSymbol(symbol, "{", 2);
1191
+ const isCodeBlockCloseSymbol = (symbol) => isRepeatedSymbol(symbol, "}", 2);
1192
+ const rootState = {
1193
+ kind: "root",
1194
+ startRange: emptyRange,
1195
+ branch: createBranchState()
1196
+ };
1197
+ const statementStates = [rootState];
1198
+ const isCodeMode = mode === "code";
1199
+ let isInExpressionBlock = isCodeMode;
1200
+ let expectedCloseSymbol;
1201
+ while (true) {
1202
+ const token = drainEndOfLineAndPeek(cursor);
1203
+ if (!token) break;
1204
+ switch (token.kind) {
1205
+ case "text":
1206
+ cursor.skipToken();
1207
+ if (isInExpressionBlock) {
1208
+ logs.push({
1209
+ type: "error",
1210
+ description: `Already opened expression block (tokenizer bug?)`,
1211
+ range: token.range
1212
+ });
1213
+ break;
1214
+ }
1215
+ pushNode(statementStates, {
1216
+ kind: "text",
1217
+ text: token.text,
1218
+ range: token.range
1219
+ }, logs);
1220
+ break;
1221
+ case "open":
1222
+ if (isCodeBlockOpenSymbol(token.symbol)) {
1223
+ cursor.skipToken();
1224
+ if (!isCodeMode) if (isInExpressionBlock) logs.push({
1225
+ type: "error",
1226
+ description: `Already opened expression block`,
1227
+ range: token.range
1228
+ });
1229
+ else {
1230
+ isInExpressionBlock = true;
1231
+ expectedCloseSymbol = "}".repeat(token.symbol.length);
1232
+ }
1233
+ } else {
1234
+ const node = parseExpression(cursor, logs);
1235
+ if (node) pushNode(statementStates, node, logs);
1236
+ }
1237
+ break;
1238
+ case "close":
1239
+ cursor.skipToken();
1240
+ if (isCodeBlockCloseSymbol(token.symbol) && isCodeMode) {
1241
+ flushCurrentBranch(statementStates, logs);
1242
+ break;
1243
+ }
1244
+ if (!isInExpressionBlock) {
1245
+ logs.push({
1246
+ type: "error",
1247
+ description: `Mismatched close bracket`,
1248
+ range: token.range
1249
+ });
1250
+ break;
1251
+ }
1252
+ if (isCodeMode) {
1253
+ logs.push({
1254
+ type: "error",
1255
+ description: `Mismatched close bracket`,
1256
+ range: token.range
1257
+ });
1258
+ break;
1259
+ }
1260
+ if (!expectedCloseSymbol || token.symbol !== expectedCloseSymbol) {
1261
+ logs.push({
1262
+ type: "error",
1263
+ description: `Mismatched close bracket`,
1264
+ range: token.range
1265
+ });
1266
+ break;
1267
+ }
1268
+ flushCurrentBranch(statementStates, logs);
1269
+ isInExpressionBlock = false;
1270
+ expectedCloseSymbol = void 0;
1271
+ break;
1272
+ case "identity":
1273
+ if (!isInExpressionBlock) {
1274
+ logs.push({
1275
+ type: "error",
1276
+ description: `Invalid identity (tokenizer bug?)`,
1277
+ range: token.range
1278
+ });
1279
+ break;
1280
+ }
1281
+ switch (token.name) {
1282
+ case "if": {
1283
+ cursor.skipToken();
1284
+ const args = parseStatementArguments(cursor, logs);
1285
+ if (args.length !== 1) {
1286
+ logs.push({
1287
+ type: "error",
1288
+ description: "Required `if` condition",
1289
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1290
+ });
1291
+ break;
1292
+ }
1293
+ const conditionNode = args[0];
1294
+ statementStates.push({
1295
+ kind: "if",
1296
+ startRange: token.range,
1297
+ condition: conditionNode,
1298
+ elseIfs: [],
1299
+ then: createBranchState(),
1300
+ else: createBranchState(),
1301
+ currentBlock: "then"
1302
+ });
1303
+ break;
1304
+ }
1305
+ case "else": {
1306
+ cursor.skipToken();
1307
+ const args = parseStatementArguments(cursor, logs);
1308
+ if (args.length !== 0) logs.push({
1309
+ type: "error",
1310
+ description: "Could not take any arguments in `else` statement",
1311
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1312
+ });
1313
+ if (statementStates.length <= 1) {
1314
+ logs.push({
1315
+ type: "error",
1316
+ description: "Cound not find pair of `if` statement",
1317
+ range: token.range
1318
+ });
1319
+ break;
1320
+ }
1321
+ const lastState = statementStates[statementStates.length - 1];
1322
+ if (lastState.kind !== "if") {
1323
+ logs.push({
1324
+ type: "error",
1325
+ description: "Cound not find pair of `if` statement",
1326
+ range: token.range
1327
+ });
1328
+ break;
1329
+ }
1330
+ if (lastState.currentBlock === "else") {
1331
+ logs.push({
1332
+ type: "error",
1333
+ description: "Duplicated `else` statement",
1334
+ range: token.range
1335
+ });
1336
+ break;
1337
+ }
1338
+ flushExpressions(getBranchState(lastState), logs);
1339
+ lastState.currentBlock = "else";
1340
+ lastState.currentElseIfIndex = void 0;
1341
+ break;
1342
+ }
1343
+ case "elseif": {
1344
+ cursor.skipToken();
1345
+ const args = parseStatementArguments(cursor, logs);
1346
+ if (args.length !== 1) {
1347
+ logs.push({
1348
+ type: "error",
1349
+ description: "Required `elseif` condition",
1350
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1351
+ });
1352
+ break;
1353
+ }
1354
+ if (statementStates.length <= 1) {
1355
+ logs.push({
1356
+ type: "error",
1357
+ description: "Cound not find pair of `if` statement",
1358
+ range: token.range
1359
+ });
1360
+ break;
1361
+ }
1362
+ const lastState = statementStates[statementStates.length - 1];
1363
+ if (lastState.kind !== "if") {
1364
+ logs.push({
1365
+ type: "error",
1366
+ description: "Cound not find pair of `if` statement",
1367
+ range: token.range
1368
+ });
1369
+ break;
1370
+ }
1371
+ if (lastState.currentBlock === "else") {
1372
+ logs.push({
1373
+ type: "error",
1374
+ description: "Could not place `elseif` after `else` statement",
1375
+ range: token.range
1376
+ });
1377
+ break;
1378
+ }
1379
+ flushExpressions(getBranchState(lastState), logs);
1380
+ const conditionNode = args[0];
1381
+ const elseIfIndex = lastState.elseIfs.length;
1382
+ lastState.elseIfs.push({
1383
+ startRange: token.range,
1384
+ condition: conditionNode,
1385
+ then: createBranchState()
1386
+ });
1387
+ lastState.currentBlock = "elseif";
1388
+ lastState.currentElseIfIndex = elseIfIndex;
1389
+ break;
1390
+ }
1391
+ case "while": {
1392
+ cursor.skipToken();
1393
+ const args = parseStatementArguments(cursor, logs);
1394
+ if (args.length !== 1) {
1395
+ logs.push({
1396
+ type: "error",
1397
+ description: "Required `while` condition",
1398
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1399
+ });
1400
+ break;
1401
+ }
1402
+ const conditionNode = args[0];
1403
+ statementStates.push({
1404
+ kind: "while",
1405
+ startRange: token.range,
1406
+ condition: conditionNode,
1407
+ repeat: createBranchState()
1408
+ });
1409
+ break;
1410
+ }
1411
+ case "for": {
1412
+ cursor.skipToken();
1413
+ const args = parseStatementArguments(cursor, logs);
1414
+ if (args.length !== 2) {
1415
+ logs.push({
1416
+ type: "error",
1417
+ description: "Required `for` bind identity and iterable expression",
1418
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1419
+ });
1420
+ break;
1421
+ }
1422
+ const bindNode = args[0];
1423
+ if (bindNode.kind !== "variable") {
1424
+ logs.push({
1425
+ type: "error",
1426
+ description: "Required `for` bind identity",
1427
+ range: bindNode.range
1428
+ });
1429
+ break;
1430
+ }
1431
+ const iterableNode = args[1];
1432
+ statementStates.push({
1433
+ kind: "for",
1434
+ startRange: token.range,
1435
+ bind: bindNode,
1436
+ iterable: iterableNode,
1437
+ repeat: createBranchState()
1438
+ });
1439
+ break;
1440
+ }
1441
+ case "end": {
1442
+ cursor.skipToken();
1443
+ const args = parseStatementArguments(cursor, logs);
1444
+ if (args.length !== 0) logs.push({
1445
+ type: "error",
1446
+ description: "Could not take any arguments in `end` statement",
1447
+ range: widerRange(token.range, ...args.map((node) => node.range), logs)
1448
+ });
1449
+ if (statementStates.length <= 1) {
1450
+ logs.push({
1451
+ type: "error",
1452
+ description: "Cound not find pair of `if`,`while` or `for` statement",
1453
+ range: token.range
1454
+ });
1455
+ break;
1456
+ }
1457
+ const lastState = statementStates.pop();
1458
+ flushStatementState(lastState, logs);
1459
+ switch (lastState.kind) {
1460
+ case "if": {
1461
+ let elseBlocks = lastState.else.blocks;
1462
+ for (let index = lastState.elseIfs.length - 1; index >= 0; index--) {
1463
+ const elseIf = lastState.elseIfs[index];
1464
+ elseBlocks = [{
1465
+ kind: "if",
1466
+ condition: elseIf.condition,
1467
+ then: elseIf.then.blocks,
1468
+ else: elseBlocks,
1469
+ range: widerRange(elseIf.startRange, elseIf.condition.range, ...elseIf.then.blocks.map((node) => node.range), ...elseBlocks.map((node) => node.range), token.range, logs)
1470
+ }];
1471
+ }
1472
+ pushNode(statementStates, {
1473
+ kind: "if",
1474
+ condition: lastState.condition,
1475
+ then: lastState.then.blocks,
1476
+ else: elseBlocks,
1477
+ range: widerRange(lastState.startRange, lastState.condition.range, ...lastState.then.blocks.map((node) => node.range), ...elseBlocks.map((node) => node.range), token.range, logs)
1478
+ }, logs);
1479
+ break;
1480
+ }
1481
+ case "while":
1482
+ pushNode(statementStates, {
1483
+ kind: "while",
1484
+ condition: lastState.condition,
1485
+ repeat: lastState.repeat.blocks,
1486
+ range: widerRange(lastState.startRange, lastState.condition.range, ...lastState.repeat.blocks.map((node) => node.range), token.range, logs)
1487
+ }, logs);
1488
+ break;
1489
+ case "for":
1490
+ pushNode(statementStates, {
1491
+ kind: "for",
1492
+ bind: lastState.bind,
1493
+ iterable: lastState.iterable,
1494
+ repeat: lastState.repeat.blocks,
1495
+ range: widerRange(lastState.startRange, lastState.bind.range, ...lastState.repeat.blocks.map((node) => node.range), token.range, logs)
1496
+ }, logs);
1497
+ break;
1498
+ }
1499
+ break;
1500
+ }
1501
+ default: {
1502
+ const node = parseExpression(cursor, logs);
1503
+ if (node) pushNode(statementStates, node, logs);
1504
+ break;
1505
+ }
1506
+ }
1507
+ break;
1508
+ default: {
1509
+ if (!isInExpressionBlock) {
1510
+ logs.push({
1511
+ type: "error",
1512
+ description: `Invalid ${token.kind} (tokenizer bug?)`,
1513
+ range: token.range
1514
+ });
1515
+ break;
1516
+ }
1517
+ const node = parseExpression(cursor, logs);
1518
+ if (node) pushNode(statementStates, node, logs);
1519
+ break;
1520
+ }
1521
+ }
1522
+ }
1523
+ flushStatementState(rootState, logs);
1524
+ if (statementStates.length !== 1) logs.push({
1525
+ type: "error",
1526
+ description: `Could not find statement closing`,
1527
+ range: widerRange(...statementStates.map((state) => state.startRange), logs)
1528
+ });
1529
+ return rootState.branch.blocks;
1530
+ };
1531
+ /**
1532
+ * Parse blocks.
1533
+ * @param cursor - Parser cursor
1534
+ * @param logs - Will be stored detected warnings/logs into it
1535
+ * @returns Parsed block nodes
1536
+ */
1537
+ var parseBlock = (cursor, logs) => {
1538
+ return parseBlockCore(cursor, logs, "script");
1539
+ };
1540
+ /**
1541
+ * Create a parser cursor.
1542
+ * @param tokens - Target tokens
1543
+ * @returns Parser cursor
1544
+ */
1545
+ var createParserCursor = (tokens) => {
1546
+ let index = 0;
1547
+ const peekToken = () => {
1548
+ return tokens[index];
1549
+ };
1550
+ const takeToken = () => {
1551
+ if (index >= tokens.length) return;
1552
+ const token = tokens[index];
1553
+ index++;
1554
+ return token;
1555
+ };
1556
+ const skipToken = () => {
1557
+ if (index >= tokens.length) return;
1558
+ index++;
1559
+ };
1560
+ return {
1561
+ peekToken,
1562
+ takeToken,
1563
+ skipToken
1564
+ };
1565
+ };
1566
+ /**
1567
+ * Parse expressions in code block.
1568
+ * @param tokens - Token list
1569
+ * @param logs - Will be stored detected warnings/logs into it
1570
+ * @returns Parsed node list
1571
+ */
1572
+ var parseExpressions = (tokens, logs) => {
1573
+ return parseBlockCore(createParserCursor(tokens), logs, "code");
1574
+ };
1575
+ /**
1576
+ * Run the parser.
1577
+ * @param tokens - Token list
1578
+ * @param logs - Will be stored detected warnings/logs into it
1579
+ * @returns Parsed node list
1580
+ */
1581
+ var runParser = (tokens, logs) => {
1582
+ return parseBlock(createParserCursor(tokens), logs);
1583
+ };
1584
+ //#endregion
1585
+ //#region src/reducer.ts
1586
+ var throwError$1 = (info) => {
1587
+ throw new FunCityReducerError({
1588
+ type: "error",
1589
+ ...info
1590
+ });
1591
+ };
1592
+ var deconstructConditionalCombine$1 = (name) => {
1593
+ if (name.length >= 1) {
1594
+ if (name[name.length - 1] === "?") return {
1595
+ name: name.substring(0, name.length - 1),
1596
+ canIgnore: true
1597
+ };
1598
+ }
1599
+ return {
1600
+ name,
1601
+ canIgnore: false
1602
+ };
1603
+ };
1604
+ var resolveVariable$1 = (context, name, signal) => {
1605
+ const result = deconstructConditionalCombine$1(name.name);
1606
+ const valueResult = context.getValue(result.name, signal);
1607
+ if (!valueResult.isFound) {
1608
+ if (!result.canIgnore) throwError$1({
1609
+ description: `variable is not bound: ${result.name}`,
1610
+ range: name.range
1611
+ });
1612
+ return;
1613
+ }
1614
+ return valueResult.value;
1615
+ };
1616
+ var resolveDotNode = async (context, node, signal) => {
1617
+ var _node$segments$0$opti, _node$segments$;
1618
+ signal === null || signal === void 0 || signal.throwIfAborted();
1619
+ const firstSegmentOptional = (_node$segments$0$opti = (_node$segments$ = node.segments[0]) === null || _node$segments$ === void 0 ? void 0 : _node$segments$.optional) !== null && _node$segments$0$opti !== void 0 ? _node$segments$0$opti : false;
1620
+ let value;
1621
+ if (node.base.kind === "variable") {
1622
+ const baseResult = deconstructConditionalCombine$1(node.base.name);
1623
+ const valueResult = context.getValue(baseResult.name, signal);
1624
+ if (!valueResult.isFound) {
1625
+ if (!baseResult.canIgnore && !firstSegmentOptional) throwError$1({
1626
+ description: `variable is not bound: ${baseResult.name}`,
1627
+ range: node.base.range
1628
+ });
1629
+ return;
1630
+ }
1631
+ value = valueResult.value;
1632
+ } else value = await reduceExpressionNode(context, node.base, signal);
1633
+ let parent;
1634
+ for (const segment of node.segments) {
1635
+ const result = deconstructConditionalCombine$1(segment.name);
1636
+ const isOptional = segment.optional || result.canIgnore;
1637
+ if (value !== null && (typeof value === "object" || typeof value === "function")) {
1638
+ const record = value;
1639
+ parent = value;
1640
+ value = record[result.name];
1641
+ } else {
1642
+ if (!isOptional) throwError$1({
1643
+ description: `variable is not bound: ${result.name}`,
1644
+ range: segment.range
1645
+ });
1646
+ return;
1647
+ }
1648
+ }
1649
+ if (parent && typeof value === "function" && !isFunCityFunction(value)) return context.getBoundFunction(parent, value);
1650
+ return value;
1651
+ };
1652
+ var applyFunction = async (context, node, signal) => {
1653
+ signal === null || signal === void 0 || signal.throwIfAborted();
1654
+ const func = await reduceExpressionNode(context, node.func, signal);
1655
+ if (typeof func !== "function") {
1656
+ throwError$1({
1657
+ description: "could not apply it for function",
1658
+ range: node.range
1659
+ });
1660
+ return;
1661
+ }
1662
+ const args = isFunCityFunction(func) ? node.args : await Promise.all(node.args.map(async (argNode) => {
1663
+ return await reduceExpressionNode(context, argNode, signal);
1664
+ }));
1665
+ try {
1666
+ const thisProxy = context.createFunctionContext(node, signal);
1667
+ return await func.call(thisProxy, ...args);
1668
+ } catch (e) {
1669
+ if (e instanceof FunCityReducerError) throw e;
1670
+ if (e instanceof Error && e.name === "AbortError") throw e;
1671
+ throw new FunCityReducerError({
1672
+ type: "error",
1673
+ description: fromError(e),
1674
+ range: node.range
1675
+ });
1676
+ }
1677
+ };
1678
+ /**
1679
+ * Reduce expression node.
1680
+ * @param context - Reducer context
1681
+ * @param node - Target expression node
1682
+ * @param signal - AbortSignal
1683
+ * @returns Reduced native value
1684
+ */
1685
+ var reduceExpressionNode = async (context, node, signal) => {
1686
+ switch (node.kind) {
1687
+ case "number":
1688
+ case "string": return node.value;
1689
+ case "template": {
1690
+ const resultList = [];
1691
+ for (const block of node.blocks) {
1692
+ const results = await reduceNode(context, block, signal);
1693
+ for (const result of results) if (result !== void 0) resultList.push(result);
1694
+ }
1695
+ return resultList.map((result) => context.convertToString(result)).join("");
1696
+ }
1697
+ case "variable": return resolveVariable$1(context, node, signal);
1698
+ case "dot": return await resolveDotNode(context, node, signal);
1699
+ case "apply": return await applyFunction(context, node, signal);
1700
+ case "list": return await Promise.all(node.items.map((item) => reduceExpressionNode(context, item, signal)));
1701
+ case "scope": {
1702
+ if (node.nodes.length === 0) return [];
1703
+ let result = void 0;
1704
+ for (const childNode of node.nodes) result = await reduceExpressionNode(context, childNode, signal);
1705
+ return result;
1706
+ }
1707
+ }
1708
+ };
1709
+ /**
1710
+ * Reduce a node.
1711
+ * @param context - Reducer context
1712
+ * @param node - Target node
1713
+ * @param signal - AbortSignal
1714
+ * @returns Reduced native value list
1715
+ */
1716
+ var reduceNode = async (context, node, signal) => {
1717
+ switch (node.kind) {
1718
+ case "text": return [node.text];
1719
+ case "for": {
1720
+ const iterable = asIterable(await reduceExpressionNode(context, node.iterable, signal));
1721
+ if (!iterable) {
1722
+ throwError$1({
1723
+ description: "could not apply it for function",
1724
+ range: node.range
1725
+ });
1726
+ return [];
1727
+ }
1728
+ const resultList = [];
1729
+ for (const item of iterable) {
1730
+ context.setValue(node.bind.name, item, signal);
1731
+ for (const repeat of node.repeat) {
1732
+ const results = await reduceNode(context, repeat, signal);
1733
+ resultList.push(...results);
1734
+ }
1735
+ }
1736
+ return resultList;
1737
+ }
1738
+ case "while": {
1739
+ const resultList = [];
1740
+ while (true) {
1741
+ if (!isConditionalTrue(await reduceExpressionNode(context, node.condition, signal))) break;
1742
+ for (const repeat of node.repeat) {
1743
+ const results = await reduceNode(context, repeat, signal);
1744
+ resultList.push(...results);
1745
+ }
1746
+ }
1747
+ return resultList;
1748
+ }
1749
+ case "if": {
1750
+ const resultList = [];
1751
+ if (isConditionalTrue(await reduceExpressionNode(context, node.condition, signal))) for (const then of node.then) {
1752
+ const results = await reduceNode(context, then, signal);
1753
+ resultList.push(...results);
1754
+ }
1755
+ else for (const els of node.else) {
1756
+ const results = await reduceNode(context, els, signal);
1757
+ resultList.push(...results);
1758
+ }
1759
+ return resultList;
1760
+ }
1761
+ default: return [await reduceExpressionNode(context, node, signal)];
1762
+ }
1763
+ };
1764
+ var defaultReducerExecutor = {
1765
+ reduceExpressionNodeImmediate: (context, node, signal) => reduceExpressionNode(context, node, signal),
1766
+ reduceExpressionNode: (context, node, signal) => Promise.resolve(reduceExpressionNode(context, node, signal)),
1767
+ reduceNodeImmediate: (context, node, signal) => reduceNode(context, node, signal),
1768
+ reduceNode: (context, node, signal) => Promise.resolve(reduceNode(context, node, signal))
1769
+ };
1770
+ var reduceBlockImmediate = (context, nodeOrNodes, signal) => {
1771
+ const nodes = Array.isArray(nodeOrNodes) ? nodeOrNodes : [nodeOrNodes];
1772
+ const resultList = [];
1773
+ for (let index = 0; index < nodes.length; index++) {
1774
+ const results = context.reduceNodeImmediate(nodes[index], signal);
1775
+ if (isPromiseLike(results)) return (async () => {
1776
+ const firstResults = await results;
1777
+ for (const result of firstResults) if (result !== void 0) resultList.push(result);
1778
+ for (let continueIndex = index + 1; continueIndex < nodes.length; continueIndex++) {
1779
+ const continueResults = await context.reduceNodeImmediate(nodes[continueIndex], signal);
1780
+ for (const result of continueResults) if (result !== void 0) resultList.push(result);
1781
+ }
1782
+ return resultList;
1783
+ })();
1784
+ for (const result of results) if (result !== void 0) resultList.push(result);
1785
+ }
1786
+ return resultList;
1787
+ };
1788
+ var createPreparedSlotState = (slotNames, slotValues, signal) => {
1789
+ signal === null || signal === void 0 || signal.throwIfAborted();
1790
+ let preparedSlotIds;
1791
+ let preparedSlotValues;
1792
+ let preparedSlotVersion = 0;
1793
+ if (slotNames === void 0 || slotNames.length === 0) return {
1794
+ preparedSlotIds,
1795
+ preparedSlotValues,
1796
+ preparedSlotVersion
1797
+ };
1798
+ for (let index = 0; index < slotNames.length; index++) {
1799
+ const name = slotNames[index];
1800
+ const existingSlot = preparedSlotIds === null || preparedSlotIds === void 0 ? void 0 : preparedSlotIds.get(name);
1801
+ if (existingSlot !== void 0) {
1802
+ preparedSlotValues[existingSlot] = slotValues === null || slotValues === void 0 ? void 0 : slotValues[index];
1803
+ continue;
1804
+ }
1805
+ if (!preparedSlotIds) preparedSlotIds = /* @__PURE__ */ new Map();
1806
+ if (!preparedSlotValues) preparedSlotValues = [];
1807
+ const slot = preparedSlotValues.length;
1808
+ preparedSlotIds.set(name, slot);
1809
+ preparedSlotValues.push(slotValues === null || slotValues === void 0 ? void 0 : slotValues[index]);
1810
+ preparedSlotVersion++;
1811
+ }
1812
+ return {
1813
+ preparedSlotIds,
1814
+ preparedSlotValues,
1815
+ preparedSlotVersion
1816
+ };
1817
+ };
1818
+ var createScopedReducerContext = (parent, signal, executor, initialSlotNames, initialSlotValues) => {
1819
+ signal === null || signal === void 0 || signal.throwIfAborted();
1820
+ const preparedSlotState = createPreparedSlotState(initialSlotNames, initialSlotValues, signal);
1821
+ let thisSlotIds = preparedSlotState.preparedSlotIds;
1822
+ let thisSlotValues = preparedSlotState.preparedSlotValues;
1823
+ let thisSlotVersion = preparedSlotState.preparedSlotVersion;
1824
+ let thisContext;
1825
+ const getSlotVersion = () => thisSlotVersion;
1826
+ const resolveLocalSlot = (name, signal) => {
1827
+ signal === null || signal === void 0 || signal.throwIfAborted();
1828
+ return thisSlotIds === null || thisSlotIds === void 0 ? void 0 : thisSlotIds.get(name);
1829
+ };
1830
+ const ensureLocalSlot = (name, signal) => {
1831
+ signal === null || signal === void 0 || signal.throwIfAborted();
1832
+ let slot = thisSlotIds === null || thisSlotIds === void 0 ? void 0 : thisSlotIds.get(name);
1833
+ if (slot !== void 0) return slot;
1834
+ if (!thisSlotIds) thisSlotIds = /* @__PURE__ */ new Map();
1835
+ if (!thisSlotValues) thisSlotValues = [];
1836
+ slot = thisSlotValues.length;
1837
+ thisSlotIds.set(name, slot);
1838
+ thisSlotValues.push(void 0);
1839
+ thisSlotVersion++;
1840
+ return slot;
1841
+ };
1842
+ const getSlotValue = (slot, signal) => {
1843
+ signal === null || signal === void 0 || signal.throwIfAborted();
1844
+ return thisSlotValues === null || thisSlotValues === void 0 ? void 0 : thisSlotValues[slot];
1845
+ };
1846
+ const setSlotValue = (slot, value, signal) => {
1847
+ signal === null || signal === void 0 || signal.throwIfAborted();
1848
+ if (!thisSlotValues) thisSlotValues = [];
1849
+ thisSlotValues[slot] = value;
1850
+ };
1851
+ const getValue = (name, signal) => {
1852
+ signal === null || signal === void 0 || signal.throwIfAborted();
1853
+ const slot = resolveLocalSlot(name, signal);
1854
+ if (slot !== void 0) return {
1855
+ value: getSlotValue(slot, signal),
1856
+ isFound: true
1857
+ };
1858
+ return parent.getValue(name, signal);
1859
+ };
1860
+ const setValue = (name, value, signal) => {
1861
+ signal === null || signal === void 0 || signal.throwIfAborted();
1862
+ setSlotValue(ensureLocalSlot(name, signal), value, signal);
1863
+ };
1864
+ const createFunctionContext = (thisNode, signal) => {
1865
+ const reduceBlock = (nodeOrNodes) => Promise.resolve(reduceBlockImmediate(thisContext, nodeOrNodes, signal));
1866
+ return {
1867
+ thisNode,
1868
+ abortSignal: signal,
1869
+ getValue: (name) => getValue(name, signal),
1870
+ setValue: (name, value) => setValue(name, value, signal),
1871
+ appendWarning: parent.appendWarning,
1872
+ getBoundFunction: parent.getBoundFunction,
1873
+ newScope: () => createScopedReducerContext(thisContext, signal, executor, void 0, void 0),
1874
+ convertToString: parent.convertToString,
1875
+ reduceImmediate: (node) => thisContext.reduceExpressionNodeImmediate(node, signal),
1876
+ reduce: (node) => thisContext.reduceExpressionNode(node, signal),
1877
+ reduceBlockImmediate: (nodeOrNodes) => reduceBlockImmediate(thisContext, nodeOrNodes, signal),
1878
+ reduceBlock
1879
+ };
1880
+ };
1881
+ thisContext = {
1882
+ getValue,
1883
+ setValue,
1884
+ getBoundFunction: parent.getBoundFunction,
1885
+ appendWarning: parent.appendWarning,
1886
+ newScope: (signal) => createScopedReducerContext(thisContext, signal, executor, void 0, void 0),
1887
+ newCallScope: (slotNames, slotValues, signal) => createScopedReducerContext(thisContext, signal, executor, slotNames, slotValues),
1888
+ getSlotVersion,
1889
+ resolveLocalSlot,
1890
+ ensureLocalSlot,
1891
+ getSlotValue,
1892
+ setSlotValue,
1893
+ convertToString: parent.convertToString,
1894
+ reduceExpressionNode: (node, signal) => executor.reduceExpressionNode(thisContext, node, signal),
1895
+ reduceExpressionNodeImmediate: (node, signal) => executor.reduceExpressionNodeImmediate(thisContext, node, signal),
1896
+ reduceNode: (node, signal) => executor.reduceNode(thisContext, node, signal),
1897
+ reduceNodeImmediate: (node, signal) => executor.reduceNodeImmediate(thisContext, node, signal),
1898
+ isConstructable: parent.isConstructable,
1899
+ createFunctionContext
1900
+ };
1901
+ return thisContext;
1902
+ };
1903
+ /**
1904
+ * Create reducer context.
1905
+ * @param variables - Predefined variables
1906
+ * @returns Reducer context
1907
+ */
1908
+ var createReducerContext = (variables, warningLogs, executor = defaultReducerExecutor) => {
1909
+ let thisSlotIds;
1910
+ let thisSlotValues;
1911
+ let thisSlotVersion = 0;
1912
+ let thisContext;
1913
+ const boundFunctionCache = /* @__PURE__ */ new WeakMap();
1914
+ const getBoundFunction = (owner, fn) => {
1915
+ let ownerCache = boundFunctionCache.get(owner);
1916
+ if (!ownerCache) {
1917
+ ownerCache = /* @__PURE__ */ new WeakMap();
1918
+ boundFunctionCache.set(owner, ownerCache);
1919
+ }
1920
+ const cached = ownerCache.get(fn);
1921
+ if (cached) return cached;
1922
+ const bound = fn.bind(owner);
1923
+ ownerCache.set(fn, bound);
1924
+ return bound;
1925
+ };
1926
+ const constructorCache = /* @__PURE__ */ new WeakMap();
1927
+ const getSlotVersion = () => thisSlotVersion;
1928
+ const resolveLocalSlot = (name, signal) => {
1929
+ signal === null || signal === void 0 || signal.throwIfAborted();
1930
+ return thisSlotIds === null || thisSlotIds === void 0 ? void 0 : thisSlotIds.get(name);
1931
+ };
1932
+ const ensureLocalSlot = (name, signal) => {
1933
+ signal === null || signal === void 0 || signal.throwIfAborted();
1934
+ let slot = thisSlotIds === null || thisSlotIds === void 0 ? void 0 : thisSlotIds.get(name);
1935
+ if (slot !== void 0) return slot;
1936
+ if (!thisSlotIds) thisSlotIds = /* @__PURE__ */ new Map();
1937
+ if (!thisSlotValues) thisSlotValues = [];
1938
+ slot = thisSlotValues.length;
1939
+ thisSlotIds.set(name, slot);
1940
+ thisSlotValues.push(void 0);
1941
+ thisSlotVersion++;
1942
+ return slot;
1943
+ };
1944
+ const getSlotValue = (slot, signal) => {
1945
+ signal === null || signal === void 0 || signal.throwIfAborted();
1946
+ return thisSlotValues === null || thisSlotValues === void 0 ? void 0 : thisSlotValues[slot];
1947
+ };
1948
+ const setSlotValue = (slot, value, signal) => {
1949
+ signal === null || signal === void 0 || signal.throwIfAborted();
1950
+ if (!thisSlotValues) thisSlotValues = [];
1951
+ thisSlotValues[slot] = value;
1952
+ };
1953
+ const getValue = (name, signal) => {
1954
+ signal === null || signal === void 0 || signal.throwIfAborted();
1955
+ const slot = resolveLocalSlot(name, signal);
1956
+ if (slot !== void 0) return {
1957
+ value: getSlotValue(slot, signal),
1958
+ isFound: true
1959
+ };
1960
+ if (variables.has(name)) return {
1961
+ value: variables.get(name),
1962
+ isFound: true
1963
+ };
1964
+ return {
1965
+ value: void 0,
1966
+ isFound: false
1967
+ };
1968
+ };
1969
+ const setValue = (name, value, signal) => {
1970
+ signal === null || signal === void 0 || signal.throwIfAborted();
1971
+ setSlotValue(ensureLocalSlot(name, signal), value, signal);
1972
+ };
1973
+ const appendWarning = (warning) => {
1974
+ warningLogs.push(warning);
1975
+ };
1976
+ const isConstructable = (fn) => {
1977
+ if (constructorCache.has(fn)) return constructorCache.get(fn);
1978
+ let result = false;
1979
+ try {
1980
+ Reflect.construct(Object, [], fn);
1981
+ result = true;
1982
+ } catch (_unused) {
1983
+ result = false;
1984
+ }
1985
+ constructorCache.set(fn, result);
1986
+ return result;
1987
+ };
1988
+ const getFuncId = internalCreateFunctionIdGenerator();
1989
+ const convertToString = (v) => {
1990
+ return internalConvertToString(v, getFuncId);
1991
+ };
1992
+ const createFunctionContext = (thisNode, signal) => {
1993
+ const reduceBlock = (nodeOrNodes) => Promise.resolve(reduceBlockImmediate(thisContext, nodeOrNodes, signal));
1994
+ return {
1995
+ thisNode,
1996
+ abortSignal: signal,
1997
+ getValue: (name) => getValue(name, signal),
1998
+ setValue: (name, value) => setValue(name, value, signal),
1999
+ appendWarning,
2000
+ getBoundFunction,
2001
+ newScope: () => createScopedReducerContext(thisContext, signal, executor, void 0, void 0),
2002
+ convertToString,
2003
+ reduceImmediate: (node) => thisContext.reduceExpressionNodeImmediate(node, signal),
2004
+ reduce: (node) => thisContext.reduceExpressionNode(node, signal),
2005
+ reduceBlockImmediate: (nodeOrNodes) => reduceBlockImmediate(thisContext, nodeOrNodes, signal),
2006
+ reduceBlock
2007
+ };
2008
+ };
2009
+ thisContext = {
2010
+ getValue,
2011
+ setValue,
2012
+ getBoundFunction,
2013
+ appendWarning,
2014
+ newScope: (signal) => createScopedReducerContext(thisContext, signal, executor, void 0, void 0),
2015
+ newCallScope: (slotNames, slotValues, signal) => createScopedReducerContext(thisContext, signal, executor, slotNames, slotValues),
2016
+ getSlotVersion,
2017
+ resolveLocalSlot,
2018
+ ensureLocalSlot,
2019
+ getSlotValue,
2020
+ setSlotValue,
2021
+ convertToString,
2022
+ reduceExpressionNode: (node, signal) => executor.reduceExpressionNode(thisContext, node, signal),
2023
+ reduceExpressionNodeImmediate: (node, signal) => executor.reduceExpressionNodeImmediate(thisContext, node, signal),
2024
+ reduceNode: (node, signal) => executor.reduceNode(thisContext, node, signal),
2025
+ reduceNodeImmediate: (node, signal) => executor.reduceNodeImmediate(thisContext, node, signal),
2026
+ isConstructable,
2027
+ createFunctionContext
2028
+ };
2029
+ return thisContext;
2030
+ };
2031
+ /**
2032
+ * Run the reducer.
2033
+ * @param nodes - Target nodes
2034
+ * @param variables - Predefined variables
2035
+ * @param logs - Will be stored logs
2036
+ * @param signal - Abort signal
2037
+ * @returns Reduced native values
2038
+ */
2039
+ async function runReducer(nodes, variables, warningLogs, signal) {
2040
+ const context = createReducerContext(variables, warningLogs);
2041
+ const resultList = [];
2042
+ for (const node of nodes) {
2043
+ const results = await reduceNode(context, node, signal);
2044
+ for (const result of results) if (result !== void 0) resultList.push(result);
2045
+ }
2046
+ return resultList;
2047
+ }
2048
+ //#endregion
2049
+ //#region src/variables/standard-variables.ts
2050
+ var resolveMaybePromise$1 = (value, onResolved) => {
2051
+ if (isPromiseLike(value)) return value.then((resolved) => onResolved(resolved));
2052
+ return onResolved(value);
2053
+ };
2054
+ var _cond = makeFunCityFunction(function(arg0, arg1, arg2) {
2055
+ if (!arg0 || !arg1 || !arg2) throw new FunCityReducerError({
2056
+ type: "error",
2057
+ description: "Required `cond` condition, true and false expressions",
2058
+ range: this.thisNode.range
2059
+ });
2060
+ return resolveMaybePromise$1(this.reduceImmediate(arg0), (cond) => isConditionalTrue(cond) ? this.reduceImmediate(arg1) : this.reduceImmediate(arg2));
2061
+ });
2062
+ var _defaults = makeFunCityFunction(function(arg0, arg1, ...rest) {
2063
+ if (!arg0 || !arg1 || rest.length !== 0) throw new FunCityReducerError({
2064
+ type: "error",
2065
+ description: "Required `defaults` value and default expression",
2066
+ range: this.thisNode.range
2067
+ });
2068
+ return resolveMaybePromise$1(this.reduceImmediate(arg0), (value) => {
2069
+ if (value !== void 0 && value !== null) return value;
2070
+ return this.reduceImmediate(arg1);
2071
+ });
2072
+ });
2073
+ var _set = makeFunCityFunction(function(arg0, arg1, ...rest) {
2074
+ if (!arg0 || !arg1 || rest.length !== 0) throw new FunCityReducerError({
2075
+ type: "error",
2076
+ description: "Required `set` bind identity and expression",
2077
+ range: this.thisNode.range
2078
+ });
2079
+ if (arg0.kind !== "variable") throw new FunCityReducerError({
2080
+ type: "error",
2081
+ description: "Required `set` bind identity",
2082
+ range: arg0.range
2083
+ });
2084
+ return resolveMaybePromise$1(this.reduceImmediate(arg1), (value) => {
2085
+ this.setValue(arg0.name, value);
2086
+ });
2087
+ });
2088
+ var isConstructable = (fn) => {
2089
+ try {
2090
+ Reflect.construct(Object, [], fn);
2091
+ return true;
2092
+ } catch (_unused) {
2093
+ return false;
2094
+ }
2095
+ };
2096
+ var _new = makeFunCityFunction(function(arg0, ...rest) {
2097
+ if (!arg0) throw new FunCityReducerError({
2098
+ type: "error",
2099
+ description: "Required `new` constructor expression",
2100
+ range: this.thisNode.range
2101
+ });
2102
+ return resolveMaybePromise$1(this.reduceImmediate(arg0), (target) => {
2103
+ if (typeof target !== "function") throw new FunCityReducerError({
2104
+ type: "error",
2105
+ description: "Required `new` constructor function",
2106
+ range: arg0.range
2107
+ });
2108
+ if (!isConstructable(target)) throw new FunCityReducerError({
2109
+ type: "error",
2110
+ description: "Required `new` constructable function",
2111
+ range: arg0.range
2112
+ });
2113
+ return resolveMaybePromise$1(Promise.all(rest.map((arg) => this.reduce(arg))), (args) => Reflect.construct(target, args));
2114
+ });
2115
+ });
2116
+ var extractParameterArguments = (namesNode, _context) => {
2117
+ switch (namesNode.kind) {
2118
+ case "variable": return [namesNode];
2119
+ case "list": {
2120
+ const nameNodes = [];
2121
+ for (const nameNode of namesNode.items) if (nameNode.kind !== "variable") throw new FunCityReducerError({
2122
+ type: "error",
2123
+ description: "Required `fun` parameter identity",
2124
+ range: nameNode.range
2125
+ });
2126
+ else nameNodes.push(nameNode);
2127
+ return nameNodes;
2128
+ }
2129
+ default: throw new FunCityReducerError({
2130
+ type: "error",
2131
+ description: "Required `fun` parameter identity",
2132
+ range: namesNode.range
2133
+ });
2134
+ }
2135
+ };
2136
+ var _fun = makeFunCityFunction(function(arg0, arg1, ...rest) {
2137
+ if (!arg0 || !arg1 || rest.length !== 0) throw new FunCityReducerError({
2138
+ type: "error",
2139
+ description: "Required `fun` parameter identity and expression",
2140
+ range: this.thisNode.range
2141
+ });
2142
+ const nameNodes = extractParameterArguments(arg0, this);
2143
+ if (!nameNodes) return;
2144
+ const bodyNode = arg1;
2145
+ const lambdaRange = this.thisNode.range;
2146
+ const createScope = this.newScope;
2147
+ return (...args) => {
2148
+ if (args.length < nameNodes.length) throw new FunCityReducerError({
2149
+ type: "error",
2150
+ description: `Arguments are not filled: ${args.length} < ${nameNodes.length}`,
2151
+ range: lambdaRange
2152
+ });
2153
+ else if (args.length > nameNodes.length) this.appendWarning({
2154
+ type: "warning",
2155
+ description: `Too many arguments: ${args.length} > ${nameNodes.length}`,
2156
+ range: lambdaRange
2157
+ });
2158
+ const newContext = createScope();
2159
+ for (let index = 0; index < nameNodes.length; index++) newContext.setValue(nameNodes[index].name, args[index], this.abortSignal);
2160
+ return newContext.reduceExpressionNodeImmediate(bodyNode, this.abortSignal);
2161
+ };
2162
+ });
2163
+ var _typeof = (arg0) => {
2164
+ if (arg0 === null) return "null";
2165
+ else if (typeof arg0 === "string") return "string";
2166
+ else if (Array.isArray(arg0)) return "array";
2167
+ else if (asIterable(arg0)) return "iterable";
2168
+ else return typeof arg0;
2169
+ };
2170
+ var _toString = (...args) => {
2171
+ return args.map((arg0) => convertToString(arg0)).join(",");
2172
+ };
2173
+ var _toBoolean = (arg0) => {
2174
+ return isConditionalTrue(arg0);
2175
+ };
2176
+ var _toNumber = (arg0) => {
2177
+ return Number(arg0);
2178
+ };
2179
+ var _toBigInt = (arg0) => {
2180
+ switch (typeof arg0) {
2181
+ case "number":
2182
+ case "bigint":
2183
+ case "string":
2184
+ case "boolean": return BigInt(arg0);
2185
+ default: return BigInt(_toString(arg0));
2186
+ }
2187
+ };
2188
+ var _add = (arg0, ...args) => {
2189
+ return args.reduce((v0, v) => v0 + Number(v), Number(arg0));
2190
+ };
2191
+ var _sub = (arg0, ...args) => {
2192
+ return args.reduce((v0, v) => v0 - Number(v), Number(arg0));
2193
+ };
2194
+ var _mul = (arg0, ...args) => {
2195
+ return args.reduce((v0, v) => v0 * Number(v), Number(arg0));
2196
+ };
2197
+ var _div = (arg0, ...args) => {
2198
+ return args.reduce((v0, v) => v0 / Number(v), Number(arg0));
2199
+ };
2200
+ var _mod = (arg0, ...args) => {
2201
+ return args.reduce((v0, v) => v0 % Number(v), Number(arg0));
2202
+ };
2203
+ var _eq = (arg0, arg1) => {
2204
+ return arg0 === arg1;
2205
+ };
2206
+ var _ne = (arg0, arg1) => {
2207
+ return arg0 !== arg1;
2208
+ };
2209
+ var _lt = (arg0, arg1) => {
2210
+ return arg0 < arg1;
2211
+ };
2212
+ var _gt = (arg0, arg1) => {
2213
+ return arg0 > arg1;
2214
+ };
2215
+ var _le = (arg0, arg1) => {
2216
+ return arg0 <= arg1;
2217
+ };
2218
+ var _ge = (arg0, arg1) => {
2219
+ return arg0 >= arg1;
2220
+ };
2221
+ var _now = () => {
2222
+ return /* @__PURE__ */ new Date();
2223
+ };
2224
+ var _random = makeFunCityFunction(function(arg0, arg1, ...rest) {
2225
+ if (!arg0 || rest.length !== 0) throw new FunCityReducerError({
2226
+ type: "error",
2227
+ description: "Required `random` range arguments",
2228
+ range: this.thisNode.range
2229
+ });
2230
+ return resolveMaybePromise$1(this.reduceImmediate(arg0), (baseValue) => {
2231
+ return resolveMaybePromise$1(arg1 ? this.reduceImmediate(arg1) : baseValue, (resolvedSpanValue) => {
2232
+ const base = arg1 ? Number(baseValue) : 0;
2233
+ const span = Number(resolvedSpanValue);
2234
+ return base + Math.floor(Math.random() * span);
2235
+ });
2236
+ });
2237
+ });
2238
+ var _randomf = (arg0, arg1) => {
2239
+ if (arg0 === void 0) return Math.random();
2240
+ const base = arg1 === void 0 ? 0 : Number(arg0);
2241
+ const span = Number(arg1 !== null && arg1 !== void 0 ? arg1 : arg0);
2242
+ return base + Math.random() * span;
2243
+ };
2244
+ var concatInner = (sep, args) => {
2245
+ let v = "";
2246
+ let f = true;
2247
+ for (const arg of args) {
2248
+ let as;
2249
+ if (typeof arg === "string") as = arg;
2250
+ else {
2251
+ const iterable = asIterable(arg);
2252
+ if (iterable) as = concatInner(sep, iterable);
2253
+ else as = convertToString(arg);
2254
+ }
2255
+ if (f) {
2256
+ v = v + as;
2257
+ f = false;
2258
+ } else v = v + sep + as;
2259
+ }
2260
+ return v;
2261
+ };
2262
+ var _concat = (...args) => {
2263
+ return concatInner("", args);
2264
+ };
2265
+ var _join = (arg0, ...args) => {
2266
+ return concatInner(convertToString(arg0), args);
2267
+ };
2268
+ var _trim = (arg0) => {
2269
+ let v = arg0;
2270
+ if (v === void 0 || v === null) v = "";
2271
+ else if (typeof v !== "string") {
2272
+ var _v$toString;
2273
+ v = (_v$toString = v.toString()) !== null && _v$toString !== void 0 ? _v$toString : "";
2274
+ }
2275
+ return v.trim();
2276
+ };
2277
+ var _toUpper = (arg0) => {
2278
+ let v = arg0;
2279
+ if (typeof v !== "string") {
2280
+ var _v$toString2;
2281
+ v = (_v$toString2 = v.toString()) !== null && _v$toString2 !== void 0 ? _v$toString2 : "";
2282
+ }
2283
+ return v.toUpperCase();
2284
+ };
2285
+ var _toLower = (arg0) => {
2286
+ let v = arg0;
2287
+ if (typeof v !== "string") {
2288
+ var _v$toString3;
2289
+ v = (_v$toString3 = v.toString()) !== null && _v$toString3 !== void 0 ? _v$toString3 : "";
2290
+ }
2291
+ return v.toLowerCase();
2292
+ };
2293
+ var _length = (arg0) => {
2294
+ if (arg0) {
2295
+ if (typeof arg0 === "string") return arg0.length;
2296
+ else if (Array.isArray(arg0)) return arg0.length;
2297
+ else if (asIterable(arg0)) {
2298
+ let count = 0;
2299
+ for (const _item of arg0) count++;
2300
+ return count;
2301
+ }
2302
+ }
2303
+ return 0;
2304
+ };
2305
+ var _and = makeFunCityFunction(function(...args) {
2306
+ if (args.length === 0) throw new FunCityReducerError({
2307
+ type: "error",
2308
+ description: "empty arguments",
2309
+ range: this.thisNode.range
2310
+ });
2311
+ for (let index = 0; index < args.length; index++) {
2312
+ const value = this.reduceImmediate(args[index]);
2313
+ if (isPromiseLike(value)) return (async () => {
2314
+ if (!isConditionalTrue(await value)) return false;
2315
+ for (let continueIndex = index + 1; continueIndex < args.length; continueIndex++) if (!isConditionalTrue(await this.reduceImmediate(args[continueIndex]))) return false;
2316
+ return true;
2317
+ })();
2318
+ if (!isConditionalTrue(value)) return false;
2319
+ }
2320
+ return true;
2321
+ });
2322
+ var _or = makeFunCityFunction(function(...args) {
2323
+ if (args.length === 0) throw new FunCityReducerError({
2324
+ type: "error",
2325
+ description: "empty arguments",
2326
+ range: this.thisNode.range
2327
+ });
2328
+ for (let index = 0; index < args.length; index++) {
2329
+ const value = this.reduceImmediate(args[index]);
2330
+ if (isPromiseLike(value)) return (async () => {
2331
+ if (isConditionalTrue(await value)) return true;
2332
+ for (let continueIndex = index + 1; continueIndex < args.length; continueIndex++) if (isConditionalTrue(await this.reduceImmediate(args[continueIndex]))) return true;
2333
+ return false;
2334
+ })();
2335
+ if (isConditionalTrue(value)) return true;
2336
+ }
2337
+ return false;
2338
+ });
2339
+ var _not = (arg0) => {
2340
+ return !isConditionalTrue(arg0);
2341
+ };
2342
+ var _at = (arg0, arg1) => {
2343
+ const index = Number(arg0);
2344
+ if (arg1) if (typeof arg1 === "string") return arg1[index];
2345
+ else if (Array.isArray(arg1)) return arg1[index];
2346
+ else {
2347
+ const iterable = asIterable(arg1);
2348
+ if (iterable) {
2349
+ let current = 0;
2350
+ for (const item of iterable) {
2351
+ if (current >= index) return item;
2352
+ current++;
2353
+ }
2354
+ }
2355
+ }
2356
+ };
2357
+ var _first = (arg0) => {
2358
+ if (arg0) if (typeof arg0 === "string") return arg0[0];
2359
+ else if (Array.isArray(arg0)) return arg0[0];
2360
+ else {
2361
+ const iterable = asIterable(arg0);
2362
+ if (iterable) for (const item of iterable) return item;
2363
+ }
2364
+ };
2365
+ var _last = (arg0) => {
2366
+ if (arg0) if (typeof arg0 === "string") return arg0[arg0.length - 1];
2367
+ else if (Array.isArray(arg0)) return arg0[arg0.length - 1];
2368
+ else {
2369
+ const iterable = asIterable(arg0);
2370
+ if (iterable) {
2371
+ let lastItem = void 0;
2372
+ for (const item of iterable) lastItem = item;
2373
+ return lastItem;
2374
+ }
2375
+ }
2376
+ };
2377
+ var _range = (arg0, arg1) => {
2378
+ let value = Number(arg0);
2379
+ const count = Number(arg1);
2380
+ const resultList = [];
2381
+ for (let index = 0; index < count; index++) resultList.push(value++);
2382
+ return resultList;
2383
+ };
2384
+ var sliceIterable = (iter, start, end) => {
2385
+ const resultList = [];
2386
+ for (const item of iter) resultList.push(item);
2387
+ return resultList.slice(start, end);
2388
+ };
2389
+ var _slice = (arg0, arg1, arg2) => {
2390
+ const start = arg0 === void 0 ? void 0 : Number(arg0);
2391
+ if (arg2 === void 0) {
2392
+ if (typeof arg1 === "string") return arg1.slice(start);
2393
+ return sliceIterable(arg1, start, void 0);
2394
+ }
2395
+ const end = arg1 === void 0 ? void 0 : Number(arg1);
2396
+ if (typeof arg2 === "string") return arg2.slice(start, end);
2397
+ return sliceIterable(arg2, start, end);
2398
+ };
2399
+ var _reverse = (arg0) => {
2400
+ const iter = arg0;
2401
+ let resultList = [];
2402
+ for (const item of iter) resultList.push(item);
2403
+ return resultList.reverse();
2404
+ };
2405
+ var _sort = (arg0) => {
2406
+ const iter = arg0;
2407
+ let resultList = [];
2408
+ for (const item of iter) resultList.push(item);
2409
+ return resultList.sort();
2410
+ };
2411
+ var _map = async (arg0, arg1) => {
2412
+ const predicate = arg0;
2413
+ const iter = arg1;
2414
+ const resultList = [];
2415
+ for (const item of iter) {
2416
+ const result = await predicate(item);
2417
+ resultList.push(result);
2418
+ }
2419
+ return resultList;
2420
+ };
2421
+ var _flatMap = async (arg0, arg1) => {
2422
+ const predicate = arg0;
2423
+ const iter = arg1;
2424
+ const resultList = [];
2425
+ for (const item of iter) {
2426
+ const results = await predicate(item);
2427
+ resultList.push(...results);
2428
+ }
2429
+ return resultList;
2430
+ };
2431
+ var _flatten = (arg0) => {
2432
+ const iter = arg0;
2433
+ const resultList = [];
2434
+ for (const item of iter) {
2435
+ const iterable = asIterable(item);
2436
+ if (!iterable) throw new TypeError("flatten requires nested iterable items");
2437
+ resultList.push(...iterable);
2438
+ }
2439
+ return resultList;
2440
+ };
2441
+ var _filter = async (arg0, arg1) => {
2442
+ const predicate = arg0;
2443
+ const iter = arg1;
2444
+ const resultList = [];
2445
+ for (const item of iter) if (isConditionalTrue(await predicate(item))) resultList.push(item);
2446
+ return resultList;
2447
+ };
2448
+ var _collect = (arg0) => {
2449
+ const iter = arg0;
2450
+ const resultList = [];
2451
+ for (const item of iter) if (item !== void 0 && item !== null) resultList.push(item);
2452
+ return resultList;
2453
+ };
2454
+ var _distinct = (arg0) => {
2455
+ const iter = arg0;
2456
+ const seen = /* @__PURE__ */ new Set();
2457
+ const resultList = [];
2458
+ for (const item of iter) if (!seen.has(item)) {
2459
+ seen.add(item);
2460
+ resultList.push(item);
2461
+ }
2462
+ return resultList;
2463
+ };
2464
+ var _distinctBy = async (arg0, arg1) => {
2465
+ const selector = arg0;
2466
+ const iter = arg1;
2467
+ const seen = /* @__PURE__ */ new Set();
2468
+ const resultList = [];
2469
+ for (const item of iter) {
2470
+ const key = await selector(item);
2471
+ if (!seen.has(key)) {
2472
+ seen.add(key);
2473
+ resultList.push(item);
2474
+ }
2475
+ }
2476
+ return resultList;
2477
+ };
2478
+ var _union = (arg0, arg1) => {
2479
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2480
+ const union = arg0.union;
2481
+ if (typeof union === "function") return Array.from(union.call(arg0, arg1));
2482
+ }
2483
+ const resultList = [];
2484
+ const seen = /* @__PURE__ */ new Set();
2485
+ for (const item of arg0) if (!seen.has(item)) {
2486
+ seen.add(item);
2487
+ resultList.push(item);
2488
+ }
2489
+ for (const item of arg1) if (!seen.has(item)) {
2490
+ seen.add(item);
2491
+ resultList.push(item);
2492
+ }
2493
+ return resultList;
2494
+ };
2495
+ var _unionBy = async (arg0, arg1, arg2) => {
2496
+ const selector = arg0;
2497
+ const iterA = arg1;
2498
+ const iterB = arg2;
2499
+ const resultList = [];
2500
+ const seen = /* @__PURE__ */ new Set();
2501
+ for (const item of iterA) {
2502
+ const key = await selector(item);
2503
+ if (!seen.has(key)) {
2504
+ seen.add(key);
2505
+ resultList.push(item);
2506
+ }
2507
+ }
2508
+ for (const item of iterB) {
2509
+ const key = await selector(item);
2510
+ if (!seen.has(key)) {
2511
+ seen.add(key);
2512
+ resultList.push(item);
2513
+ }
2514
+ }
2515
+ return resultList;
2516
+ };
2517
+ var _intersection = (arg0, arg1) => {
2518
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2519
+ const intersection = arg0.intersection;
2520
+ if (typeof intersection === "function") return Array.from(intersection.call(arg0, arg1));
2521
+ }
2522
+ const iterA = arg0;
2523
+ const setB = new Set(arg1);
2524
+ const seen = /* @__PURE__ */ new Set();
2525
+ const resultList = [];
2526
+ for (const item of iterA) if (!seen.has(item) && setB.has(item)) {
2527
+ seen.add(item);
2528
+ resultList.push(item);
2529
+ }
2530
+ return resultList;
2531
+ };
2532
+ var _intersectionBy = async (arg0, arg1, arg2) => {
2533
+ const selector = arg0;
2534
+ const iterA = arg1;
2535
+ const iterB = arg2;
2536
+ const keysB = /* @__PURE__ */ new Set();
2537
+ for (const item of iterB) {
2538
+ const key = await selector(item);
2539
+ keysB.add(key);
2540
+ }
2541
+ const seen = /* @__PURE__ */ new Set();
2542
+ const resultList = [];
2543
+ for (const item of iterA) {
2544
+ const key = await selector(item);
2545
+ if (!seen.has(key) && keysB.has(key)) {
2546
+ seen.add(key);
2547
+ resultList.push(item);
2548
+ }
2549
+ }
2550
+ return resultList;
2551
+ };
2552
+ var _difference = (arg0, arg1) => {
2553
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2554
+ const difference = arg0.difference;
2555
+ if (typeof difference === "function") return Array.from(difference.call(arg0, arg1));
2556
+ }
2557
+ const iterA = arg0;
2558
+ const setB = new Set(arg1);
2559
+ const seen = /* @__PURE__ */ new Set();
2560
+ const resultList = [];
2561
+ for (const item of iterA) if (!seen.has(item) && !setB.has(item)) {
2562
+ seen.add(item);
2563
+ resultList.push(item);
2564
+ }
2565
+ return resultList;
2566
+ };
2567
+ var _differenceBy = async (arg0, arg1, arg2) => {
2568
+ const selector = arg0;
2569
+ const iterA = arg1;
2570
+ const iterB = arg2;
2571
+ const keysB = /* @__PURE__ */ new Set();
2572
+ for (const item of iterB) {
2573
+ const key = await selector(item);
2574
+ keysB.add(key);
2575
+ }
2576
+ const seen = /* @__PURE__ */ new Set();
2577
+ const resultList = [];
2578
+ for (const item of iterA) {
2579
+ const key = await selector(item);
2580
+ if (!seen.has(key) && !keysB.has(key)) {
2581
+ seen.add(key);
2582
+ resultList.push(item);
2583
+ }
2584
+ }
2585
+ return resultList;
2586
+ };
2587
+ var _symmetricDifference = (arg0, arg1) => {
2588
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2589
+ const symmetricDifference = arg0.symmetricDifference;
2590
+ if (typeof symmetricDifference === "function") return Array.from(symmetricDifference.call(arg0, arg1));
2591
+ }
2592
+ const iterA = arg0;
2593
+ const iterB = arg1;
2594
+ const itemsA = [];
2595
+ const itemsB = [];
2596
+ const setA = /* @__PURE__ */ new Set();
2597
+ const setB = /* @__PURE__ */ new Set();
2598
+ for (const item of iterA) if (!setA.has(item)) {
2599
+ setA.add(item);
2600
+ itemsA.push(item);
2601
+ }
2602
+ for (const item of iterB) if (!setB.has(item)) {
2603
+ setB.add(item);
2604
+ itemsB.push(item);
2605
+ }
2606
+ const resultList = [];
2607
+ for (const item of itemsA) if (!setB.has(item)) resultList.push(item);
2608
+ for (const item of itemsB) if (!setA.has(item)) resultList.push(item);
2609
+ return resultList;
2610
+ };
2611
+ var _symmetricDifferenceBy = async (arg0, arg1, arg2) => {
2612
+ const selector = arg0;
2613
+ const iterA = arg1;
2614
+ const iterB = arg2;
2615
+ const keysA = /* @__PURE__ */ new Set();
2616
+ const keysB = /* @__PURE__ */ new Set();
2617
+ const itemsA = [];
2618
+ const itemsB = [];
2619
+ for (const item of iterA) {
2620
+ const key = await selector(item);
2621
+ if (!keysA.has(key)) {
2622
+ keysA.add(key);
2623
+ itemsA.push({
2624
+ key,
2625
+ item
2626
+ });
2627
+ }
2628
+ }
2629
+ for (const item of iterB) {
2630
+ const key = await selector(item);
2631
+ if (!keysB.has(key)) {
2632
+ keysB.add(key);
2633
+ itemsB.push({
2634
+ key,
2635
+ item
2636
+ });
2637
+ }
2638
+ }
2639
+ const resultList = [];
2640
+ for (const entry of itemsA) if (!keysB.has(entry.key)) resultList.push(entry.item);
2641
+ for (const entry of itemsB) if (!keysA.has(entry.key)) resultList.push(entry.item);
2642
+ return resultList;
2643
+ };
2644
+ var _isSubsetOf = (arg0, arg1) => {
2645
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2646
+ const isSubsetOf = arg0.isSubsetOf;
2647
+ if (typeof isSubsetOf === "function") return isSubsetOf.call(arg0, arg1);
2648
+ }
2649
+ const iterA = arg0;
2650
+ const setB = new Set(arg1);
2651
+ const seen = /* @__PURE__ */ new Set();
2652
+ for (const item of iterA) {
2653
+ if (seen.has(item)) continue;
2654
+ seen.add(item);
2655
+ if (!setB.has(item)) return false;
2656
+ }
2657
+ return true;
2658
+ };
2659
+ var _isSubsetOfBy = async (arg0, arg1, arg2) => {
2660
+ const selector = arg0;
2661
+ const iterA = arg1;
2662
+ const iterB = arg2;
2663
+ const keysB = /* @__PURE__ */ new Set();
2664
+ for (const item of iterB) {
2665
+ const key = await selector(item);
2666
+ keysB.add(key);
2667
+ }
2668
+ const seen = /* @__PURE__ */ new Set();
2669
+ for (const item of iterA) {
2670
+ const key = await selector(item);
2671
+ if (seen.has(key)) continue;
2672
+ seen.add(key);
2673
+ if (!keysB.has(key)) return false;
2674
+ }
2675
+ return true;
2676
+ };
2677
+ var _isSupersetOf = (arg0, arg1) => {
2678
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2679
+ const isSupersetOf = arg0.isSupersetOf;
2680
+ if (typeof isSupersetOf === "function") return isSupersetOf.call(arg0, arg1);
2681
+ }
2682
+ const setA = new Set(arg0);
2683
+ for (const item of arg1) if (!setA.has(item)) return false;
2684
+ return true;
2685
+ };
2686
+ var _isSupersetOfBy = async (arg0, arg1, arg2) => {
2687
+ const selector = arg0;
2688
+ const iterA = arg1;
2689
+ const iterB = arg2;
2690
+ const keysA = /* @__PURE__ */ new Set();
2691
+ for (const item of iterA) {
2692
+ const key = await selector(item);
2693
+ keysA.add(key);
2694
+ }
2695
+ const seen = /* @__PURE__ */ new Set();
2696
+ for (const item of iterB) {
2697
+ const key = await selector(item);
2698
+ if (seen.has(key)) continue;
2699
+ seen.add(key);
2700
+ if (!keysA.has(key)) return false;
2701
+ }
2702
+ return true;
2703
+ };
2704
+ var _isDisjointFrom = (arg0, arg1) => {
2705
+ if (arg0 instanceof Set && arg1 instanceof Set) {
2706
+ const isDisjointFrom = arg0.isDisjointFrom;
2707
+ if (typeof isDisjointFrom === "function") return isDisjointFrom.call(arg0, arg1);
2708
+ }
2709
+ const setB = new Set(arg1);
2710
+ for (const item of arg0) if (setB.has(item)) return false;
2711
+ return true;
2712
+ };
2713
+ var _isDisjointFromBy = async (arg0, arg1, arg2) => {
2714
+ const selector = arg0;
2715
+ const iterA = arg1;
2716
+ const iterB = arg2;
2717
+ const keysB = /* @__PURE__ */ new Set();
2718
+ for (const item of iterB) {
2719
+ const key = await selector(item);
2720
+ keysB.add(key);
2721
+ }
2722
+ for (const item of iterA) {
2723
+ const key = await selector(item);
2724
+ if (keysB.has(key)) return false;
2725
+ }
2726
+ return true;
2727
+ };
2728
+ var _reduce = async (arg0, arg1, arg2) => {
2729
+ let acc = arg0;
2730
+ const predicate = arg1;
2731
+ const iter = arg2;
2732
+ for (const item of iter) acc = await predicate(acc, item);
2733
+ return acc;
2734
+ };
2735
+ var _match = (arg0, arg1) => {
2736
+ const re = arg0 instanceof RegExp ? arg0 : new RegExp(convertToString(arg0), "g");
2737
+ return convertToString(arg1).match(re);
2738
+ };
2739
+ var _replace = (arg0, arg1, arg2) => {
2740
+ const re = arg0 instanceof RegExp ? arg0 : new RegExp(convertToString(arg0), "g");
2741
+ const replace = convertToString(arg1);
2742
+ return convertToString(arg2).replace(re, replace);
2743
+ };
2744
+ var _regex = (arg0, arg1) => {
2745
+ if (arg1) return new RegExp(convertToString(arg0), convertToString(arg1));
2746
+ else return new RegExp(convertToString(arg0));
2747
+ };
2748
+ var _bind = (arg0, ...args) => {
2749
+ return arg0.bind(void 0, ...args);
2750
+ };
2751
+ var _url = (arg0, arg1) => {
2752
+ return new URL(convertToString(arg0), arg1 !== void 0 ? convertToString(arg1) : void 0);
2753
+ };
2754
+ var _delay = async function(ms, value) {
2755
+ const delayMs = Number(ms);
2756
+ const signal = this.abortSignal;
2757
+ if (!signal) return await new Promise((resolve) => {
2758
+ setTimeout(resolve, delayMs, value);
2759
+ });
2760
+ signal.throwIfAborted();
2761
+ return await new Promise((resolve, reject) => {
2762
+ let timer;
2763
+ const cleanup = () => {
2764
+ if (timer !== void 0) {
2765
+ clearTimeout(timer);
2766
+ timer = void 0;
2767
+ }
2768
+ signal.removeEventListener("abort", onAbort);
2769
+ };
2770
+ const onAbort = () => {
2771
+ cleanup();
2772
+ try {
2773
+ signal.throwIfAborted();
2774
+ } catch (error) {
2775
+ reject(error);
2776
+ return;
2777
+ }
2778
+ const abortError = /* @__PURE__ */ new Error("Aborted");
2779
+ abortError.name = "AbortError";
2780
+ reject(abortError);
2781
+ };
2782
+ timer = setTimeout(() => {
2783
+ if (signal.aborted) {
2784
+ onAbort();
2785
+ return;
2786
+ }
2787
+ cleanup();
2788
+ resolve(value);
2789
+ }, delayMs);
2790
+ signal.addEventListener("abort", onAbort, { once: true });
2791
+ });
2792
+ };
2793
+ var createIncludeFunction = (options) => {
2794
+ const { resolve, logs, mode = "template", scope = "child", includeMissing = "error", tryIncludeMissing = "empty" } = options;
2795
+ let compileCacheModulePromise;
2796
+ const getCompileCacheModule = async () => {
2797
+ var _compileCacheModulePr;
2798
+ (_compileCacheModulePr = compileCacheModulePromise) !== null && _compileCacheModulePr !== void 0 || (compileCacheModulePromise = Promise.resolve().then(() => compile_cache_exports));
2799
+ return await compileCacheModulePromise;
2800
+ };
2801
+ const parseScript = async (script, sourceId) => {
2802
+ const { compileScriptCached } = await getCompileCacheModule();
2803
+ return compileScriptCached(script, sourceId, mode, "reducer");
2804
+ };
2805
+ const resolveSource = async (request, context) => {
2806
+ const resolved = await resolve(request, context);
2807
+ if (resolved === void 0 || resolved === null) return;
2808
+ if (typeof resolved === "string") return {
2809
+ sourceId: request,
2810
+ script: resolved
2811
+ };
2812
+ return resolved;
2813
+ };
2814
+ const normalizeIncludeStack = (includeStack, sourceId) => includeStack[includeStack.length - 1] === sourceId ? includeStack : [...includeStack, sourceId];
2815
+ const throwPrimaryParseError = (parseLogs) => {
2816
+ let primaryError;
2817
+ for (const entry of parseLogs) if (entry.type === "error" && primaryError === void 0) primaryError = entry;
2818
+ else logs.push(entry);
2819
+ if ((primaryError === null || primaryError === void 0 ? void 0 : primaryError.type) === "error") throw new FunCityReducerError(primaryError);
2820
+ };
2821
+ const withSameScopeIncludeFunctions = async (context, includeFunctions, run) => {
2822
+ const previousInclude = context.getValue("include");
2823
+ const previousTryInclude = context.getValue("tryInclude");
2824
+ context.setValue("include", includeFunctions.include);
2825
+ context.setValue("tryInclude", includeFunctions.tryInclude);
2826
+ try {
2827
+ return await run();
2828
+ } finally {
2829
+ if (previousInclude.isFound) context.setValue("include", previousInclude.value);
2830
+ if (previousTryInclude.isFound) context.setValue("tryInclude", previousTryInclude.value);
2831
+ }
2832
+ };
2833
+ const installIncludeFunctions = (context, includeFunctions, signal) => {
2834
+ context.setValue("include", includeFunctions.include, signal);
2835
+ context.setValue("tryInclude", includeFunctions.tryInclude, signal);
2836
+ };
2837
+ const reduceWithScope = async (context, nodes, includeFunctions) => {
2838
+ if (scope === "same") return await withSameScopeIncludeFunctions(context, includeFunctions, () => context.reduceBlock(nodes));
2839
+ const scopedContext = context.newScope();
2840
+ installIncludeFunctions(scopedContext, includeFunctions, context.abortSignal);
2841
+ const resultList = [];
2842
+ for (const node of nodes) {
2843
+ const results = await scopedContext.reduceNode(node, context.abortSignal);
2844
+ for (const result of results) if (result !== void 0) resultList.push(result);
2845
+ }
2846
+ return resultList;
2847
+ };
2848
+ const createIncludeFunctions = (includeStack) => {
2849
+ const renderIncluded = async (context, arg0, missingBehavior) => {
2850
+ if (!arg0) throw new FunCityReducerError({
2851
+ type: "error",
2852
+ description: "Required `include` target",
2853
+ range: context.thisNode.range
2854
+ });
2855
+ const resolvedArg = await context.reduce(arg0);
2856
+ if (resolvedArg === void 0 || resolvedArg === null) {
2857
+ if (missingBehavior === "empty") return "";
2858
+ throw new FunCityReducerError({
2859
+ type: "error",
2860
+ description: "Required `include` target",
2861
+ range: context.thisNode.range
2862
+ });
2863
+ }
2864
+ const request = String(resolvedArg);
2865
+ const activeIncludeStack = normalizeIncludeStack(includeStack, context.thisNode.range.sourceId);
2866
+ const source = await resolveSource(request, {
2867
+ sourceId: context.thisNode.range.sourceId,
2868
+ range: context.thisNode.range,
2869
+ signal: context.abortSignal
2870
+ });
2871
+ if (!source) {
2872
+ if (missingBehavior === "empty") return "";
2873
+ throw new FunCityReducerError({
2874
+ type: "error",
2875
+ description: `Include source not found: ${request}`,
2876
+ range: context.thisNode.range
2877
+ });
2878
+ }
2879
+ if (activeIncludeStack.includes(source.sourceId)) throw new FunCityReducerError({
2880
+ type: "error",
2881
+ description: `circular include detected: ${source.sourceId}`,
2882
+ range: context.thisNode.range
2883
+ });
2884
+ const parsed = await parseScript(source.script, source.sourceId);
2885
+ if (parsed.logs.length > 0) throwPrimaryParseError(parsed.logs);
2886
+ const nestedIncludeFunctions = createIncludeFunctions([...activeIncludeStack, source.sourceId]);
2887
+ return (await reduceWithScope(context, parsed.nodes, nestedIncludeFunctions)).map((value) => context.convertToString(value)).join("");
2888
+ };
2889
+ return {
2890
+ include: makeFunCityFunction(async function(arg0) {
2891
+ return await renderIncluded(this, arg0, includeMissing);
2892
+ }),
2893
+ tryInclude: makeFunCityFunction(async function(arg0) {
2894
+ return await renderIncluded(this, arg0, tryIncludeMissing);
2895
+ })
2896
+ };
2897
+ };
2898
+ return createIncludeFunctions([]);
2899
+ };
2900
+ /**
2901
+ * Built-in standard variables and functions.
2902
+ */
2903
+ var standardVariables = Object.freeze({
2904
+ undefined: void 0,
2905
+ null: null,
2906
+ true: true,
2907
+ false: false,
2908
+ cond: _cond,
2909
+ defaults: _defaults,
2910
+ set: _set,
2911
+ new: _new,
2912
+ fun: _fun,
2913
+ toString: _toString,
2914
+ toBoolean: _toBoolean,
2915
+ toNumber: _toNumber,
2916
+ toBigInt: _toBigInt,
2917
+ typeof: _typeof,
2918
+ add: _add,
2919
+ sub: _sub,
2920
+ mul: _mul,
2921
+ div: _div,
2922
+ mod: _mod,
2923
+ eq: _eq,
2924
+ ne: _ne,
2925
+ lt: _lt,
2926
+ gt: _gt,
2927
+ le: _le,
2928
+ ge: _ge,
2929
+ now: _now,
2930
+ random: _random,
2931
+ randomf: _randomf,
2932
+ concat: _concat,
2933
+ join: _join,
2934
+ trim: _trim,
2935
+ toUpper: _toUpper,
2936
+ toLower: _toLower,
2937
+ length: _length,
2938
+ and: _and,
2939
+ or: _or,
2940
+ not: _not,
2941
+ at: _at,
2942
+ first: _first,
2943
+ last: _last,
2944
+ range: _range,
2945
+ slice: _slice,
2946
+ sort: _sort,
2947
+ reverse: _reverse,
2948
+ map: _map,
2949
+ flatMap: _flatMap,
2950
+ flatten: _flatten,
2951
+ filter: _filter,
2952
+ collect: _collect,
2953
+ distinct: _distinct,
2954
+ distinctBy: _distinctBy,
2955
+ union: _union,
2956
+ unionBy: _unionBy,
2957
+ intersection: _intersection,
2958
+ intersectionBy: _intersectionBy,
2959
+ difference: _difference,
2960
+ differenceBy: _differenceBy,
2961
+ symmetricDifference: _symmetricDifference,
2962
+ symmetricDifferenceBy: _symmetricDifferenceBy,
2963
+ isSubsetOf: _isSubsetOf,
2964
+ isSubsetOfBy: _isSubsetOfBy,
2965
+ isSupersetOf: _isSupersetOf,
2966
+ isSupersetOfBy: _isSupersetOfBy,
2967
+ isDisjointFrom: _isDisjointFrom,
2968
+ isDisjointFromBy: _isDisjointFromBy,
2969
+ reduce: _reduce,
2970
+ match: _match,
2971
+ replace: _replace,
2972
+ regex: _regex,
2973
+ bind: _bind,
2974
+ url: _url,
2975
+ delay: _delay,
2976
+ console
2977
+ });
2978
+ /**
2979
+ * Build a variable map that includes standard variables.
2980
+ * @param variablesList - Additional variable sources.
2981
+ * @returns Combined variable map.
2982
+ */
2983
+ var buildCandidateVariables = (...variablesList) => {
2984
+ return combineVariables(standardVariables, ...variablesList);
2985
+ };
2986
+ //#endregion
2987
+ //#region src/dcodegen.ts
2988
+ var throwError = (info) => {
2989
+ throw new FunCityReducerError({
2990
+ type: "error",
2991
+ ...info
2992
+ });
2993
+ };
2994
+ var deconstructConditionalCombine = (name) => {
2995
+ if (name.length >= 1) {
2996
+ if (name[name.length - 1] === "?") return {
2997
+ name: name.substring(0, name.length - 1),
2998
+ canIgnore: true
2999
+ };
3000
+ }
3001
+ return {
3002
+ name,
3003
+ canIgnore: false
3004
+ };
3005
+ };
3006
+ var extractLambdaParameterNames = (node) => {
3007
+ switch (node.kind) {
3008
+ case "variable": return [node.name];
3009
+ case "list": {
3010
+ const names = [];
3011
+ for (const item of node.items) {
3012
+ if (item.kind !== "variable") return;
3013
+ names.push(item.name);
3014
+ }
3015
+ return names;
3016
+ }
3017
+ default: return;
3018
+ }
3019
+ };
3020
+ var resolveVariable = (context, result, range, signal) => {
3021
+ const valueResult = context.getValue(result.name, signal);
3022
+ if (!valueResult.isFound) {
3023
+ if (!result.canIgnore) throwError({
3024
+ description: `variable is not bound: ${result.name}`,
3025
+ range
3026
+ });
3027
+ return;
3028
+ }
3029
+ return valueResult.value;
3030
+ };
3031
+ var filterUndefined = (results) => results.filter((result) => result !== void 0);
3032
+ var resolveMaybePromise = (value, onResolved) => {
3033
+ if (isPromiseLike(value)) return value.then((resolved) => onResolved(resolved));
3034
+ return onResolved(value);
3035
+ };
3036
+ var specializableStandardCallTargets = Object.freeze({
3037
+ toString: standardVariables.toString,
3038
+ toBoolean: standardVariables.toBoolean,
3039
+ toNumber: standardVariables.toNumber,
3040
+ toBigInt: standardVariables.toBigInt,
3041
+ typeof: standardVariables.typeof,
3042
+ add: standardVariables.add,
3043
+ sub: standardVariables.sub,
3044
+ mul: standardVariables.mul,
3045
+ div: standardVariables.div,
3046
+ mod: standardVariables.mod,
3047
+ eq: standardVariables.eq,
3048
+ ne: standardVariables.ne,
3049
+ lt: standardVariables.lt,
3050
+ gt: standardVariables.gt,
3051
+ le: standardVariables.le,
3052
+ ge: standardVariables.ge,
3053
+ now: standardVariables.now,
3054
+ randomf: standardVariables.randomf,
3055
+ concat: standardVariables.concat,
3056
+ join: standardVariables.join,
3057
+ trim: standardVariables.trim,
3058
+ toUpper: standardVariables.toUpper,
3059
+ toLower: standardVariables.toLower,
3060
+ length: standardVariables.length,
3061
+ not: standardVariables.not,
3062
+ at: standardVariables.at,
3063
+ first: standardVariables.first,
3064
+ last: standardVariables.last,
3065
+ range: standardVariables.range,
3066
+ slice: standardVariables.slice,
3067
+ sort: standardVariables.sort,
3068
+ reverse: standardVariables.reverse,
3069
+ map: standardVariables.map,
3070
+ flatMap: standardVariables.flatMap,
3071
+ flatten: standardVariables.flatten,
3072
+ filter: standardVariables.filter,
3073
+ collect: standardVariables.collect,
3074
+ distinct: standardVariables.distinct,
3075
+ distinctBy: standardVariables.distinctBy,
3076
+ union: standardVariables.union,
3077
+ unionBy: standardVariables.unionBy,
3078
+ intersection: standardVariables.intersection,
3079
+ intersectionBy: standardVariables.intersectionBy,
3080
+ difference: standardVariables.difference,
3081
+ differenceBy: standardVariables.differenceBy,
3082
+ symmetricDifference: standardVariables.symmetricDifference,
3083
+ symmetricDifferenceBy: standardVariables.symmetricDifferenceBy,
3084
+ isSubsetOf: standardVariables.isSubsetOf,
3085
+ isSubsetOfBy: standardVariables.isSubsetOfBy,
3086
+ isSupersetOf: standardVariables.isSupersetOf,
3087
+ isSupersetOfBy: standardVariables.isSupersetOfBy,
3088
+ isDisjointFrom: standardVariables.isDisjointFrom,
3089
+ isDisjointFromBy: standardVariables.isDisjointFromBy,
3090
+ reduce: standardVariables.reduce,
3091
+ match: standardVariables.match,
3092
+ replace: standardVariables.replace,
3093
+ regex: standardVariables.regex,
3094
+ bind: standardVariables.bind,
3095
+ url: standardVariables.url
3096
+ });
3097
+ var toSpecializableStandardCallTarget = (name) => {
3098
+ return specializableStandardCallTargets[name];
3099
+ };
3100
+ var AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
3101
+ var createRawBlockRunnerImmediate = (generators) => {
3102
+ return (context, signal) => {
3103
+ const resultList = [];
3104
+ for (let index = 0; index < generators.length; index++) {
3105
+ const results = generators[index](context, signal);
3106
+ if (isPromiseLike(results)) return (async () => {
3107
+ resultList.push(...await results);
3108
+ for (let continueIndex = index + 1; continueIndex < generators.length; continueIndex++) resultList.push(...await generators[continueIndex](context, signal));
3109
+ return resultList;
3110
+ })();
3111
+ resultList.push(...results);
3112
+ }
3113
+ return resultList;
3114
+ };
3115
+ };
3116
+ var createTextBlockRunnerImmediate = (generators) => {
3117
+ return (context, signal) => {
3118
+ let result = "";
3119
+ for (let index = 0; index < generators.length; index++) {
3120
+ const text = generators[index](context, signal);
3121
+ if (isPromiseLike(text)) return (async () => {
3122
+ result += await text;
3123
+ for (let continueIndex = index + 1; continueIndex < generators.length; continueIndex++) result += await generators[continueIndex](context, signal);
3124
+ return result;
3125
+ })();
3126
+ result += text;
3127
+ }
3128
+ return result;
3129
+ };
3130
+ };
3131
+ var collectExpressionValues = (generators, context, signal) => {
3132
+ const resultList = [];
3133
+ for (let index = 0; index < generators.length; index++) {
3134
+ const result = generators[index](context, signal);
3135
+ if (isPromiseLike(result)) return (async () => {
3136
+ resultList.push(await result);
3137
+ for (let continueIndex = index + 1; continueIndex < generators.length; continueIndex++) resultList.push(await generators[continueIndex](context, signal));
3138
+ return resultList;
3139
+ })();
3140
+ resultList.push(result);
3141
+ }
3142
+ return resultList;
3143
+ };
3144
+ var handleApplyError = (node, error) => {
3145
+ if (error instanceof FunCityReducerError) throw error;
3146
+ if (error instanceof Error && error.name === "AbortError") throw error;
3147
+ throw new FunCityReducerError({
3148
+ type: "error",
3149
+ description: fromError(error),
3150
+ range: node.range
3151
+ });
3152
+ };
3153
+ var resolveSourceVariable = (context, name, canIgnore, range, signal) => {
3154
+ const valueResult = context.getValue(name, signal);
3155
+ if (!valueResult.isFound) {
3156
+ if (!canIgnore) throwError({
3157
+ description: `variable is not bound: ${name}`,
3158
+ range
3159
+ });
3160
+ return;
3161
+ }
3162
+ return valueResult.value;
3163
+ };
3164
+ var resolveSourceDotSegments = (context, baseValue, segments) => {
3165
+ let value = baseValue;
3166
+ let parent;
3167
+ for (const segment of segments) {
3168
+ if (value !== null && (typeof value === "object" || typeof value === "function")) {
3169
+ const record = value;
3170
+ parent = value;
3171
+ value = record[segment.name];
3172
+ continue;
3173
+ }
3174
+ if (!segment.canIgnore) throwError({
3175
+ description: `variable is not bound: ${segment.name}`,
3176
+ range: segment.range
3177
+ });
3178
+ return;
3179
+ }
3180
+ if (parent && typeof value === "function" && !isFunCityFunction(value)) return context.getBoundFunction(parent, value);
3181
+ return value;
3182
+ };
3183
+ var invokeSourceCallable = async (context, node, signal, callable, args, _isSpecial) => {
3184
+ try {
3185
+ const thisProxy = context.createFunctionContext(node, signal);
3186
+ return await callable.call(thisProxy, ...args);
3187
+ } catch (error) {
3188
+ return handleApplyError(node, error);
3189
+ }
3190
+ };
3191
+ var invokeSourceBuiltin = async (node, builtin, args) => {
3192
+ try {
3193
+ return await builtin(...args);
3194
+ } catch (error) {
3195
+ return handleApplyError(node, error);
3196
+ }
3197
+ };
3198
+ /**
3199
+ * Create a dynamic code generator.
3200
+ * @returns Dynamic code generator instance.
3201
+ */
3202
+ var createClosureDCodegen = () => {
3203
+ const expressionImmediateCache = /* @__PURE__ */ new WeakMap();
3204
+ const expressionCache = /* @__PURE__ */ new WeakMap();
3205
+ const blockImmediateCache = /* @__PURE__ */ new WeakMap();
3206
+ const blockCache = /* @__PURE__ */ new WeakMap();
3207
+ const rawProgramImmediateCache = /* @__PURE__ */ new WeakMap();
3208
+ const textBlockImmediateCache = /* @__PURE__ */ new WeakMap();
3209
+ const textProgramImmediateCache = /* @__PURE__ */ new WeakMap();
3210
+ const textProgramCache = /* @__PURE__ */ new WeakMap();
3211
+ const programImmediateCache = /* @__PURE__ */ new WeakMap();
3212
+ const programCache = /* @__PURE__ */ new WeakMap();
3213
+ const generateRawProgramImmediate = (nodes) => {
3214
+ const cached = rawProgramImmediateCache.get(nodes);
3215
+ if (cached) return cached;
3216
+ const generator = createRawBlockRunnerImmediate(nodes.map(generateBlockImmediate));
3217
+ rawProgramImmediateCache.set(nodes, generator);
3218
+ return generator;
3219
+ };
3220
+ const generateTextProgramImmediate = (nodes) => {
3221
+ const cached = textProgramImmediateCache.get(nodes);
3222
+ if (cached) return cached;
3223
+ const generator = createTextBlockRunnerImmediate(nodes.map(generateTextBlockImmediate));
3224
+ textProgramImmediateCache.set(nodes, generator);
3225
+ return generator;
3226
+ };
3227
+ const resolveDotNode = (context, node, signal, compiledBase, baseResult) => {
3228
+ var _node$segments$0$opti, _node$segments$;
3229
+ signal === null || signal === void 0 || signal.throwIfAborted();
3230
+ const firstSegmentOptional = (_node$segments$0$opti = (_node$segments$ = node.segments[0]) === null || _node$segments$ === void 0 ? void 0 : _node$segments$.optional) !== null && _node$segments$0$opti !== void 0 ? _node$segments$0$opti : false;
3231
+ const resolveSegments = (baseValue) => {
3232
+ let value = baseValue;
3233
+ let parent;
3234
+ for (const segment of node.segments) {
3235
+ const result = deconstructConditionalCombine(segment.name);
3236
+ const isOptional = segment.optional || result.canIgnore;
3237
+ if (value !== null && (typeof value === "object" || typeof value === "function")) {
3238
+ const record = value;
3239
+ parent = value;
3240
+ value = record[result.name];
3241
+ } else {
3242
+ if (!isOptional) throwError({
3243
+ description: `variable is not bound: ${result.name}`,
3244
+ range: segment.range
3245
+ });
3246
+ return;
3247
+ }
3248
+ }
3249
+ if (parent && typeof value === "function" && !isFunCityFunction(value)) return context.getBoundFunction(parent, value);
3250
+ return value;
3251
+ };
3252
+ if (baseResult) {
3253
+ const valueResult = context.getValue(baseResult.name, signal);
3254
+ if (!valueResult.isFound) {
3255
+ if (!baseResult.canIgnore && !firstSegmentOptional) throwError({
3256
+ description: `variable is not bound: ${baseResult.name}`,
3257
+ range: node.base.range
3258
+ });
3259
+ return;
3260
+ }
3261
+ return resolveSegments(valueResult.value);
3262
+ }
3263
+ if (!compiledBase) return;
3264
+ return resolveMaybePromise(compiledBase(context, signal), resolveSegments);
3265
+ };
3266
+ const applyResolvedFunction = (context, node, signal, callable, compiledArgs) => {
3267
+ const resolvedArgs = isFunCityFunction(callable) ? node.args : collectExpressionValues(compiledArgs, context, signal);
3268
+ const invokeCallable = (args) => {
3269
+ try {
3270
+ const thisProxy = context.createFunctionContext(node, signal);
3271
+ return callable.call(thisProxy, ...args);
3272
+ } catch (error) {
3273
+ handleApplyError(node, error);
3274
+ }
3275
+ };
3276
+ const result = resolveMaybePromise(resolvedArgs, (args) => invokeCallable(args));
3277
+ if (isPromiseLike(result)) return result.catch((error) => handleApplyError(node, error));
3278
+ return result;
3279
+ };
3280
+ const applySpecializedStandardFunction = (context, node, signal, builtin, compiledArgs) => {
3281
+ const invokeBuiltin = (args) => {
3282
+ try {
3283
+ return builtin(...args);
3284
+ } catch (error) {
3285
+ handleApplyError(node, error);
3286
+ }
3287
+ };
3288
+ const result = resolveMaybePromise(collectExpressionValues(compiledArgs, context, signal), (args) => invokeBuiltin(args));
3289
+ if (isPromiseLike(result)) return result.catch((error) => handleApplyError(node, error));
3290
+ return result;
3291
+ };
3292
+ const applyFunction = (context, node, signal, compiledFunc, compiledArgs) => {
3293
+ signal === null || signal === void 0 || signal.throwIfAborted();
3294
+ return resolveMaybePromise(compiledFunc(context, signal), (func) => {
3295
+ if (typeof func !== "function") throwError({
3296
+ description: "could not apply it for function",
3297
+ range: node.range
3298
+ });
3299
+ return applyResolvedFunction(context, node, signal, func, compiledArgs);
3300
+ });
3301
+ };
3302
+ const generateExpressionImmediate = (node) => {
3303
+ const cached = expressionImmediateCache.get(node);
3304
+ if (cached) return cached;
3305
+ let generator;
3306
+ switch (node.kind) {
3307
+ case "number":
3308
+ case "string":
3309
+ generator = () => node.value;
3310
+ break;
3311
+ case "template": {
3312
+ const generatedText = generateTextProgramImmediate(node.blocks);
3313
+ generator = (context, signal) => generatedText(context, signal);
3314
+ break;
3315
+ }
3316
+ case "variable": {
3317
+ const variableResult = deconstructConditionalCombine(node.name);
3318
+ generator = (context, signal) => resolveVariable(context, variableResult, node.range, signal);
3319
+ break;
3320
+ }
3321
+ case "dot": {
3322
+ const compiledBase = node.base.kind === "variable" ? void 0 : generateExpressionImmediate(node.base);
3323
+ const baseResult = node.base.kind === "variable" ? deconstructConditionalCombine(node.base.name) : void 0;
3324
+ generator = (context, signal) => resolveDotNode(context, node, signal, compiledBase, baseResult);
3325
+ break;
3326
+ }
3327
+ case "apply": {
3328
+ const compiledFunc = generateExpressionImmediate(node.func);
3329
+ const compiledArgs = node.args.map(generateExpressionImmediate);
3330
+ const isIntrinsicCond = node.func.kind === "variable" && node.func.name === "cond" && node.args.length === 3;
3331
+ const intrinsicFunParameters = node.func.kind === "variable" && node.func.name === "fun" && node.args.length === 2 ? extractLambdaParameterNames(node.args[0]) : void 0;
3332
+ const intrinsicFunBody = intrinsicFunParameters !== void 0 ? node.args[1] : void 0;
3333
+ const compiledIntrinsicFunBody = intrinsicFunBody !== void 0 ? generateExpressionImmediate(intrinsicFunBody) : void 0;
3334
+ const specializedBuiltinName = node.func.kind === "variable" ? node.func.name : void 0;
3335
+ const specializedBuiltin = specializedBuiltinName !== void 0 ? toSpecializableStandardCallTarget(specializedBuiltinName) : void 0;
3336
+ if (isIntrinsicCond) {
3337
+ generator = (context, signal) => {
3338
+ const boundFunction = context.getValue("cond", signal);
3339
+ if (boundFunction.isFound && boundFunction.value === standardVariables.cond) return resolveMaybePromise(compiledArgs[0](context, signal), (condition) => isConditionalTrue(condition) ? compiledArgs[1](context, signal) : compiledArgs[2](context, signal));
3340
+ return applyFunction(context, node, signal, compiledFunc, compiledArgs);
3341
+ };
3342
+ break;
3343
+ }
3344
+ if (compiledIntrinsicFunBody !== void 0 && intrinsicFunParameters !== void 0) {
3345
+ generator = (context, signal) => {
3346
+ const boundFunction = context.getValue("fun", signal);
3347
+ if (boundFunction.isFound && boundFunction.value === standardVariables.fun) return (...args) => {
3348
+ if (args.length < intrinsicFunParameters.length) throwError({
3349
+ description: `Arguments are not filled: ${args.length} < ${intrinsicFunParameters.length}`,
3350
+ range: node.range
3351
+ });
3352
+ if (args.length > intrinsicFunParameters.length) context.appendWarning({
3353
+ type: "warning",
3354
+ description: `Too many arguments: ${args.length} > ${intrinsicFunParameters.length}`,
3355
+ range: node.range
3356
+ });
3357
+ return compiledIntrinsicFunBody(context.newCallScope(intrinsicFunParameters, args, signal), signal);
3358
+ };
3359
+ if (specializedBuiltin === void 0) return applyFunction(context, node, signal, compiledFunc, compiledArgs);
3360
+ const specializedFunction = context.getValue(specializedBuiltinName, signal);
3361
+ if (specializedFunction.isFound && specializedFunction.value === specializedBuiltin) return applySpecializedStandardFunction(context, node, signal, specializedBuiltin, compiledArgs);
3362
+ return applyFunction(context, node, signal, compiledFunc, compiledArgs);
3363
+ };
3364
+ break;
3365
+ }
3366
+ if (specializedBuiltin === void 0) {
3367
+ generator = (context, signal) => applyFunction(context, node, signal, compiledFunc, compiledArgs);
3368
+ break;
3369
+ }
3370
+ generator = (context, signal) => {
3371
+ const boundFunction = context.getValue(specializedBuiltinName, signal);
3372
+ if (boundFunction.isFound && boundFunction.value === specializedBuiltin) return applySpecializedStandardFunction(context, node, signal, specializedBuiltin, compiledArgs);
3373
+ return applyFunction(context, node, signal, compiledFunc, compiledArgs);
3374
+ };
3375
+ break;
3376
+ }
3377
+ case "list": {
3378
+ const compiledItems = node.items.map(generateExpressionImmediate);
3379
+ generator = (context, signal) => collectExpressionValues(compiledItems, context, signal);
3380
+ break;
3381
+ }
3382
+ case "scope": {
3383
+ const compiledNodes = node.nodes.map(generateExpressionImmediate);
3384
+ generator = (context, signal) => {
3385
+ if (compiledNodes.length === 0) return [];
3386
+ let result = void 0;
3387
+ for (let index = 0; index < compiledNodes.length; index++) {
3388
+ const current = compiledNodes[index](context, signal);
3389
+ if (isPromiseLike(current)) return (async () => {
3390
+ result = await current;
3391
+ for (let continueIndex = index + 1; continueIndex < compiledNodes.length; continueIndex++) result = await compiledNodes[continueIndex](context, signal);
3392
+ return result;
3393
+ })();
3394
+ result = current;
3395
+ }
3396
+ return result;
3397
+ };
3398
+ break;
3399
+ }
3400
+ }
3401
+ expressionImmediateCache.set(node, generator);
3402
+ return generator;
3403
+ };
3404
+ const generateExpression = (node) => {
3405
+ const cached = expressionCache.get(node);
3406
+ if (cached) return cached;
3407
+ const immediate = generateExpressionImmediate(node);
3408
+ const generator = (context, signal) => Promise.resolve(immediate(context, signal));
3409
+ expressionCache.set(node, generator);
3410
+ return generator;
3411
+ };
3412
+ const generateBlockImmediate = (node) => {
3413
+ const cached = blockImmediateCache.get(node);
3414
+ if (cached) return cached;
3415
+ let generator;
3416
+ switch (node.kind) {
3417
+ case "text":
3418
+ generator = () => [node.text];
3419
+ break;
3420
+ case "for": {
3421
+ const iterableGenerator = generateExpressionImmediate(node.iterable);
3422
+ const repeatGenerator = generateRawProgramImmediate(node.repeat);
3423
+ generator = (context, signal) => resolveMaybePromise(iterableGenerator(context, signal), (result) => {
3424
+ const iterable = asIterable(result);
3425
+ if (!iterable) throwError({
3426
+ description: "could not apply it for function",
3427
+ range: node.range
3428
+ });
3429
+ const resolvedIterable = iterable;
3430
+ const resultList = [];
3431
+ const iterator = resolvedIterable[Symbol.iterator]();
3432
+ for (let current = iterator.next(); !current.done; current = iterator.next()) {
3433
+ context.setValue(node.bind.name, current.value, signal);
3434
+ const repeated = repeatGenerator(context, signal);
3435
+ if (isPromiseLike(repeated)) return (async () => {
3436
+ resultList.push(...await repeated);
3437
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
3438
+ context.setValue(node.bind.name, next.value, signal);
3439
+ resultList.push(...await repeatGenerator(context, signal));
3440
+ }
3441
+ return resultList;
3442
+ })();
3443
+ resultList.push(...repeated);
3444
+ }
3445
+ return resultList;
3446
+ });
3447
+ break;
3448
+ }
3449
+ case "while": {
3450
+ const conditionGenerator = generateExpressionImmediate(node.condition);
3451
+ const repeatGenerator = generateRawProgramImmediate(node.repeat);
3452
+ generator = (context, signal) => {
3453
+ const resultList = [];
3454
+ while (true) {
3455
+ const condition = conditionGenerator(context, signal);
3456
+ if (isPromiseLike(condition)) return (async () => {
3457
+ let currentCondition = await condition;
3458
+ while (isConditionalTrue(currentCondition)) {
3459
+ resultList.push(...await repeatGenerator(context, signal));
3460
+ currentCondition = await conditionGenerator(context, signal);
3461
+ }
3462
+ return resultList;
3463
+ })();
3464
+ if (!isConditionalTrue(condition)) return resultList;
3465
+ const repeated = repeatGenerator(context, signal);
3466
+ if (isPromiseLike(repeated)) return (async () => {
3467
+ resultList.push(...await repeated);
3468
+ while (true) {
3469
+ if (!isConditionalTrue(await conditionGenerator(context, signal))) break;
3470
+ resultList.push(...await repeatGenerator(context, signal));
3471
+ }
3472
+ return resultList;
3473
+ })();
3474
+ resultList.push(...repeated);
3475
+ }
3476
+ };
3477
+ break;
3478
+ }
3479
+ case "if": {
3480
+ const conditionGenerator = generateExpressionImmediate(node.condition);
3481
+ const thenGenerator = generateRawProgramImmediate(node.then);
3482
+ const elseGenerator = generateRawProgramImmediate(node.else);
3483
+ generator = (context, signal) => resolveMaybePromise(conditionGenerator(context, signal), (condition) => isConditionalTrue(condition) ? thenGenerator(context, signal) : elseGenerator(context, signal));
3484
+ break;
3485
+ }
3486
+ default: {
3487
+ const expressionGenerator = generateExpressionImmediate(node);
3488
+ generator = (context, signal) => resolveMaybePromise(expressionGenerator(context, signal), (result) => [result]);
3489
+ break;
3490
+ }
3491
+ }
3492
+ blockImmediateCache.set(node, generator);
3493
+ return generator;
3494
+ };
3495
+ const generateBlock = (node) => {
3496
+ const cached = blockCache.get(node);
3497
+ if (cached) return cached;
3498
+ const immediate = generateBlockImmediate(node);
3499
+ const generator = (context, signal) => Promise.resolve(immediate(context, signal));
3500
+ blockCache.set(node, generator);
3501
+ return generator;
3502
+ };
3503
+ const generateTextBlockImmediate = (node) => {
3504
+ const cached = textBlockImmediateCache.get(node);
3505
+ if (cached) return cached;
3506
+ let generator;
3507
+ switch (node.kind) {
3508
+ case "text":
3509
+ generator = () => node.text;
3510
+ break;
3511
+ case "for": {
3512
+ const iterableGenerator = generateExpressionImmediate(node.iterable);
3513
+ const repeatGenerator = generateTextProgramImmediate(node.repeat);
3514
+ generator = (context, signal) => resolveMaybePromise(iterableGenerator(context, signal), (result) => {
3515
+ const iterable = asIterable(result);
3516
+ if (!iterable) throwError({
3517
+ description: "could not apply it for function",
3518
+ range: node.range
3519
+ });
3520
+ const iterator = iterable[Symbol.iterator]();
3521
+ let text = "";
3522
+ for (let current = iterator.next(); !current.done; current = iterator.next()) {
3523
+ context.setValue(node.bind.name, current.value, signal);
3524
+ const repeated = repeatGenerator(context, signal);
3525
+ if (isPromiseLike(repeated)) return (async () => {
3526
+ text += await repeated;
3527
+ for (let next = iterator.next(); !next.done; next = iterator.next()) {
3528
+ context.setValue(node.bind.name, next.value, signal);
3529
+ text += await repeatGenerator(context, signal);
3530
+ }
3531
+ return text;
3532
+ })();
3533
+ text += repeated;
3534
+ }
3535
+ return text;
3536
+ });
3537
+ break;
3538
+ }
3539
+ case "while": {
3540
+ const conditionGenerator = generateExpressionImmediate(node.condition);
3541
+ const repeatGenerator = generateTextProgramImmediate(node.repeat);
3542
+ generator = (context, signal) => {
3543
+ let text = "";
3544
+ while (true) {
3545
+ const condition = conditionGenerator(context, signal);
3546
+ if (isPromiseLike(condition)) return (async () => {
3547
+ let currentCondition = await condition;
3548
+ while (isConditionalTrue(currentCondition)) {
3549
+ text += await repeatGenerator(context, signal);
3550
+ currentCondition = await conditionGenerator(context, signal);
3551
+ }
3552
+ return text;
3553
+ })();
3554
+ if (!isConditionalTrue(condition)) return text;
3555
+ const repeated = repeatGenerator(context, signal);
3556
+ if (isPromiseLike(repeated)) return (async () => {
3557
+ text += await repeated;
3558
+ while (true) {
3559
+ if (!isConditionalTrue(await conditionGenerator(context, signal))) break;
3560
+ text += await repeatGenerator(context, signal);
3561
+ }
3562
+ return text;
3563
+ })();
3564
+ text += repeated;
3565
+ }
3566
+ };
3567
+ break;
3568
+ }
3569
+ case "if": {
3570
+ const conditionGenerator = generateExpressionImmediate(node.condition);
3571
+ const thenGenerator = generateTextProgramImmediate(node.then);
3572
+ const elseGenerator = generateTextProgramImmediate(node.else);
3573
+ generator = (context, signal) => resolveMaybePromise(conditionGenerator(context, signal), (condition) => isConditionalTrue(condition) ? thenGenerator(context, signal) : elseGenerator(context, signal));
3574
+ break;
3575
+ }
3576
+ default: {
3577
+ const expressionGenerator = generateExpressionImmediate(node);
3578
+ generator = (context, signal) => resolveMaybePromise(expressionGenerator(context, signal), (result) => result === void 0 ? "" : context.convertToString(result));
3579
+ break;
3580
+ }
3581
+ }
3582
+ textBlockImmediateCache.set(node, generator);
3583
+ return generator;
3584
+ };
3585
+ const generateProgramImmediate = (nodes) => {
3586
+ const cached = programImmediateCache.get(nodes);
3587
+ if (cached) return cached;
3588
+ const generatedBlocks = generateRawProgramImmediate(nodes);
3589
+ const generator = (context, signal) => resolveMaybePromise(generatedBlocks(context, signal), (results) => filterUndefined(results));
3590
+ programImmediateCache.set(nodes, generator);
3591
+ return generator;
3592
+ };
3593
+ const generateProgram = (nodes) => {
3594
+ const cached = programCache.get(nodes);
3595
+ if (cached) return cached;
3596
+ const immediate = generateProgramImmediate(nodes);
3597
+ const generator = (context, signal) => Promise.resolve(immediate(context, signal));
3598
+ programCache.set(nodes, generator);
3599
+ return generator;
3600
+ };
3601
+ const generateTextProgram = (nodes) => {
3602
+ const cached = textProgramCache.get(nodes);
3603
+ if (cached) return cached;
3604
+ const immediate = generateTextProgramImmediate(nodes);
3605
+ const generator = (context, signal) => Promise.resolve(immediate(context, signal));
3606
+ textProgramCache.set(nodes, generator);
3607
+ return generator;
3608
+ };
3609
+ const createExecutor = () => {
3610
+ const reduceExpressionNodeImmediate = (context, node, signal) => generateExpressionImmediate(node)(context, signal);
3611
+ const reduceNodeImmediate = (context, node, signal) => generateBlockImmediate(node)(context, signal);
3612
+ return {
3613
+ reduceExpressionNode: (context, node, signal) => Promise.resolve(reduceExpressionNodeImmediate(context, node, signal)),
3614
+ reduceExpressionNodeImmediate,
3615
+ reduceNode: (context, node, signal) => Promise.resolve(reduceNodeImmediate(context, node, signal)),
3616
+ reduceNodeImmediate
3617
+ };
3618
+ };
3619
+ return {
3620
+ generateExpression,
3621
+ generateBlock,
3622
+ generateProgram,
3623
+ generateTextProgram,
3624
+ createExecutor
3625
+ };
3626
+ };
3627
+ var createSourceRunner = (body) => {
3628
+ return new AsyncFunction("context", "signal", "runtime", `'use strict';\n${body}`);
3629
+ };
3630
+ var stripAbortChecksFromSource = (body) => {
3631
+ return body.replace(/(^|\n)signal\?\.throwIfAborted\(\);\n?/g, "$1");
3632
+ };
3633
+ var createAdaptiveSourceRunner = (body) => {
3634
+ const runnerWithSignal = createSourceRunner(body);
3635
+ const runnerWithoutSignal = createSourceRunner(stripAbortChecksFromSource(body));
3636
+ return (context, signal, runtime) => signal === void 0 ? runnerWithoutSignal(context, void 0, runtime) : runnerWithSignal(context, signal, runtime);
3637
+ };
3638
+ var createSourceDCodegen = (options) => {
3639
+ var _options$aggressiveOp;
3640
+ const closureExecutor = createClosureDCodegen().createExecutor();
3641
+ const aggressiveOptimize = (_options$aggressiveOp = options === null || options === void 0 ? void 0 : options.aggressiveOptimize) !== null && _options$aggressiveOp !== void 0 ? _options$aggressiveOp : false;
3642
+ const expressionCache = /* @__PURE__ */ new WeakMap();
3643
+ const blockCache = /* @__PURE__ */ new WeakMap();
3644
+ const programCache = /* @__PURE__ */ new WeakMap();
3645
+ const textProgramCache = /* @__PURE__ */ new WeakMap();
3646
+ const addConstant = (state, value) => {
3647
+ const index = state.constants.length;
3648
+ state.constants.push(value);
3649
+ return index;
3650
+ };
3651
+ const allocateTemp = (state, prefix) => {
3652
+ return `__${prefix}${state.nextTempId++}`;
3653
+ };
3654
+ const emptyCompileScope = {
3655
+ localSlots: /* @__PURE__ */ new Map(),
3656
+ directBindings: /* @__PURE__ */ new Map(),
3657
+ selfBindings: /* @__PURE__ */ new Map()
3658
+ };
3659
+ const extendCompileScope = (scope, name, slotVar) => {
3660
+ return {
3661
+ localSlots: new Map(scope.localSlots).set(name, slotVar),
3662
+ directBindings: scope.directBindings,
3663
+ selfBindings: scope.selfBindings
3664
+ };
3665
+ };
3666
+ const extendDirectBindingCompileScope = (scope, name, bindingRef) => {
3667
+ return {
3668
+ localSlots: scope.localSlots,
3669
+ directBindings: new Map(scope.directBindings).set(name, bindingRef),
3670
+ selfBindings: scope.selfBindings
3671
+ };
3672
+ };
3673
+ const extendSelfBindingCompileScope = (scope, name, bindingRef) => {
3674
+ return {
3675
+ localSlots: scope.localSlots,
3676
+ directBindings: scope.directBindings,
3677
+ selfBindings: new Map(scope.selfBindings).set(name, bindingRef)
3678
+ };
3679
+ };
3680
+ const resolveLocalSlotRef = (scope, name) => {
3681
+ return scope.localSlots.get(name);
3682
+ };
3683
+ const resolveSelfBindingRef = (scope, name) => {
3684
+ return scope.selfBindings.get(name);
3685
+ };
3686
+ const resolveDirectBindingRef = (scope, name) => {
3687
+ return scope.directBindings.get(name);
3688
+ };
3689
+ const createLookupResultSource = (scope, name) => {
3690
+ const localSlotRef = resolveLocalSlotRef(scope, name);
3691
+ return localSlotRef !== void 0 ? `{ isFound: true, value: context.getSlotValue(${localSlotRef}, signal) }` : `context.getValue(${JSON.stringify(name)}, signal)`;
3692
+ };
3693
+ const resolveAggressiveVariableSource = (state, name) => {
3694
+ if (!state.aggressiveOptimize) return;
3695
+ switch (name) {
3696
+ case "undefined": return "undefined";
3697
+ case "null": return "null";
3698
+ case "true": return "true";
3699
+ case "false": return "false";
3700
+ case "cond": return "runtime.standardIntrinsics.cond";
3701
+ case "fun": return "runtime.standardIntrinsics.fun";
3702
+ case "set": return "runtime.standardIntrinsics.set";
3703
+ case "add":
3704
+ case "sub":
3705
+ case "mul":
3706
+ case "div":
3707
+ case "mod":
3708
+ case "eq":
3709
+ case "ne":
3710
+ case "lt":
3711
+ case "gt":
3712
+ case "le":
3713
+ case "ge":
3714
+ case "not": return `runtime.standardBuiltins.${name}`;
3715
+ case "and":
3716
+ case "or": return `runtime.constants[${addConstant(state, standardVariables[name])}]`;
3717
+ case "range":
3718
+ case "map":
3719
+ case "filter":
3720
+ case "reduce": return `runtime.standardBuiltins.${name}`;
3721
+ default: return;
3722
+ }
3723
+ };
3724
+ const canExpressionSuspend = (node) => {
3725
+ switch (node.kind) {
3726
+ case "number":
3727
+ case "string":
3728
+ case "variable": return false;
3729
+ case "template": return canBlockListSuspend(node.blocks);
3730
+ case "dot": return canExpressionSuspend(node.base);
3731
+ case "apply": return true;
3732
+ case "list": return node.items.some((item) => canExpressionSuspend(item));
3733
+ case "scope": return node.nodes.some((childNode) => canExpressionSuspend(childNode));
3734
+ }
3735
+ };
3736
+ const canBlockSuspend = (node) => {
3737
+ switch (node.kind) {
3738
+ case "text": return false;
3739
+ case "for": return canExpressionSuspend(node.iterable) || canBlockListSuspend(node.repeat);
3740
+ case "while": return canExpressionSuspend(node.condition) || canBlockListSuspend(node.repeat);
3741
+ case "if": return canExpressionSuspend(node.condition) || canBlockListSuspend(node.then) || canBlockListSuspend(node.else);
3742
+ default: return canExpressionSuspend(node);
3743
+ }
3744
+ };
3745
+ const canBlockListSuspend = (nodes) => {
3746
+ return nodes.some((node) => canBlockSuspend(node));
3747
+ };
3748
+ const expressionContainsSetForName = (node, name) => {
3749
+ switch (node.kind) {
3750
+ case "number":
3751
+ case "string":
3752
+ case "variable": return false;
3753
+ case "template": return blockListContainsSetForName(node.blocks, name);
3754
+ case "dot": return expressionContainsSetForName(node.base, name);
3755
+ case "apply":
3756
+ var _node$args$;
3757
+ if (node.func.kind === "variable" && node.func.name === "set" && ((_node$args$ = node.args[0]) === null || _node$args$ === void 0 ? void 0 : _node$args$.kind) === "variable" && node.args[0].name === name) return true;
3758
+ if (expressionContainsSetForName(node.func, name)) return true;
3759
+ return node.args.some((arg) => expressionContainsSetForName(arg, name));
3760
+ case "list": return node.items.some((item) => expressionContainsSetForName(item, name));
3761
+ case "scope": return node.nodes.some((childNode) => blockContainsSetForName(childNode, name));
3762
+ }
3763
+ };
3764
+ const blockContainsSetForName = (node, name) => {
3765
+ switch (node.kind) {
3766
+ case "text": return false;
3767
+ case "for": return expressionContainsSetForName(node.iterable, name) || blockListContainsSetForName(node.repeat, name);
3768
+ case "while": return expressionContainsSetForName(node.condition, name) || blockListContainsSetForName(node.repeat, name);
3769
+ case "if": return expressionContainsSetForName(node.condition, name) || blockListContainsSetForName(node.then, name) || blockListContainsSetForName(node.else, name);
3770
+ default: return expressionContainsSetForName(node, name);
3771
+ }
3772
+ };
3773
+ const blockListContainsSetForName = (nodes, name) => {
3774
+ return nodes.some((node) => blockContainsSetForName(node, name));
3775
+ };
3776
+ const wrapAwaitedSource = (source, canSuspend) => {
3777
+ return canSuspend ? `await (${source})` : `(${source})`;
3778
+ };
3779
+ const wrapSourceClosure = (body, canSuspend) => {
3780
+ return canSuspend ? `(async () => {\n${body}\n})()` : `(() => {\n${body}\n})()`;
3781
+ };
3782
+ const getBuiltinArgSource = (argVars, index) => {
3783
+ var _argVars$index;
3784
+ return (_argVars$index = argVars[index]) !== null && _argVars$index !== void 0 ? _argVars$index : "undefined";
3785
+ };
3786
+ const compileNumericFoldSource = (argVars, operator) => {
3787
+ const initial = `Number(${getBuiltinArgSource(argVars, 0)})`;
3788
+ return argVars.slice(1).reduce((expression, argVar) => `(${expression} ${operator} Number(${argVar}))`, initial);
3789
+ };
3790
+ const compileInlineStandardBuiltinSource = (name, argVars) => {
3791
+ switch (name) {
3792
+ case "toString": return `[${argVars.map((argVar) => `context.convertToString(${argVar})`).join(", ")}].join(',')`;
3793
+ case "toBoolean": return `runtime.isConditionalTrue(${getBuiltinArgSource(argVars, 0)})`;
3794
+ case "toNumber": return `Number(${getBuiltinArgSource(argVars, 0)})`;
3795
+ case "toBigInt": return `(() => {
3796
+ const __value = ${getBuiltinArgSource(argVars, 0)};
3797
+ switch (typeof __value) {
3798
+ case 'number':
3799
+ case 'bigint':
3800
+ case 'string':
3801
+ case 'boolean':
3802
+ return BigInt(__value);
3803
+ default:
3804
+ return BigInt(context.convertToString(__value));
3805
+ }
3806
+ })()`;
3807
+ case "typeof": return `(() => {
3808
+ const __value = ${getBuiltinArgSource(argVars, 0)};
3809
+ if (__value === null) {
3810
+ return 'null';
3811
+ }
3812
+ if (typeof __value === 'string') {
3813
+ return 'string';
3814
+ }
3815
+ if (Array.isArray(__value)) {
3816
+ return 'array';
3817
+ }
3818
+ if (runtime.asIterable(__value)) {
3819
+ return 'iterable';
3820
+ }
3821
+ return typeof __value;
3822
+ })()`;
3823
+ case "add": return compileNumericFoldSource(argVars, "+");
3824
+ case "sub": return compileNumericFoldSource(argVars, "-");
3825
+ case "mul": return compileNumericFoldSource(argVars, "*");
3826
+ case "div": return compileNumericFoldSource(argVars, "/");
3827
+ case "mod": return compileNumericFoldSource(argVars, "%");
3828
+ case "eq": return `(${getBuiltinArgSource(argVars, 0)} === ${getBuiltinArgSource(argVars, 1)})`;
3829
+ case "ne": return `(${getBuiltinArgSource(argVars, 0)} !== ${getBuiltinArgSource(argVars, 1)})`;
3830
+ case "lt": return `(${getBuiltinArgSource(argVars, 0)} < ${getBuiltinArgSource(argVars, 1)})`;
3831
+ case "gt": return `(${getBuiltinArgSource(argVars, 0)} > ${getBuiltinArgSource(argVars, 1)})`;
3832
+ case "le": return `(${getBuiltinArgSource(argVars, 0)} <= ${getBuiltinArgSource(argVars, 1)})`;
3833
+ case "ge": return `(${getBuiltinArgSource(argVars, 0)} >= ${getBuiltinArgSource(argVars, 1)})`;
3834
+ case "not": return `(!runtime.isConditionalTrue(${getBuiltinArgSource(argVars, 0)}))`;
3835
+ case "trim": return `(() => {
3836
+ let __value = ${getBuiltinArgSource(argVars, 0)};
3837
+ if (__value === undefined || __value === null) {
3838
+ __value = '';
3839
+ } else if (typeof __value !== 'string') {
3840
+ __value = __value.toString() ?? '';
3841
+ }
3842
+ return __value.trim();
3843
+ })()`;
3844
+ case "toUpper": return `(() => {
3845
+ let __value = ${getBuiltinArgSource(argVars, 0)};
3846
+ if (typeof __value !== 'string') {
3847
+ __value = __value.toString() ?? '';
3848
+ }
3849
+ return __value.toUpperCase();
3850
+ })()`;
3851
+ case "toLower": return `(() => {
3852
+ let __value = ${getBuiltinArgSource(argVars, 0)};
3853
+ if (typeof __value !== 'string') {
3854
+ __value = __value.toString() ?? '';
3855
+ }
3856
+ return __value.toLowerCase();
3857
+ })()`;
3858
+ case "length": return `(() => {
3859
+ const __value = ${getBuiltinArgSource(argVars, 0)};
3860
+ if (!__value) {
3861
+ return 0;
3862
+ }
3863
+ if (typeof __value === 'string' || Array.isArray(__value)) {
3864
+ return __value.length;
3865
+ }
3866
+ const __iterable = runtime.asIterable(__value);
3867
+ if (!__iterable) {
3868
+ return 0;
3869
+ }
3870
+ let __count = 0;
3871
+ for (const __item of __iterable) {
3872
+ __count++;
3873
+ }
3874
+ return __count;
3875
+ })()`;
3876
+ case "at": return `(() => {
3877
+ const __index = Number(${getBuiltinArgSource(argVars, 0)});
3878
+ const __value = ${getBuiltinArgSource(argVars, 1)};
3879
+ if (!__value) {
3880
+ return undefined;
3881
+ }
3882
+ if (typeof __value === 'string' || Array.isArray(__value)) {
3883
+ return __value[__index];
3884
+ }
3885
+ const __iterable = runtime.asIterable(__value);
3886
+ if (!__iterable) {
3887
+ return undefined;
3888
+ }
3889
+ let __current = 0;
3890
+ for (const __item of __iterable) {
3891
+ if (__current >= __index) {
3892
+ return __item;
3893
+ }
3894
+ __current++;
3895
+ }
3896
+ return undefined;
3897
+ })()`;
3898
+ case "first": return `(() => {
3899
+ const __value = ${getBuiltinArgSource(argVars, 0)};
3900
+ if (!__value) {
3901
+ return undefined;
3902
+ }
3903
+ if (typeof __value === 'string' || Array.isArray(__value)) {
3904
+ return __value[0];
3905
+ }
3906
+ const __iterable = runtime.asIterable(__value);
3907
+ if (!__iterable) {
3908
+ return undefined;
3909
+ }
3910
+ for (const __item of __iterable) {
3911
+ return __item;
3912
+ }
3913
+ return undefined;
3914
+ })()`;
3915
+ case "last": return `(() => {
3916
+ const __value = ${getBuiltinArgSource(argVars, 0)};
3917
+ if (!__value) {
3918
+ return undefined;
3919
+ }
3920
+ if (typeof __value === 'string' || Array.isArray(__value)) {
3921
+ return __value[__value.length - 1];
3922
+ }
3923
+ const __iterable = runtime.asIterable(__value);
3924
+ if (!__iterable) {
3925
+ return undefined;
3926
+ }
3927
+ let __lastItem = undefined;
3928
+ for (const __item of __iterable) {
3929
+ __lastItem = __item;
3930
+ }
3931
+ return __lastItem;
3932
+ })()`;
3933
+ case "slice": {
3934
+ const startSource = getBuiltinArgSource(argVars, 0);
3935
+ const middleSource = getBuiltinArgSource(argVars, 1);
3936
+ const tailSource = getBuiltinArgSource(argVars, 2);
3937
+ return `(() => {
3938
+ const __start = ${startSource} === undefined ? undefined : Number(${startSource});
3939
+ if (${tailSource} === undefined) {
3940
+ const __value = ${middleSource};
3941
+ if (typeof __value === 'string') {
3942
+ return __value.slice(__start);
3943
+ }
3944
+ return Array.from(__value).slice(__start, undefined);
3945
+ }
3946
+ const __end = ${middleSource} === undefined ? undefined : Number(${middleSource});
3947
+ const __value = ${tailSource};
3948
+ if (typeof __value === 'string') {
3949
+ return __value.slice(__start, __end);
3950
+ }
3951
+ return Array.from(__value).slice(__start, __end);
3952
+ })()`;
3953
+ }
3954
+ default: return;
3955
+ }
3956
+ };
3957
+ const compileDirectInlineBuiltinApplySource = (state, node, scope, name) => {
3958
+ const builtinArgVars = node.args.map(() => allocateTemp(state, "arg"));
3959
+ const inlineBuiltinSource = compileInlineStandardBuiltinSource(name, builtinArgVars);
3960
+ if (inlineBuiltinSource === void 0) return;
3961
+ return wrapSourceClosure(`signal?.throwIfAborted();
3962
+ ${node.args.map((arg, index) => {
3963
+ const argSource = compileExpressionSource(state, arg, scope);
3964
+ return `const ${builtinArgVars[index]} = ${wrapAwaitedSource(argSource, canExpressionSuspend(arg))};`;
3965
+ }).join("\n")}
3966
+ return ${inlineBuiltinSource};`, node.args.some((arg) => canExpressionSuspend(arg)));
3967
+ };
3968
+ const compileDirectLogicalApplySource = (state, node, scope, kind) => {
3969
+ const rangeIndex = addConstant(state, node.range);
3970
+ if (node.args.length === 0) return wrapSourceClosure(`signal?.throwIfAborted();
3971
+ runtime.throwError({ description: 'empty arguments', range: runtime.constants[${rangeIndex}] });`, false);
3972
+ const valueVars = node.args.map(() => allocateTemp(state, "value"));
3973
+ return wrapSourceClosure(`signal?.throwIfAborted();
3974
+ ${node.args.map((arg, index) => {
3975
+ const valueVar = valueVars[index];
3976
+ const argSource = compileExpressionSource(state, arg, scope);
3977
+ const condition = kind === "and" ? `!runtime.isConditionalTrue(${valueVar})` : `runtime.isConditionalTrue(${valueVar})`;
3978
+ const result = kind === "and" ? "false" : "true";
3979
+ return `const ${valueVar} = ${wrapAwaitedSource(argSource, canExpressionSuspend(arg))};
3980
+ if (${condition}) {
3981
+ return ${result};
3982
+ }`;
3983
+ }).join("\n")}
3984
+ return ${kind === "and" ? "true" : "false"};`, node.args.some((arg) => canExpressionSuspend(arg)));
3985
+ };
3986
+ const compileDirectRangeApplySource = (state, node, scope) => {
3987
+ const startVar = allocateTemp(state, "start");
3988
+ const countVar = allocateTemp(state, "count");
3989
+ const resultVar = allocateTemp(state, "range");
3990
+ const indexVar = allocateTemp(state, "index");
3991
+ return wrapSourceClosure(`signal?.throwIfAborted();
3992
+ let ${startVar} = Number(${node.args[0] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[0], scope), canExpressionSuspend(node.args[0]))});
3993
+ const ${countVar} = Number(${node.args[1] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[1], scope), canExpressionSuspend(node.args[1]))});
3994
+ const ${resultVar} = [];
3995
+ for (let ${indexVar} = 0; ${indexVar} < ${countVar}; ${indexVar}++) {
3996
+ ${resultVar}.push(${startVar}++);
3997
+ }
3998
+ return ${resultVar};`, node.args[0] !== void 0 && canExpressionSuspend(node.args[0]) || node.args[1] !== void 0 && canExpressionSuspend(node.args[1]));
3999
+ };
4000
+ const compileDirectCollectionApplySource = (state, node, scope, name) => {
4001
+ if (name === "map") {
4002
+ const mapperVar = allocateTemp(state, "mapper");
4003
+ const iterableVar = allocateTemp(state, "iterable");
4004
+ const resultVar = allocateTemp(state, "mapped");
4005
+ const itemVar = allocateTemp(state, "item");
4006
+ return wrapSourceClosure(`signal?.throwIfAborted();
4007
+ const ${mapperVar} = ${node.args[0] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[0], scope), canExpressionSuspend(node.args[0]))};
4008
+ const ${iterableVar} = ${node.args[1] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[1], scope), canExpressionSuspend(node.args[1]))};
4009
+ const ${resultVar} = [];
4010
+ for (const ${itemVar} of ${iterableVar}) {
4011
+ ${resultVar}.push(await ${mapperVar}(${itemVar}));
4012
+ }
4013
+ return ${resultVar};`, true);
4014
+ }
4015
+ if (name === "filter") {
4016
+ const predicateVar = allocateTemp(state, "predicate");
4017
+ const iterableVar = allocateTemp(state, "iterable");
4018
+ const resultVar = allocateTemp(state, "filtered");
4019
+ const itemVar = allocateTemp(state, "item");
4020
+ return wrapSourceClosure(`signal?.throwIfAborted();
4021
+ const ${predicateVar} = ${node.args[0] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[0], scope), canExpressionSuspend(node.args[0]))};
4022
+ const ${iterableVar} = ${node.args[1] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[1], scope), canExpressionSuspend(node.args[1]))};
4023
+ const ${resultVar} = [];
4024
+ for (const ${itemVar} of ${iterableVar}) {
4025
+ if (runtime.isConditionalTrue(await ${predicateVar}(${itemVar}))) {
4026
+ ${resultVar}.push(${itemVar});
4027
+ }
4028
+ }
4029
+ return ${resultVar};`, true);
4030
+ }
4031
+ const accVar = allocateTemp(state, "acc");
4032
+ const reducerVar = allocateTemp(state, "reducer");
4033
+ const iterableVar = allocateTemp(state, "iterable");
4034
+ const itemVar = allocateTemp(state, "item");
4035
+ return wrapSourceClosure(`signal?.throwIfAborted();
4036
+ let ${accVar} = ${node.args[0] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[0], scope), canExpressionSuspend(node.args[0]))};
4037
+ const ${reducerVar} = ${node.args[1] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[1], scope), canExpressionSuspend(node.args[1]))};
4038
+ const ${iterableVar} = ${node.args[2] === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, node.args[2], scope), canExpressionSuspend(node.args[2]))};
4039
+ for (const ${itemVar} of ${iterableVar}) {
4040
+ ${accVar} = await ${reducerVar}(${accVar}, ${itemVar});
4041
+ }
4042
+ return ${accVar};`, true);
4043
+ };
4044
+ const compileAggressiveApplySource = (state, node, scope) => {
4045
+ if (!state.aggressiveOptimize || node.func.kind !== "variable") return;
4046
+ switch (node.func.name) {
4047
+ case "add":
4048
+ case "sub":
4049
+ case "mul":
4050
+ case "div":
4051
+ case "mod":
4052
+ case "eq":
4053
+ case "ne":
4054
+ case "lt":
4055
+ case "gt":
4056
+ case "le":
4057
+ case "ge":
4058
+ case "not": return compileDirectInlineBuiltinApplySource(state, node, scope, node.func.name);
4059
+ case "and":
4060
+ case "or": return compileDirectLogicalApplySource(state, node, scope, node.func.name);
4061
+ case "range": return compileDirectRangeApplySource(state, node, scope);
4062
+ case "map":
4063
+ case "filter":
4064
+ case "reduce": return compileDirectCollectionApplySource(state, node, scope, node.func.name);
4065
+ default: return;
4066
+ }
4067
+ };
4068
+ const deconstructAggressiveRangeLoop = (state, node) => {
4069
+ if (!state.aggressiveOptimize || node.kind !== "apply") return;
4070
+ if (node.func.kind !== "variable" || node.func.name !== "range") return;
4071
+ return {
4072
+ startNode: node.args[0],
4073
+ countNode: node.args[1]
4074
+ };
4075
+ };
4076
+ const toNumberLiteral = (state, value) => {
4077
+ if (Object.is(value, -0)) return "-0";
4078
+ if (Number.isFinite(value)) return String(value);
4079
+ return `runtime.constants[${addConstant(state, value)}]`;
4080
+ };
4081
+ const createRuntime = (constants) => {
4082
+ return {
4083
+ constants,
4084
+ standardBuiltins: specializableStandardCallTargets,
4085
+ standardIntrinsics: {
4086
+ cond: standardVariables.cond,
4087
+ fun: standardVariables.fun,
4088
+ set: standardVariables.set
4089
+ },
4090
+ asIterable,
4091
+ isConditionalTrue,
4092
+ isFunCityFunction,
4093
+ throwError,
4094
+ handleApplyError,
4095
+ resolveVariable: resolveSourceVariable,
4096
+ resolveDotSegments: resolveSourceDotSegments,
4097
+ invokeCallable: invokeSourceCallable,
4098
+ invokeBuiltin: invokeSourceBuiltin
4099
+ };
4100
+ };
4101
+ const compileBlockStatements = (state, node, targetVar, filterUndefinedValues, scope) => {
4102
+ switch (node.kind) {
4103
+ case "text": return `${targetVar}.push(${JSON.stringify(node.text)});\n`;
4104
+ case "for": {
4105
+ const iterableVar = allocateTemp(state, "iterable");
4106
+ const slotVar = allocateTemp(state, "slot");
4107
+ const itemVar = allocateTemp(state, "item");
4108
+ const rangeIndex = addConstant(state, node.range);
4109
+ return `{
4110
+ const ${iterableVar} = runtime.asIterable(${wrapAwaitedSource(compileExpressionSource(state, node.iterable, scope), canExpressionSuspend(node.iterable))});
4111
+ if (!${iterableVar}) {
4112
+ runtime.throwError({ description: 'could not apply it for function', range: runtime.constants[${rangeIndex}] });
4113
+ }
4114
+ const ${slotVar} = context.ensureLocalSlot(${JSON.stringify(node.bind.name)}, signal);
4115
+ for (const ${itemVar} of ${iterableVar}) {
4116
+ context.setSlotValue(${slotVar}, ${itemVar}, signal);
4117
+ ${compileBlockListStatements(state, node.repeat, targetVar, filterUndefinedValues, extendCompileScope(scope, node.bind.name, slotVar))}
4118
+ }
4119
+ }\n`;
4120
+ }
4121
+ case "while": return `while (runtime.isConditionalTrue(${wrapAwaitedSource(compileExpressionSource(state, node.condition, scope), canExpressionSuspend(node.condition))})) {
4122
+ ${compileBlockListStatements(state, node.repeat, targetVar, filterUndefinedValues, scope)}
4123
+ }\n`;
4124
+ case "if": return `if (runtime.isConditionalTrue(${wrapAwaitedSource(compileExpressionSource(state, node.condition, scope), canExpressionSuspend(node.condition))})) {
4125
+ ${compileBlockListStatements(state, node.then, targetVar, filterUndefinedValues, scope)}
4126
+ } else {
4127
+ ${compileBlockListStatements(state, node.else, targetVar, filterUndefinedValues, scope)}
4128
+ }\n`;
4129
+ default: {
4130
+ const valueVar = allocateTemp(state, "value");
4131
+ return `{
4132
+ const ${valueVar} = ${wrapAwaitedSource(compileExpressionSource(state, node, scope), canExpressionSuspend(node))};
4133
+ ${filterUndefinedValues ? `if (${valueVar} !== undefined) { ${targetVar}.push(${valueVar}); }` : `${targetVar}.push(${valueVar});`}
4134
+ }\n`;
4135
+ }
4136
+ }
4137
+ };
4138
+ const compileBlockListStatements = (state, nodes, targetVar, filterUndefinedValues, scope) => {
4139
+ return nodes.map((node) => compileBlockStatements(state, node, targetVar, filterUndefinedValues, scope)).join("");
4140
+ };
4141
+ const compileTextBlockStatements = (state, node, targetVar, scope) => {
4142
+ switch (node.kind) {
4143
+ case "text": return `${targetVar} += ${JSON.stringify(node.text)};\n`;
4144
+ case "for": {
4145
+ const aggressiveRangeLoop = deconstructAggressiveRangeLoop(state, node.iterable);
4146
+ if (aggressiveRangeLoop !== void 0) {
4147
+ const startVar = allocateTemp(state, "start");
4148
+ const countVar = allocateTemp(state, "count");
4149
+ const indexVar = allocateTemp(state, "index");
4150
+ const itemVar = allocateTemp(state, "item");
4151
+ const startSource = aggressiveRangeLoop.startNode === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, aggressiveRangeLoop.startNode, scope), canExpressionSuspend(aggressiveRangeLoop.startNode));
4152
+ const countSource = aggressiveRangeLoop.countNode === void 0 ? "undefined" : wrapAwaitedSource(compileExpressionSource(state, aggressiveRangeLoop.countNode, scope), canExpressionSuspend(aggressiveRangeLoop.countNode));
4153
+ if (!blockListContainsSetForName(node.repeat, node.bind.name)) return `{
4154
+ let ${startVar} = Number(${startSource});
4155
+ const ${countVar} = Number(${countSource});
4156
+ for (let ${indexVar} = 0; ${indexVar} < ${countVar}; ${indexVar}++) {
4157
+ const ${itemVar} = ${startVar}++;
4158
+ ${compileTextBlockListStatements(state, node.repeat, targetVar, extendDirectBindingCompileScope(scope, node.bind.name, itemVar))}
4159
+ }
4160
+ }\n`;
4161
+ const slotVar = allocateTemp(state, "slot");
4162
+ return `{
4163
+ let ${startVar} = Number(${startSource});
4164
+ const ${countVar} = Number(${countSource});
4165
+ const ${slotVar} = context.ensureLocalSlot(${JSON.stringify(node.bind.name)}, signal);
4166
+ for (let ${indexVar} = 0; ${indexVar} < ${countVar}; ${indexVar}++) {
4167
+ const ${itemVar} = ${startVar}++;
4168
+ context.setSlotValue(${slotVar}, ${itemVar}, signal);
4169
+ ${compileTextBlockListStatements(state, node.repeat, targetVar, extendCompileScope(scope, node.bind.name, slotVar))}
4170
+ }
4171
+ }\n`;
4172
+ }
4173
+ const iterableVar = allocateTemp(state, "iterable");
4174
+ const slotVar = allocateTemp(state, "slot");
4175
+ const itemVar = allocateTemp(state, "item");
4176
+ const rangeIndex = addConstant(state, node.range);
4177
+ return `{
4178
+ const ${iterableVar} = runtime.asIterable(${wrapAwaitedSource(compileExpressionSource(state, node.iterable, scope), canExpressionSuspend(node.iterable))});
4179
+ if (!${iterableVar}) {
4180
+ runtime.throwError({ description: 'could not apply it for function', range: runtime.constants[${rangeIndex}] });
4181
+ }
4182
+ const ${slotVar} = context.ensureLocalSlot(${JSON.stringify(node.bind.name)}, signal);
4183
+ for (const ${itemVar} of ${iterableVar}) {
4184
+ context.setSlotValue(${slotVar}, ${itemVar}, signal);
4185
+ ${compileTextBlockListStatements(state, node.repeat, targetVar, extendCompileScope(scope, node.bind.name, slotVar))}
4186
+ }
4187
+ }\n`;
4188
+ }
4189
+ case "while": return `while (runtime.isConditionalTrue(${wrapAwaitedSource(compileExpressionSource(state, node.condition, scope), canExpressionSuspend(node.condition))})) {
4190
+ ${compileTextBlockListStatements(state, node.repeat, targetVar, scope)}
4191
+ }\n`;
4192
+ case "if": return `if (runtime.isConditionalTrue(${wrapAwaitedSource(compileExpressionSource(state, node.condition, scope), canExpressionSuspend(node.condition))})) {
4193
+ ${compileTextBlockListStatements(state, node.then, targetVar, scope)}
4194
+ } else {
4195
+ ${compileTextBlockListStatements(state, node.else, targetVar, scope)}
4196
+ }\n`;
4197
+ default: {
4198
+ const valueVar = allocateTemp(state, "value");
4199
+ const valueSource = compileExpressionSource(state, node, scope);
4200
+ if (state.aggressiveOptimize) return `{
4201
+ const ${valueVar} = ${wrapAwaitedSource(valueSource, canExpressionSuspend(node))};
4202
+ if (${valueVar} !== undefined) {
4203
+ if (${valueVar} === null) {
4204
+ ${targetVar} += '(null)';
4205
+ } else {
4206
+ switch (typeof ${valueVar}) {
4207
+ case 'string':
4208
+ ${targetVar} += ${valueVar};
4209
+ break;
4210
+ case 'boolean':
4211
+ case 'number':
4212
+ case 'bigint':
4213
+ case 'symbol':
4214
+ ${targetVar} += ${valueVar}.toString();
4215
+ break;
4216
+ default:
4217
+ ${targetVar} += context.convertToString(${valueVar});
4218
+ break;
4219
+ }
4220
+ }
4221
+ }
4222
+ }\n`;
4223
+ return `{
4224
+ const ${valueVar} = ${wrapAwaitedSource(valueSource, canExpressionSuspend(node))};
4225
+ if (${valueVar} !== undefined) {
4226
+ ${targetVar} += context.convertToString(${valueVar});
4227
+ }
4228
+ }\n`;
4229
+ }
4230
+ }
4231
+ };
4232
+ const compileTextBlockListStatements = (state, nodes, targetVar, scope) => {
4233
+ return nodes.map((node) => compileTextBlockStatements(state, node, targetVar, scope)).join("");
4234
+ };
4235
+ const compileIntrinsicLambdaSource = (state, lambdaRange, parameterNames, bodyNode, scope, selfBinding) => {
4236
+ const lambdaArgsVar = allocateTemp(state, "args");
4237
+ const lambdaContextVar = allocateTemp(state, "context");
4238
+ const rangeIndex = addConstant(state, lambdaRange);
4239
+ const parameterNamesIndex = addConstant(state, [...parameterNames]);
4240
+ const parameterSlotRefs = /* @__PURE__ */ new Map();
4241
+ for (const parameterName of parameterNames) if (!parameterSlotRefs.has(parameterName)) parameterSlotRefs.set(parameterName, String(parameterSlotRefs.size));
4242
+ const bodySource = compileExpressionSource(state, bodyNode, Array.from(parameterSlotRefs.entries()).reduce((currentScope, [parameterName, slotRef]) => extendCompileScope(currentScope, parameterName, slotRef), selfBinding === void 0 ? scope : extendSelfBindingCompileScope(scope, selfBinding.name, selfBinding.bindingRef)));
4243
+ return `(...${lambdaArgsVar}) => {
4244
+ if (${lambdaArgsVar}.length < ${parameterNames.length}) {
4245
+ runtime.throwError({ description: 'Arguments are not filled: ' + ${lambdaArgsVar}.length + ' < ${parameterNames.length}', range: runtime.constants[${rangeIndex}] });
4246
+ }
4247
+ if (${lambdaArgsVar}.length > ${parameterNames.length}) {
4248
+ context.appendWarning({ type: 'warning', description: 'Too many arguments: ' + ${lambdaArgsVar}.length + ' > ${parameterNames.length}', range: runtime.constants[${rangeIndex}] });
4249
+ }
4250
+ const ${lambdaContextVar} = context.newCallScope(runtime.constants[${parameterNamesIndex}], ${lambdaArgsVar}, signal);
4251
+ return ((context) => {
4252
+ return ${bodySource};
4253
+ })(${lambdaContextVar});
4254
+ }`;
4255
+ };
4256
+ const compileGenericApplySource = (state, node, scope) => {
4257
+ const applyNodeIndex = addConstant(state, node);
4258
+ const rangeIndex = addConstant(state, node.range);
4259
+ const argsNodeIndex = addConstant(state, node.args);
4260
+ const argArraySource = `[${node.args.map((arg) => wrapAwaitedSource(compileExpressionSource(state, arg, scope), canExpressionSuspend(arg))).join(", ")}]`;
4261
+ if (node.func.kind === "variable") {
4262
+ if (toSpecializableStandardCallTarget(node.func.name) !== void 0) {
4263
+ const bindingVar = allocateTemp(state, "binding");
4264
+ const funcVar = allocateTemp(state, "func");
4265
+ const callArgsVar = allocateTemp(state, "args");
4266
+ const builtinArgVars = node.args.map(() => allocateTemp(state, "arg"));
4267
+ const inlineBuiltinSource = compileInlineStandardBuiltinSource(node.func.name, builtinArgVars);
4268
+ const builtinArgStatements = node.args.map((arg, index) => {
4269
+ const argSource = compileExpressionSource(state, arg, scope);
4270
+ return `const ${builtinArgVars[index]} = ${wrapAwaitedSource(argSource, canExpressionSuspend(arg))};`;
4271
+ }).join("\n");
4272
+ return `(async () => {
4273
+ signal?.throwIfAborted();
4274
+ const ${bindingVar} = ${createLookupResultSource(scope, node.func.name)};
4275
+ if (${bindingVar}.isFound && ${bindingVar}.value === runtime.standardBuiltins.${node.func.name}) {
4276
+ ${builtinArgStatements}
4277
+ try {
4278
+ return ${inlineBuiltinSource !== null && inlineBuiltinSource !== void 0 ? inlineBuiltinSource : `await runtime.standardBuiltins.${node.func.name}(${builtinArgVars.join(", ")})`};
4279
+ } catch (error) {
4280
+ return runtime.handleApplyError(runtime.constants[${applyNodeIndex}], error);
4281
+ }
4282
+ }
4283
+ const ${funcVar} = ${bindingVar}.isFound
4284
+ ? ${bindingVar}.value
4285
+ : runtime.resolveVariable(context, ${JSON.stringify(node.func.name)}, false, runtime.constants[${addConstant(state, node.func.range)}], signal);
4286
+ if (typeof ${funcVar} !== 'function') {
4287
+ runtime.throwError({ description: 'could not apply it for function', range: runtime.constants[${rangeIndex}] });
4288
+ }
4289
+ if (runtime.isFunCityFunction(${funcVar})) {
4290
+ return runtime.invokeCallable(context, runtime.constants[${applyNodeIndex}], signal, ${funcVar}, runtime.constants[${argsNodeIndex}], true);
4291
+ }
4292
+ const ${callArgsVar} = ${argArraySource};
4293
+ return runtime.invokeCallable(context, runtime.constants[${applyNodeIndex}], signal, ${funcVar}, ${callArgsVar}, false);
4294
+ })()`;
4295
+ }
4296
+ }
4297
+ const funcVar = allocateTemp(state, "func");
4298
+ const argsVar = allocateTemp(state, "args");
4299
+ return `(async () => {
4300
+ signal?.throwIfAborted();
4301
+ const ${funcVar} = ${wrapAwaitedSource(compileExpressionSource(state, node.func, scope), canExpressionSuspend(node.func))};
4302
+ if (typeof ${funcVar} !== 'function') {
4303
+ runtime.throwError({ description: 'could not apply it for function', range: runtime.constants[${rangeIndex}] });
4304
+ }
4305
+ if (runtime.isFunCityFunction(${funcVar})) {
4306
+ return runtime.invokeCallable(context, runtime.constants[${applyNodeIndex}], signal, ${funcVar}, runtime.constants[${argsNodeIndex}], true);
4307
+ }
4308
+ const ${argsVar} = ${argArraySource};
4309
+ return runtime.invokeCallable(context, runtime.constants[${applyNodeIndex}], signal, ${funcVar}, ${argsVar}, false);
4310
+ })()`;
4311
+ };
4312
+ const compileExpressionSource = (state, node, scope) => {
4313
+ switch (node.kind) {
4314
+ case "number": return toNumberLiteral(state, node.value);
4315
+ case "string": return JSON.stringify(node.value);
4316
+ case "template": {
4317
+ const textVar = allocateTemp(state, "text");
4318
+ return wrapSourceClosure(`let ${textVar} = '';
4319
+ ${compileTextBlockListStatements(state, node.blocks, textVar, scope)}
4320
+ return ${textVar};`, canBlockListSuspend(node.blocks));
4321
+ }
4322
+ case "variable": {
4323
+ const variableResult = deconstructConditionalCombine(node.name);
4324
+ const aggressiveSource = resolveAggressiveVariableSource(state, variableResult.name);
4325
+ if (aggressiveSource !== void 0) return aggressiveSource;
4326
+ const localSlotRef = resolveLocalSlotRef(scope, variableResult.name);
4327
+ if (localSlotRef !== void 0) return `context.getSlotValue(${localSlotRef}, signal)`;
4328
+ const directBindingRef = resolveDirectBindingRef(scope, variableResult.name);
4329
+ if (directBindingRef !== void 0) return directBindingRef;
4330
+ const selfBindingRef = resolveSelfBindingRef(scope, variableResult.name);
4331
+ if (selfBindingRef !== void 0) return selfBindingRef;
4332
+ const rangeIndex = addConstant(state, node.range);
4333
+ return `runtime.resolveVariable(context, ${JSON.stringify(variableResult.name)}, ${variableResult.canIgnore ? "true" : "false"}, runtime.constants[${rangeIndex}], signal)`;
4334
+ }
4335
+ case "dot": {
4336
+ const segmentsIndex = addConstant(state, node.segments.map((segment) => {
4337
+ const result = deconstructConditionalCombine(segment.name);
4338
+ return {
4339
+ name: result.name,
4340
+ canIgnore: segment.optional || result.canIgnore,
4341
+ range: segment.range
4342
+ };
4343
+ }));
4344
+ if (node.base.kind === "variable") {
4345
+ var _node$segments$0$opti2, _node$segments$2;
4346
+ const baseResult = deconstructConditionalCombine(node.base.name);
4347
+ const localSlotRef = resolveLocalSlotRef(scope, baseResult.name);
4348
+ const baseRangeIndex = addConstant(state, node.base.range);
4349
+ const baseValueVar = allocateTemp(state, "base");
4350
+ return wrapSourceClosure(`signal?.throwIfAborted();
4351
+ const ${baseValueVar} = ${localSlotRef !== void 0 ? `{ isFound: true, value: context.getSlotValue(${localSlotRef}, signal) }` : createLookupResultSource(scope, baseResult.name)};
4352
+ if (!${baseValueVar}.isFound) {
4353
+ ${baseResult.canIgnore || ((_node$segments$0$opti2 = (_node$segments$2 = node.segments[0]) === null || _node$segments$2 === void 0 ? void 0 : _node$segments$2.optional) !== null && _node$segments$0$opti2 !== void 0 ? _node$segments$0$opti2 : false) ? "return undefined;" : `runtime.throwError({ description: ${JSON.stringify(`variable is not bound: ${baseResult.name}`)}, range: runtime.constants[${baseRangeIndex}] });`}
4354
+ }
4355
+ return runtime.resolveDotSegments(context, ${baseValueVar}.value, runtime.constants[${segmentsIndex}]);`, false);
4356
+ }
4357
+ return wrapSourceClosure(`signal?.throwIfAborted();
4358
+ return runtime.resolveDotSegments(
4359
+ context,
4360
+ ${wrapAwaitedSource(compileExpressionSource(state, node.base, scope), canExpressionSuspend(node.base))},
4361
+ runtime.constants[${segmentsIndex}]
4362
+ );`, canExpressionSuspend(node.base));
4363
+ }
4364
+ case "apply": {
4365
+ if (node.func.kind === "variable" && resolveLocalSlotRef(scope, node.func.name) === void 0) {
4366
+ const selfBindingRef = resolveSelfBindingRef(scope, node.func.name);
4367
+ if (selfBindingRef !== void 0) return wrapSourceClosure(`signal?.throwIfAborted();
4368
+ return ${selfBindingRef}(${node.args.map((arg) => wrapAwaitedSource(compileExpressionSource(state, arg, scope), canExpressionSuspend(arg))).join(", ")});`, node.args.some((arg) => canExpressionSuspend(arg)));
4369
+ }
4370
+ if (node.func.kind === "variable" && node.func.name === "set" && node.args.length === 2 && node.args[0].kind === "variable" && node.args[1].kind === "apply" && node.args[1].func.kind === "variable" && node.args[1].func.name === "fun" && node.args[1].args.length === 2) {
4371
+ const parameterNames = extractLambdaParameterNames(node.args[1].args[0]);
4372
+ if (parameterNames !== void 0) {
4373
+ const boundName = node.args[0].name;
4374
+ const lambdaVar = allocateTemp(state, "lambda");
4375
+ const lambdaSource = compileIntrinsicLambdaSource(state, node.args[1].range, parameterNames, node.args[1].args[1], scope, {
4376
+ name: boundName,
4377
+ bindingRef: lambdaVar
4378
+ });
4379
+ if (state.aggressiveOptimize) return wrapSourceClosure(`signal?.throwIfAborted();
4380
+ const ${lambdaVar} = ${lambdaSource};
4381
+ context.setValue(${JSON.stringify(boundName)}, ${lambdaVar}, signal);
4382
+ return undefined;`, true);
4383
+ const setBindingVar = allocateTemp(state, "binding");
4384
+ const funBindingVar = allocateTemp(state, "binding");
4385
+ return wrapSourceClosure(`signal?.throwIfAborted();
4386
+ const ${setBindingVar} = ${createLookupResultSource(scope, "set")};
4387
+ const ${funBindingVar} = ${createLookupResultSource(scope, "fun")};
4388
+ if (${setBindingVar}.isFound && ${setBindingVar}.value === runtime.standardIntrinsics.set && ${funBindingVar}.isFound && ${funBindingVar}.value === runtime.standardIntrinsics.fun) {
4389
+ const ${lambdaVar} = ${lambdaSource};
4390
+ context.setValue(${JSON.stringify(boundName)}, ${lambdaVar}, signal);
4391
+ return undefined;
4392
+ }
4393
+ return ${compileGenericApplySource(state, node, scope)};`, true);
4394
+ }
4395
+ }
4396
+ if (node.func.kind === "variable" && state.aggressiveOptimize && node.func.name === "set" && node.args.length === 2 && node.args[0].kind === "variable") {
4397
+ const valueSource = compileExpressionSource(state, node.args[1], scope);
4398
+ return wrapSourceClosure(`signal?.throwIfAborted();
4399
+ context.setValue(${JSON.stringify(node.args[0].name)}, ${wrapAwaitedSource(valueSource, canExpressionSuspend(node.args[1]))}, signal);
4400
+ return undefined;`, canExpressionSuspend(node.args[1]));
4401
+ }
4402
+ if (node.func.kind === "variable" && node.func.name === "cond" && node.args.length === 3) {
4403
+ const conditionNode = node.args[0];
4404
+ const thenNode = node.args[1];
4405
+ const elseNode = node.args[2];
4406
+ const bindingVar = allocateTemp(state, "binding");
4407
+ const conditionVar = allocateTemp(state, "condition");
4408
+ const conditionSource = compileExpressionSource(state, conditionNode, scope);
4409
+ const thenSource = compileExpressionSource(state, thenNode, scope);
4410
+ const elseSource = compileExpressionSource(state, elseNode, scope);
4411
+ if (state.aggressiveOptimize) return wrapSourceClosure(`signal?.throwIfAborted();
4412
+ const ${conditionVar} = ${wrapAwaitedSource(conditionSource, canExpressionSuspend(conditionNode))};
4413
+ if (runtime.isConditionalTrue(${conditionVar})) {
4414
+ return ${wrapAwaitedSource(thenSource, canExpressionSuspend(thenNode))};
4415
+ }
4416
+ return ${wrapAwaitedSource(elseSource, canExpressionSuspend(elseNode))};`, true);
4417
+ return wrapSourceClosure(`signal?.throwIfAborted();
4418
+ const ${bindingVar} = ${createLookupResultSource(scope, "cond")};
4419
+ if (${bindingVar}.isFound && ${bindingVar}.value === runtime.standardIntrinsics.cond) {
4420
+ const ${conditionVar} = ${wrapAwaitedSource(conditionSource, canExpressionSuspend(conditionNode))};
4421
+ if (runtime.isConditionalTrue(${conditionVar})) {
4422
+ return ${wrapAwaitedSource(thenSource, canExpressionSuspend(thenNode))};
4423
+ }
4424
+ return ${wrapAwaitedSource(elseSource, canExpressionSuspend(elseNode))};
4425
+ }
4426
+ return ${compileGenericApplySource(state, node, scope)};`, true);
4427
+ }
4428
+ if (node.func.kind === "variable" && node.func.name === "fun" && node.args.length === 2) {
4429
+ const parameterNames = extractLambdaParameterNames(node.args[0]);
4430
+ if (parameterNames !== void 0) {
4431
+ const lambdaSource = compileIntrinsicLambdaSource(state, node.range, parameterNames, node.args[1], scope, void 0);
4432
+ if (state.aggressiveOptimize) return lambdaSource;
4433
+ const bindingVar = allocateTemp(state, "binding");
4434
+ return wrapSourceClosure(`signal?.throwIfAborted();
4435
+ const ${bindingVar} = ${createLookupResultSource(scope, "fun")};
4436
+ if (${bindingVar}.isFound && ${bindingVar}.value === runtime.standardIntrinsics.fun) {
4437
+ return ${lambdaSource};
4438
+ }
4439
+ return ${compileGenericApplySource(state, node, scope)};`, true);
4440
+ }
4441
+ }
4442
+ const aggressiveApplySource = compileAggressiveApplySource(state, node, scope);
4443
+ if (aggressiveApplySource !== void 0) return aggressiveApplySource;
4444
+ return compileGenericApplySource(state, node, scope);
4445
+ }
4446
+ case "list": return `[${node.items.map((item) => wrapAwaitedSource(compileExpressionSource(state, item, scope), canExpressionSuspend(item))).join(", ")}]`;
4447
+ case "scope": {
4448
+ if (node.nodes.length === 0) return "[]";
4449
+ const resultVar = allocateTemp(state, "result");
4450
+ return wrapSourceClosure(`let ${resultVar} = undefined;
4451
+ ${node.nodes.map((childNode) => {
4452
+ return `${resultVar} = ${wrapAwaitedSource(compileExpressionSource(state, childNode, scope), canExpressionSuspend(childNode))};`;
4453
+ }).join("\n")}
4454
+ return ${resultVar};`, node.nodes.some((childNode) => canExpressionSuspend(childNode)));
4455
+ }
4456
+ }
4457
+ };
4458
+ const createExpressionRunner = (node) => {
4459
+ const cached = expressionCache.get(node);
4460
+ if (cached) return cached;
4461
+ const state = {
4462
+ nextTempId: 0,
4463
+ constants: [],
4464
+ aggressiveOptimize
4465
+ };
4466
+ const runner = createAdaptiveSourceRunner(`const {
4467
+ constants,
4468
+ standardBuiltins,
4469
+ asIterable,
4470
+ isConditionalTrue,
4471
+ isFunCityFunction,
4472
+ throwError,
4473
+ resolveVariable,
4474
+ resolveDotSegments,
4475
+ invokeCallable,
4476
+ invokeBuiltin
4477
+ } = runtime;
4478
+ return ${compileExpressionSource(state, node, emptyCompileScope)};`);
4479
+ const runtime = createRuntime(state.constants);
4480
+ const generated = (context, signal) => runner(context, signal, runtime);
4481
+ expressionCache.set(node, generated);
4482
+ return generated;
4483
+ };
4484
+ const createBlockRunner = (node) => {
4485
+ const cached = blockCache.get(node);
4486
+ if (cached) return cached;
4487
+ const state = {
4488
+ nextTempId: 0,
4489
+ constants: [],
4490
+ aggressiveOptimize
4491
+ };
4492
+ const resultVar = allocateTemp(state, "result");
4493
+ const runner = createAdaptiveSourceRunner(`const {
4494
+ constants,
4495
+ standardBuiltins,
4496
+ asIterable,
4497
+ isConditionalTrue,
4498
+ isFunCityFunction,
4499
+ throwError,
4500
+ resolveVariable,
4501
+ resolveDotSegments,
4502
+ invokeCallable,
4503
+ invokeBuiltin
4504
+ } = runtime;
4505
+ const ${resultVar} = [];
4506
+ ${compileBlockStatements(state, node, resultVar, false, emptyCompileScope)}
4507
+ return ${resultVar};`);
4508
+ const runtime = createRuntime(state.constants);
4509
+ const generated = (context, signal) => runner(context, signal, runtime);
4510
+ blockCache.set(node, generated);
4511
+ return generated;
4512
+ };
4513
+ const createProgramRunner = (nodes) => {
4514
+ const cached = programCache.get(nodes);
4515
+ if (cached) return cached;
4516
+ const state = {
4517
+ nextTempId: 0,
4518
+ constants: [],
4519
+ aggressiveOptimize
4520
+ };
4521
+ const resultVar = allocateTemp(state, "result");
4522
+ const runner = createAdaptiveSourceRunner(`const {
4523
+ constants,
4524
+ standardBuiltins,
4525
+ asIterable,
4526
+ isConditionalTrue,
4527
+ isFunCityFunction,
4528
+ throwError,
4529
+ resolveVariable,
4530
+ resolveDotSegments,
4531
+ invokeCallable,
4532
+ invokeBuiltin
4533
+ } = runtime;
4534
+ const ${resultVar} = [];
4535
+ ${compileBlockListStatements(state, nodes, resultVar, true, emptyCompileScope)}
4536
+ return ${resultVar};`);
4537
+ const runtime = createRuntime(state.constants);
4538
+ const generated = (context, signal) => runner(context, signal, runtime);
4539
+ programCache.set(nodes, generated);
4540
+ return generated;
4541
+ };
4542
+ const createTextProgramRunner = (nodes) => {
4543
+ const cached = textProgramCache.get(nodes);
4544
+ if (cached) return cached;
4545
+ const state = {
4546
+ nextTempId: 0,
4547
+ constants: [],
4548
+ aggressiveOptimize
4549
+ };
4550
+ const textVar = allocateTemp(state, "text");
4551
+ const runner = createAdaptiveSourceRunner(`const {
4552
+ constants,
4553
+ standardBuiltins,
4554
+ asIterable,
4555
+ isConditionalTrue,
4556
+ isFunCityFunction,
4557
+ throwError,
4558
+ resolveVariable,
4559
+ resolveDotSegments,
4560
+ invokeCallable,
4561
+ invokeBuiltin
4562
+ } = runtime;
4563
+ let ${textVar} = '';
4564
+ ${compileTextBlockListStatements(state, nodes, textVar, emptyCompileScope)}
4565
+ return ${textVar};`);
4566
+ const runtime = createRuntime(state.constants);
4567
+ const generated = (context, signal) => runner(context, signal, runtime);
4568
+ textProgramCache.set(nodes, generated);
4569
+ return generated;
4570
+ };
4571
+ const createExecutor = () => {
4572
+ return {
4573
+ reduceExpressionNode: (context, node, signal) => createExpressionRunner(node)(context, signal),
4574
+ reduceExpressionNodeImmediate: closureExecutor.reduceExpressionNodeImmediate,
4575
+ reduceNode: (context, node, signal) => createBlockRunner(node)(context, signal),
4576
+ reduceNodeImmediate: closureExecutor.reduceNodeImmediate
4577
+ };
4578
+ };
4579
+ return {
4580
+ generateExpression: createExpressionRunner,
4581
+ generateBlock: createBlockRunner,
4582
+ generateProgram: createProgramRunner,
4583
+ generateTextProgram: createTextProgramRunner,
4584
+ createExecutor
4585
+ };
4586
+ };
4587
+ /**
4588
+ * Create a dynamic code generator.
4589
+ * @param options - Generator options.
4590
+ * @returns Dynamic code generator instance.
4591
+ */
4592
+ var createDCodegen = (options) => {
4593
+ switch (options === null || options === void 0 ? void 0 : options.backend) {
4594
+ case "source": return createSourceDCodegen(options);
4595
+ case "closure":
4596
+ case void 0: return createClosureDCodegen();
4597
+ }
4598
+ };
4599
+ /**
4600
+ * Run a node list with the dynamic code generator.
4601
+ * @param nodes - Target nodes.
4602
+ * @param variables - Predefined variables.
4603
+ * @param warningLogs - Warning sink.
4604
+ * @param signal - AbortSignal when available.
4605
+ * @returns Reduced native values.
4606
+ */
4607
+ var runDCodegen = async (nodes, variables, warningLogs, signal) => {
4608
+ const dcodegen = createDCodegen();
4609
+ const context = createReducerContext(variables, warningLogs, dcodegen.createExecutor());
4610
+ return await dcodegen.generateProgram(nodes)(context, signal);
4611
+ };
4612
+ //#endregion
4613
+ //#region src/compile-cache.ts
4614
+ var compile_cache_exports = /* @__PURE__ */ require_node.__exportAll({
4615
+ compileScriptCached: () => compileScriptCached,
4616
+ createSharedDCodegenExecutor: () => createSharedDCodegenExecutor
4617
+ });
4618
+ var compilationCacheLimit = 64;
4619
+ var sharedSourceDCodegen = createDCodegen({ backend: "source" });
4620
+ var sharedAggressiveSourceDCodegen = createDCodegen({
4621
+ backend: "source",
4622
+ aggressiveOptimize: true
4623
+ });
4624
+ var sharedClosureDCodegen = createDCodegen({ backend: "closure" });
4625
+ var compiledScriptCache = /* @__PURE__ */ new Map();
4626
+ var defaultExecutionBackend = "source";
4627
+ var resolveExecutionBackend = (backend) => backend !== null && backend !== void 0 ? backend : defaultExecutionBackend;
4628
+ var isDynamicCodegenBackend = (backend) => backend !== "reducer";
4629
+ var resolveAggressiveOptimize = (backend, aggressiveOptimize) => backend === "source" ? aggressiveOptimize !== null && aggressiveOptimize !== void 0 ? aggressiveOptimize : false : false;
4630
+ var getSharedDCodegen = (backend, aggressiveOptimize) => {
4631
+ if (backend === "closure") return sharedClosureDCodegen;
4632
+ return resolveAggressiveOptimize(backend, aggressiveOptimize) ? sharedAggressiveSourceDCodegen : sharedSourceDCodegen;
4633
+ };
4634
+ var toCompilationCacheKey = (script, sourceId, mode, backend, aggressiveOptimize) => `${mode}\u0000${backend}\u0000${aggressiveOptimize ? "aggr1" : "aggr0"}\u0000${sourceId}\u0000${script}`;
4635
+ var setCompiledScriptCache = (key, compiled) => {
4636
+ compiledScriptCache.set(key, compiled);
4637
+ if (compiledScriptCache.size <= compilationCacheLimit) return;
4638
+ const firstKey = compiledScriptCache.keys().next().value;
4639
+ if (firstKey !== void 0) compiledScriptCache.delete(firstKey);
4640
+ };
4641
+ /**
4642
+ * Create a reducer executor backed by the shared dynamic code generator.
4643
+ * @param backend - Dynamic code generator backend.
4644
+ * @returns Reducer executor.
4645
+ */
4646
+ var createSharedDCodegenExecutor = (backend, aggressiveOptimize) => {
4647
+ return getSharedDCodegen(backend !== null && backend !== void 0 ? backend : defaultExecutionBackend, aggressiveOptimize).createExecutor();
4648
+ };
4649
+ var createReducerBackedProgram = (nodes) => {
4650
+ return async (context, signal) => {
4651
+ const resultList = [];
4652
+ for (const node of nodes) {
4653
+ const results = await context.reduceNode(node, signal);
4654
+ for (const result of results) if (result !== void 0) resultList.push(result);
4655
+ }
4656
+ return resultList;
4657
+ };
4658
+ };
4659
+ var createReducerBackedTextProgram = (nodes) => {
4660
+ const reducerProgram = createReducerBackedProgram(nodes);
4661
+ return async (context, signal) => {
4662
+ return (await reducerProgram(context, signal)).map((value) => context.convertToString(value)).join("");
4663
+ };
4664
+ };
4665
+ /**
4666
+ * Compile a script with cache.
4667
+ * @param script - Source text.
4668
+ * @param sourceId - Source identifier.
4669
+ * @param mode - Parse mode.
4670
+ * @param backend - Execution backend.
4671
+ * @returns Cached compilation result.
4672
+ */
4673
+ var compileScriptCached = (script, sourceId, mode, backend, aggressiveOptimize) => {
4674
+ var _sharedDCodegen$gener, _sharedDCodegen$gener2;
4675
+ const resolvedBackend = resolveExecutionBackend(backend);
4676
+ const resolvedAggressiveOptimize = resolveAggressiveOptimize(resolvedBackend, aggressiveOptimize);
4677
+ const cacheKey = toCompilationCacheKey(script, sourceId, mode, resolvedBackend, resolvedAggressiveOptimize);
4678
+ const cached = compiledScriptCache.get(cacheKey);
4679
+ if (cached) {
4680
+ compiledScriptCache.delete(cacheKey);
4681
+ compiledScriptCache.set(cacheKey, cached);
4682
+ return cached;
4683
+ }
4684
+ const logs = [];
4685
+ const tokens = mode === "code" ? runCodeTokenizer(script, logs, sourceId) : runTokenizer(script, logs, sourceId);
4686
+ const nodes = mode === "code" ? parseExpressions(tokens, logs) : runParser(tokens, logs);
4687
+ const sharedDCodegen = isDynamicCodegenBackend(resolvedBackend) ? getSharedDCodegen(resolvedBackend, resolvedAggressiveOptimize) : void 0;
4688
+ const compiled = {
4689
+ sourceId,
4690
+ mode,
4691
+ nodes,
4692
+ logs: logs.slice(),
4693
+ program: (_sharedDCodegen$gener = sharedDCodegen === null || sharedDCodegen === void 0 ? void 0 : sharedDCodegen.generateProgram(nodes)) !== null && _sharedDCodegen$gener !== void 0 ? _sharedDCodegen$gener : createReducerBackedProgram(nodes),
4694
+ textProgram: (_sharedDCodegen$gener2 = sharedDCodegen === null || sharedDCodegen === void 0 ? void 0 : sharedDCodegen.generateTextProgram(nodes)) !== null && _sharedDCodegen$gener2 !== void 0 ? _sharedDCodegen$gener2 : createReducerBackedTextProgram(nodes)
4695
+ };
4696
+ setCompiledScriptCache(cacheKey, compiled);
4697
+ return compiled;
4698
+ };
4699
+ //#endregion
4700
+ Object.defineProperty(exports, "FunCityReducerError", {
4701
+ enumerable: true,
4702
+ get: function() {
4703
+ return FunCityReducerError;
4704
+ }
4705
+ });
4706
+ Object.defineProperty(exports, "buildCandidateVariables", {
4707
+ enumerable: true,
4708
+ get: function() {
4709
+ return buildCandidateVariables;
4710
+ }
4711
+ });
4712
+ Object.defineProperty(exports, "combineVariables", {
4713
+ enumerable: true,
4714
+ get: function() {
4715
+ return combineVariables;
4716
+ }
4717
+ });
4718
+ Object.defineProperty(exports, "compileScriptCached", {
4719
+ enumerable: true,
4720
+ get: function() {
4721
+ return compileScriptCached;
4722
+ }
4723
+ });
4724
+ Object.defineProperty(exports, "compile_cache_exports", {
4725
+ enumerable: true,
4726
+ get: function() {
4727
+ return compile_cache_exports;
4728
+ }
4729
+ });
4730
+ Object.defineProperty(exports, "convertToString", {
4731
+ enumerable: true,
4732
+ get: function() {
4733
+ return convertToString;
4734
+ }
4735
+ });
4736
+ Object.defineProperty(exports, "createDCodegen", {
4737
+ enumerable: true,
4738
+ get: function() {
4739
+ return createDCodegen;
4740
+ }
4741
+ });
4742
+ Object.defineProperty(exports, "createIncludeFunction", {
4743
+ enumerable: true,
4744
+ get: function() {
4745
+ return createIncludeFunction;
4746
+ }
4747
+ });
4748
+ Object.defineProperty(exports, "createParserCursor", {
4749
+ enumerable: true,
4750
+ get: function() {
4751
+ return createParserCursor;
4752
+ }
4753
+ });
4754
+ Object.defineProperty(exports, "createReducerContext", {
4755
+ enumerable: true,
4756
+ get: function() {
4757
+ return createReducerContext;
4758
+ }
4759
+ });
4760
+ Object.defineProperty(exports, "createSharedDCodegenExecutor", {
4761
+ enumerable: true,
4762
+ get: function() {
4763
+ return createSharedDCodegenExecutor;
4764
+ }
4765
+ });
4766
+ Object.defineProperty(exports, "emptyLocation", {
4767
+ enumerable: true,
4768
+ get: function() {
4769
+ return emptyLocation;
4770
+ }
4771
+ });
4772
+ Object.defineProperty(exports, "emptyRange", {
4773
+ enumerable: true,
4774
+ get: function() {
4775
+ return emptyRange;
4776
+ }
4777
+ });
4778
+ Object.defineProperty(exports, "isConditionalTrue", {
4779
+ enumerable: true,
4780
+ get: function() {
4781
+ return isConditionalTrue;
4782
+ }
4783
+ });
4784
+ Object.defineProperty(exports, "isFunCityFunction", {
4785
+ enumerable: true,
4786
+ get: function() {
4787
+ return isFunCityFunction;
4788
+ }
4789
+ });
4790
+ Object.defineProperty(exports, "makeFunCityFunction", {
4791
+ enumerable: true,
4792
+ get: function() {
4793
+ return makeFunCityFunction;
4794
+ }
4795
+ });
4796
+ Object.defineProperty(exports, "outputErrors", {
4797
+ enumerable: true,
4798
+ get: function() {
4799
+ return outputErrors;
4800
+ }
4801
+ });
4802
+ Object.defineProperty(exports, "parseBlock", {
4803
+ enumerable: true,
4804
+ get: function() {
4805
+ return parseBlock;
4806
+ }
4807
+ });
4808
+ Object.defineProperty(exports, "parseExpression", {
4809
+ enumerable: true,
4810
+ get: function() {
4811
+ return parseExpression;
4812
+ }
4813
+ });
4814
+ Object.defineProperty(exports, "parseExpressions", {
4815
+ enumerable: true,
4816
+ get: function() {
4817
+ return parseExpressions;
4818
+ }
4819
+ });
4820
+ Object.defineProperty(exports, "reduceExpressionNode", {
4821
+ enumerable: true,
4822
+ get: function() {
4823
+ return reduceExpressionNode;
4824
+ }
4825
+ });
4826
+ Object.defineProperty(exports, "reduceNode", {
4827
+ enumerable: true,
4828
+ get: function() {
4829
+ return reduceNode;
4830
+ }
4831
+ });
4832
+ Object.defineProperty(exports, "runCodeTokenizer", {
4833
+ enumerable: true,
4834
+ get: function() {
4835
+ return runCodeTokenizer;
4836
+ }
4837
+ });
4838
+ Object.defineProperty(exports, "runDCodegen", {
4839
+ enumerable: true,
4840
+ get: function() {
4841
+ return runDCodegen;
4842
+ }
4843
+ });
4844
+ Object.defineProperty(exports, "runParser", {
4845
+ enumerable: true,
4846
+ get: function() {
4847
+ return runParser;
4848
+ }
4849
+ });
4850
+ Object.defineProperty(exports, "runReducer", {
4851
+ enumerable: true,
4852
+ get: function() {
4853
+ return runReducer;
4854
+ }
4855
+ });
4856
+ Object.defineProperty(exports, "runTokenizer", {
4857
+ enumerable: true,
4858
+ get: function() {
4859
+ return runTokenizer;
4860
+ }
4861
+ });
4862
+ Object.defineProperty(exports, "standardVariables", {
4863
+ enumerable: true,
4864
+ get: function() {
4865
+ return standardVariables;
4866
+ }
4867
+ });
4868
+
4869
+ //# sourceMappingURL=compile-cache-D9XyNhoC.cjs.map