@graffiticode/parser 0.1.0 → 0.1.2

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 (71) hide show
  1. package/dist/api/src/config/config.d.ts +3 -0
  2. package/dist/api/src/config/config.js +4 -0
  3. package/dist/api/src/config/config.js.map +1 -0
  4. package/dist/api/src/config/index.d.ts +1 -0
  5. package/dist/api/src/config/index.js +3 -0
  6. package/dist/api/src/config/index.js.map +1 -0
  7. package/dist/api/src/lang/base-url.d.ts +7 -0
  8. package/dist/api/src/lang/base-url.js +24 -0
  9. package/dist/api/src/lang/base-url.js.map +1 -0
  10. package/dist/api/src/lang/compile.d.ts +4 -0
  11. package/dist/api/src/lang/compile.js +6 -0
  12. package/dist/api/src/lang/compile.js.map +1 -0
  13. package/dist/api/src/lang/get-asset.d.ts +4 -0
  14. package/dist/api/src/lang/get-asset.js +9 -0
  15. package/dist/api/src/lang/get-asset.js.map +1 -0
  16. package/dist/api/src/lang/index.d.ts +4 -0
  17. package/dist/api/src/lang/index.js +22 -0
  18. package/dist/api/src/lang/index.js.map +1 -0
  19. package/dist/api/src/lang/ping-lang.d.ts +5 -0
  20. package/dist/api/src/lang/ping-lang.js +31 -0
  21. package/dist/api/src/lang/ping-lang.js.map +1 -0
  22. package/dist/api/src/util.d.ts +23 -0
  23. package/dist/api/src/util.js +187 -0
  24. package/dist/api/src/util.js.map +1 -0
  25. package/dist/parser/src/ast.d.ts +58 -0
  26. package/dist/parser/src/ast.js +683 -0
  27. package/dist/parser/src/ast.js.map +1 -0
  28. package/dist/parser/src/env.d.ts +8 -0
  29. package/dist/parser/src/env.js +38 -0
  30. package/dist/parser/src/env.js.map +1 -0
  31. package/dist/parser/src/fold.d.ts +4 -0
  32. package/dist/parser/src/fold.js +217 -0
  33. package/dist/parser/src/fold.js.map +1 -0
  34. package/dist/parser/src/folder.d.ts +30 -0
  35. package/dist/parser/src/folder.js +231 -0
  36. package/dist/parser/src/folder.js.map +1 -0
  37. package/dist/parser/src/index.d.ts +5 -0
  38. package/dist/parser/src/index.js +6 -0
  39. package/dist/parser/src/index.js.map +1 -0
  40. package/dist/parser/src/parse.d.ts +56 -0
  41. package/dist/parser/src/parse.js +902 -0
  42. package/dist/parser/src/parse.js.map +1 -0
  43. package/dist/parser/src/parser.d.ts +17 -0
  44. package/dist/parser/src/parser.js +89 -0
  45. package/dist/parser/src/parser.js.map +1 -0
  46. package/dist/parser/src/parserForTests.d.ts +3 -0
  47. package/dist/parser/src/parserForTests.js +4 -0
  48. package/dist/parser/src/parserForTests.js.map +1 -0
  49. package/dist/parser/src/stringstream.d.ts +10 -0
  50. package/dist/parser/src/stringstream.js +21 -0
  51. package/dist/parser/src/stringstream.js.map +1 -0
  52. package/dist/parser/src/testing/index.d.ts +2 -0
  53. package/dist/parser/src/testing/index.js +17 -0
  54. package/dist/parser/src/testing/index.js.map +1 -0
  55. package/dist/parser/src/types.d.ts +44 -0
  56. package/dist/parser/src/types.js +2 -0
  57. package/dist/parser/src/types.js.map +1 -0
  58. package/package.json +5 -9
  59. package/src/ast.js +730 -0
  60. package/src/env.js +50 -0
  61. package/src/folder.js +249 -0
  62. package/src/folder.spec.js +42 -0
  63. package/src/parse.js +35 -935
  64. package/src/parse.spec.js +118 -0
  65. package/src/parse.spec.js~ +119 -0
  66. package/src/parse.ts~ +1037 -0
  67. package/src/parser.spec.js +11 -35
  68. package/src/{parser.js~ → parser.ts~} +25 -7
  69. package/src/stringstream.js +22 -0
  70. package/src/fold.js +0 -235
  71. package/src/parser.spec.js~ +0 -175
@@ -0,0 +1,683 @@
1
+ import { Env } from "./env";
2
+ import { folder } from "./folder";
3
+ import { assertErr } from "./parse";
4
+ const ASSERT = true;
5
+ const assert = function (val, str) {
6
+ if (!ASSERT) {
7
+ return;
8
+ }
9
+ if (str === undefined) {
10
+ str = "failed!";
11
+ }
12
+ if (!val) {
13
+ throw new Error(str);
14
+ }
15
+ };
16
+ // Helper function not part of the class
17
+ function nodeToJSON(n) {
18
+ let obj;
19
+ if (typeof n === "object") {
20
+ switch (n.tag) {
21
+ case "num":
22
+ obj = n.elts[0];
23
+ break;
24
+ case "str":
25
+ obj = n.elts[0];
26
+ break;
27
+ default:
28
+ obj = {};
29
+ obj.tag = n.tag;
30
+ obj.elts = [];
31
+ for (let i = 0; i < n.elts.length; i++) {
32
+ obj.elts[i] = nodeToJSON(n.elts[i]);
33
+ }
34
+ break;
35
+ }
36
+ }
37
+ else if (typeof n === "string") {
38
+ obj = n;
39
+ }
40
+ else {
41
+ obj = n;
42
+ }
43
+ return obj;
44
+ }
45
+ export class Ast {
46
+ static push(ctx, node) {
47
+ let nid;
48
+ if (typeof node === "number") { // if already interned
49
+ nid = node;
50
+ }
51
+ else {
52
+ nid = Ast.intern(ctx, node);
53
+ }
54
+ ctx.state.nodeStack.push(nid);
55
+ }
56
+ static topNode(ctx) {
57
+ const nodeStack = ctx.state.nodeStack;
58
+ return nodeStack[nodeStack.length - 1];
59
+ }
60
+ static pop(ctx) {
61
+ const nodeStack = ctx.state.nodeStack;
62
+ return nodeStack.pop();
63
+ }
64
+ static peek(ctx, n) {
65
+ if (n === undefined) {
66
+ n = 0;
67
+ }
68
+ const nodeStack = ctx.state.nodeStack;
69
+ return nodeStack[nodeStack.length - 1 - n];
70
+ }
71
+ static intern(ctx, n) {
72
+ if (!n) {
73
+ return 0;
74
+ }
75
+ const nodeMap = ctx.state.nodeMap;
76
+ const nodePool = ctx.state.nodePool;
77
+ const tag = n.tag;
78
+ let elts = "";
79
+ const count = n.elts.length;
80
+ for (let i = 0; i < count; i++) {
81
+ if (typeof n.elts[i] === "object") {
82
+ n.elts[i] = Ast.intern(ctx, n.elts[i]);
83
+ }
84
+ elts += n.elts[i];
85
+ }
86
+ const key = tag + count + elts;
87
+ let nid = nodeMap[key];
88
+ if (nid === undefined) {
89
+ nodePool.push({ tag, elts: n.elts });
90
+ nid = nodePool.length - 1;
91
+ nodeMap[key] = nid;
92
+ if (n.coord) {
93
+ ctx.state.coords[nid] = n.coord;
94
+ }
95
+ }
96
+ return nid;
97
+ }
98
+ static node(ctx, nid) {
99
+ const n = ctx.state.nodePool[nid];
100
+ if (!nid) {
101
+ return null;
102
+ }
103
+ else if (!n) {
104
+ return {};
105
+ }
106
+ const elts = [];
107
+ switch (n.tag) {
108
+ case "NULL":
109
+ break;
110
+ case "NUM":
111
+ case "STR":
112
+ case "IDENT":
113
+ case "BOOL":
114
+ elts[0] = n.elts[0];
115
+ break;
116
+ default:
117
+ for (let i = 0; i < n.elts.length; i++) {
118
+ elts[i] = Ast.node(ctx, n.elts[i]);
119
+ }
120
+ break;
121
+ }
122
+ return {
123
+ tag: n.tag,
124
+ elts,
125
+ };
126
+ }
127
+ static dumpAll(ctx) {
128
+ const nodePool = ctx.state.nodePool;
129
+ let s = "\n{";
130
+ for (let i = 1; i < nodePool.length; i++) {
131
+ const n = nodePool[i];
132
+ s = s + "\n " + i + ": " + Ast.dump(n) + ",";
133
+ }
134
+ s += "\n root: " + (nodePool.length - 1);
135
+ s += "\n}\n";
136
+ return s;
137
+ }
138
+ static poolToJSON(ctx) {
139
+ const nodePool = ctx.state.nodePool;
140
+ const obj = {};
141
+ for (let i = 1; i < nodePool.length; i++) {
142
+ const n = nodePool[i];
143
+ obj[i] = nodeToJSON(n);
144
+ }
145
+ obj.root = (nodePool.length - 1);
146
+ return obj;
147
+ }
148
+ static dump(n) {
149
+ let s;
150
+ if (typeof n === "object") {
151
+ switch (n.tag) {
152
+ case "num":
153
+ s = n.elts[0];
154
+ break;
155
+ case "str":
156
+ s = "\"" + n.elts[0] + "\"";
157
+ break;
158
+ default:
159
+ if (!n.elts) {
160
+ s = "<invalid>";
161
+ }
162
+ else {
163
+ s = "{ tag: \"" + n.tag + "\", elts: [ ";
164
+ for (let i = 0; i < n.elts.length; i++) {
165
+ if (i > 0) {
166
+ s += " , ";
167
+ }
168
+ s += Ast.dump(n.elts[i]);
169
+ }
170
+ s += " ] }";
171
+ }
172
+ break;
173
+ }
174
+ }
175
+ else if (typeof n === "string") {
176
+ s = "\"" + n + "\"";
177
+ }
178
+ else {
179
+ s = String(n);
180
+ }
181
+ return s;
182
+ }
183
+ static fold(ctx, fn, args) {
184
+ // Local defs:
185
+ // -- put bindings in env
186
+ // Three cases:
187
+ // -- full application, all args are available at parse time
188
+ // -- partial application, only some args are available at parse time
189
+ // -- late application, args are available at compile time (not parse time)
190
+ // apply <[x y]: add x y> data..
191
+ // x: val 0 data
192
+ // y: val 1 data
193
+ Env.enterEnv(ctx, fn.name);
194
+ if (fn.env) {
195
+ const lexicon = fn.env.lexicon;
196
+ const pattern = Ast.node(ctx, fn.env.pattern);
197
+ let outerEnv = null;
198
+ // let isListPattern;
199
+ // setup inner environment record (lexicon)
200
+ if (pattern && pattern.elts &&
201
+ pattern.elts.length === 1 &&
202
+ pattern.elts[0].tag === "LIST") {
203
+ // For now we only support one pattern per param list.
204
+ // isListPattern = true;
205
+ }
206
+ for (const id in lexicon) {
207
+ // For each parameter, get its definition assign the value of the argument
208
+ // used on the current function application.
209
+ if (!id)
210
+ continue;
211
+ const word = JSON.parse(JSON.stringify(lexicon[id])); // poor man's copy.
212
+ const index = args.length - word.offset - 1;
213
+ // TODO we currently ignore list patterns
214
+ // if (isListPattern) {
215
+ // // <[x y]: ...> foo..
216
+ // word.nid = Ast.intern(ctx, {
217
+ // tag: "VAL",
218
+ // elts: [{
219
+ // tag: "NUM",
220
+ // elts: [
221
+ // String(word.offset),
222
+ // ]}, {
223
+ // tag: "ARG",
224
+ // elts: [{
225
+ // tag: "NUM",
226
+ // elts: ["0"]
227
+ // }]
228
+ // }]
229
+ // });
230
+ // } else
231
+ if (index >= 0 && index < args.length) {
232
+ word.nid = args[index];
233
+ }
234
+ if (index < 0) {
235
+ // We've got an unbound variable or a variable with a default value,
236
+ // so add it to the new variable list.
237
+ // <x:x> => <x:x>
238
+ // (<x y: add x y> 10) => <y: add 10 y>
239
+ // (<y: let x = 10.. add x y>) => <y: add 10 y>
240
+ if (!outerEnv) {
241
+ outerEnv = {};
242
+ }
243
+ outerEnv[id] = word;
244
+ }
245
+ Env.addWord(ctx, id, word);
246
+ }
247
+ folder.fold(ctx, fn.nid);
248
+ if (outerEnv) {
249
+ Ast.lambda(ctx, {
250
+ lexicon: outerEnv,
251
+ pattern // FIXME need to trim pattern if some args where applied.
252
+ }, Ast.pop(ctx));
253
+ }
254
+ }
255
+ Env.exitEnv(ctx);
256
+ }
257
+ static applyLate(ctx, count) {
258
+ // Ast.applyLate
259
+ const elts = [];
260
+ for (let i = count; i > 0; i--) {
261
+ elts.push(Ast.pop(ctx));
262
+ }
263
+ Ast.push(ctx, {
264
+ tag: "APPLY",
265
+ elts
266
+ });
267
+ }
268
+ static apply(ctx, fnId, argc) {
269
+ // Construct function and apply available arguments.
270
+ const fn = Ast.node(ctx, fnId);
271
+ // if (fn.tag !== "LAMBDA") {
272
+ // // Construct an APPLY node for compiling later.
273
+ // return {
274
+ // tag: "APPLY",
275
+ // elts: [
276
+ // fnId,
277
+ // ]
278
+ // };
279
+ // }
280
+ // Construct a lexicon
281
+ const lexicon = {};
282
+ let paramc = 0;
283
+ fn.elts[0].elts.forEach(function (n, i) {
284
+ const name = n.elts[0];
285
+ const nid = Ast.intern(ctx, fn.elts[3].elts[i]);
286
+ lexicon[name] = {
287
+ cls: "val",
288
+ name,
289
+ offset: i,
290
+ nid
291
+ };
292
+ if (!nid) {
293
+ // Parameters don't have nids.
294
+ // assert that there are parameters after a binding without a nid.
295
+ paramc++;
296
+ }
297
+ });
298
+ const def = {
299
+ name: "lambda",
300
+ nid: Ast.intern(ctx, fn.elts[1]),
301
+ env: {
302
+ lexicon,
303
+ pattern: Ast.intern(ctx, fn.elts[2])
304
+ }
305
+ };
306
+ const elts = [];
307
+ // While there are args on the stack, pop them.
308
+ while (argc-- > 0 && paramc-- > 0) {
309
+ const elt = Ast.pop(ctx);
310
+ elts.unshift(elt); // Get the order right.
311
+ }
312
+ Ast.fold(ctx, def, elts);
313
+ }
314
+ // Node constructors
315
+ static error(ctx, str, coord) {
316
+ console.log("error()", "str=" + str, "coord=" + JSON.stringify(coord));
317
+ const from = coord?.from !== undefined ? coord.from : -1;
318
+ const to = coord?.to !== undefined ? coord.to : -1;
319
+ Ast.number(ctx, to);
320
+ Ast.number(ctx, from);
321
+ Ast.string(ctx, str, coord);
322
+ Ast.push(ctx, {
323
+ tag: "ERROR",
324
+ elts: [
325
+ Ast.pop(ctx),
326
+ Ast.pop(ctx),
327
+ Ast.pop(ctx),
328
+ ],
329
+ coord
330
+ });
331
+ }
332
+ static bool(ctx, val) {
333
+ let b;
334
+ if (val) {
335
+ b = true;
336
+ }
337
+ else {
338
+ b = false;
339
+ }
340
+ Ast.push(ctx, {
341
+ tag: "BOOL",
342
+ elts: [b]
343
+ });
344
+ }
345
+ static nul(ctx) {
346
+ Ast.push(ctx, {
347
+ tag: "NULL",
348
+ elts: []
349
+ });
350
+ }
351
+ static number(ctx, num, coord) {
352
+ assert(typeof num === "string" || typeof num === "number");
353
+ Ast.push(ctx, {
354
+ tag: "NUM",
355
+ elts: [String(num)],
356
+ coord
357
+ });
358
+ }
359
+ static string(ctx, str, coord) {
360
+ Ast.push(ctx, {
361
+ tag: "STR",
362
+ elts: [str],
363
+ coord
364
+ });
365
+ }
366
+ static setName(ctx, name, coord) {
367
+ Ast.push(ctx, {
368
+ tag: "IDENT",
369
+ elts: [name],
370
+ coord
371
+ });
372
+ }
373
+ static expr(ctx, argc) {
374
+ // Ast.expr -- construct a expr node for the compiler.
375
+ const elts = [];
376
+ const pos = 1; // FIXME
377
+ console.trace("expr()", "argc=" + argc, "nodeStack=" + JSON.stringify(ctx.state.nodeStack, null, 2));
378
+ assertErr(ctx, argc <= ctx.state.nodeStack.length - 1, `Too few arguments. Expected ${argc} got ${ctx.state.nodeStack.length - 1}.`, {
379
+ from: pos - 1, to: pos
380
+ });
381
+ while (argc--) {
382
+ const elt = Ast.pop(ctx);
383
+ elts.push(elt);
384
+ }
385
+ const nameId = Ast.pop(ctx);
386
+ console.log("expr()", "nameId=" + nameId);
387
+ assertErr(ctx, Boolean(nameId), "Ill formed node.");
388
+ const e = Ast.node(ctx, nameId).elts;
389
+ assertErr(ctx, e && e.length > 0, "Ill formed node.");
390
+ const name = e[0];
391
+ Ast.push(ctx, {
392
+ tag: name,
393
+ elts,
394
+ });
395
+ }
396
+ static parenExpr(ctx, coord) {
397
+ // Ast.parenExpr
398
+ const elts = [];
399
+ const elt = Ast.pop(ctx);
400
+ elts.push(elt);
401
+ Ast.push(ctx, {
402
+ tag: "PAREN",
403
+ elts,
404
+ coord
405
+ });
406
+ }
407
+ static list(ctx, count, coord, reverse) {
408
+ // Ast.list
409
+ const elts = [];
410
+ for (let i = count; i > 0; i--) {
411
+ const elt = Ast.pop(ctx);
412
+ if (elt !== undefined) {
413
+ elts.push(elt);
414
+ }
415
+ }
416
+ Ast.push(ctx, {
417
+ tag: "LIST",
418
+ elts: reverse ? elts : elts.reverse(),
419
+ coord
420
+ });
421
+ }
422
+ static binaryExpr(ctx, name) {
423
+ const elts = [];
424
+ // args are in the order produced by the parser
425
+ elts.push(Ast.pop(ctx));
426
+ elts.push(Ast.pop(ctx));
427
+ Ast.push(ctx, {
428
+ tag: name,
429
+ elts: elts.reverse()
430
+ });
431
+ }
432
+ static unaryExpr(ctx, name) {
433
+ const elts = [];
434
+ elts.push(Ast.pop(ctx));
435
+ Ast.push(ctx, {
436
+ tag: name,
437
+ elts
438
+ });
439
+ }
440
+ static prefixExpr(ctx, name) {
441
+ const elts = [];
442
+ elts.push(Ast.pop(ctx));
443
+ Ast.push(ctx, {
444
+ tag: name,
445
+ elts
446
+ });
447
+ }
448
+ static neg(ctx) {
449
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
450
+ Ast.number(ctx, -1 * v1);
451
+ }
452
+ static add(ctx, coord) {
453
+ const n2 = Ast.node(ctx, Ast.pop(ctx));
454
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
455
+ const v2 = n2.elts[0];
456
+ const v1 = n1.elts[0];
457
+ if (n1.tag !== "NUM" || n2.tag !== "NUM") {
458
+ Ast.push(ctx, {
459
+ tag: "ADD",
460
+ elts: [n1, n2],
461
+ coord
462
+ });
463
+ }
464
+ else {
465
+ Ast.number(ctx, +v1 + +v2);
466
+ }
467
+ }
468
+ static sub(ctx) {
469
+ const n2 = Ast.node(ctx, Ast.pop(ctx));
470
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
471
+ const v2 = n2.elts[0];
472
+ const v1 = n1.elts[0];
473
+ if (n1.tag !== "NUM" || n2.tag !== "NUM") {
474
+ Ast.push(ctx, { tag: "SUB", elts: [n1, n2] });
475
+ }
476
+ else {
477
+ Ast.number(ctx, +v1 - +v2);
478
+ }
479
+ }
480
+ // static mul(ctx: Context): void {
481
+ // let n2 = Ast.node(ctx, Ast.pop(ctx));
482
+ // let n1 = Ast.node(ctx, Ast.pop(ctx));
483
+ // const v2 = n2.elts[0];
484
+ // const v1 = n1.elts[0];
485
+ // if (n1.tag === undefined) {
486
+ // n1 = n1.elts[0];
487
+ // }
488
+ // if (n2.tag === undefined) {
489
+ // n2 = n2.elts[0];
490
+ // }
491
+ // if (n1.tag !== "NUM" || n2.tag !== "NUM") {
492
+ // Ast.push(ctx, { tag: "MUL", elts: [n2, n1] });
493
+ // } else {
494
+ // Ast.number(ctx, +v1 * +v2);
495
+ // }
496
+ // }
497
+ static div(ctx) {
498
+ const n2 = Ast.node(ctx, Ast.pop(ctx));
499
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
500
+ const v2 = n2.elts[0];
501
+ const v1 = n1.elts[0];
502
+ if (n1.tag !== "NUM" || n2.tag !== "NUM") {
503
+ Ast.push(ctx, { tag: "DIV", elts: [n1, n2] });
504
+ }
505
+ else {
506
+ Ast.number(ctx, +v1 / +v2);
507
+ }
508
+ }
509
+ static mod(ctx) {
510
+ const n2 = Ast.node(ctx, Ast.pop(ctx));
511
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
512
+ const v1 = n1.elts[0];
513
+ const v2 = n2.elts[0];
514
+ if (n1.tag !== "NUM" || n2.tag !== "NUM") {
515
+ Ast.push(ctx, { tag: "MOD", elts: [n1, n2] });
516
+ }
517
+ else {
518
+ Ast.number(ctx, +v1 % +v2);
519
+ }
520
+ }
521
+ static pow(ctx) {
522
+ const n2 = Ast.node(ctx, Ast.pop(ctx));
523
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
524
+ const v2 = n2.elts[0];
525
+ const v1 = n1.elts[0];
526
+ if (n1.tag !== "NUM" || n2.tag !== "NUM") {
527
+ Ast.push(ctx, { tag: "POW", elts: [n1, n2] });
528
+ }
529
+ else {
530
+ Ast.number(ctx, Math.pow(+v1, +v2));
531
+ }
532
+ }
533
+ static concat(ctx) {
534
+ const n1 = Ast.node(ctx, Ast.pop(ctx));
535
+ Ast.push(ctx, {
536
+ tag: "CONCAT",
537
+ elts: [n1]
538
+ });
539
+ }
540
+ static eq(ctx) {
541
+ const v2 = Ast.node(ctx, Ast.pop(ctx)).elts[0];
542
+ const v1 = Ast.node(ctx, Ast.pop(ctx)).elts[0];
543
+ Ast.bool(ctx, v1 === v2);
544
+ }
545
+ static ne(ctx) {
546
+ const v2 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
547
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
548
+ Ast.bool(ctx, v1 !== v2);
549
+ }
550
+ static lt(ctx) {
551
+ const v2 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
552
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
553
+ Ast.bool(ctx, v1 < v2);
554
+ }
555
+ static gt(ctx) {
556
+ const v2 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
557
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
558
+ Ast.bool(ctx, v1 > v2);
559
+ }
560
+ static le(ctx) {
561
+ const v2 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
562
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
563
+ Ast.bool(ctx, v1 <= v2);
564
+ }
565
+ static ge(ctx) {
566
+ const v2 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
567
+ const v1 = +Ast.node(ctx, Ast.pop(ctx)).elts[0];
568
+ Ast.bool(ctx, v1 >= v2);
569
+ }
570
+ static ifExpr(ctx) {
571
+ const elts = [];
572
+ elts.push(Ast.pop(ctx)); // if
573
+ elts.push(Ast.pop(ctx)); // then
574
+ elts.push(Ast.pop(ctx)); // else
575
+ Ast.push(ctx, { tag: "IF", elts: elts.reverse() });
576
+ }
577
+ static caseExpr(ctx, n) {
578
+ const elts = [];
579
+ elts.push(Ast.pop(ctx)); // val
580
+ for (let i = n; i > 0; i--) {
581
+ elts.push(Ast.pop(ctx)); // of
582
+ }
583
+ Ast.push(ctx, { tag: "CASE", elts: elts.reverse() });
584
+ }
585
+ static ofClause(ctx) {
586
+ const elts = [];
587
+ elts.push(Ast.pop(ctx));
588
+ elts.push(Ast.pop(ctx));
589
+ Ast.push(ctx, { tag: "OF", elts: elts.reverse() });
590
+ }
591
+ static record(ctx) {
592
+ // Ast.record
593
+ const count = ctx.state.exprc;
594
+ const elts = [];
595
+ for (let i = count; i > 0; i--) {
596
+ const elt = Ast.pop(ctx);
597
+ if (elt !== undefined) {
598
+ elts.push(elt);
599
+ }
600
+ }
601
+ Ast.push(ctx, {
602
+ tag: "RECORD",
603
+ elts
604
+ });
605
+ }
606
+ static binding(ctx) {
607
+ // Ast.binding
608
+ const elts = [];
609
+ elts.push(Ast.pop(ctx));
610
+ elts.push(Ast.pop(ctx));
611
+ Ast.push(ctx, {
612
+ tag: "BINDING",
613
+ elts: elts.reverse()
614
+ });
615
+ }
616
+ static lambda(ctx, env, nid) {
617
+ // Ast.lambda
618
+ const names = [];
619
+ const nids = [];
620
+ for (const id in env.lexicon) {
621
+ const word = env.lexicon[id];
622
+ names.push({
623
+ tag: "IDENT",
624
+ elts: [word.name],
625
+ });
626
+ nids.push(word.nid || 0);
627
+ }
628
+ const pattern = env.pattern;
629
+ Ast.push(ctx, {
630
+ tag: "LAMBDA",
631
+ elts: [{
632
+ tag: "LIST",
633
+ elts: names
634
+ }, nid, {
635
+ tag: "LIST",
636
+ elts: pattern
637
+ }, {
638
+ tag: "LIST",
639
+ elts: nids
640
+ }]
641
+ });
642
+ }
643
+ static exprs(ctx, count, inReverse) {
644
+ // Ast.exprs
645
+ let elts = [];
646
+ assert(ctx.state.nodeStack.length >= count);
647
+ if (inReverse) {
648
+ for (let i = count; i > 0; i--) {
649
+ const elt = Ast.pop(ctx);
650
+ elts.push(elt); // Reverse order.
651
+ }
652
+ }
653
+ else {
654
+ for (let i = count; i > 0; i--) {
655
+ const elt = Ast.pop(ctx);
656
+ elts.push(elt); // Reverse order.
657
+ }
658
+ elts = elts.reverse();
659
+ }
660
+ Ast.push(ctx, {
661
+ tag: "EXPRS",
662
+ elts
663
+ });
664
+ }
665
+ static letDef(ctx) {
666
+ // Clean up stack and produce initializer.
667
+ Ast.pop(ctx); // body
668
+ Ast.pop(ctx); // name
669
+ for (let i = 0; i < ctx.state.paramc; i++) {
670
+ Ast.pop(ctx); // params
671
+ }
672
+ ctx.state.exprc--; // don't count as expr.
673
+ }
674
+ static program(ctx) {
675
+ const elts = [];
676
+ elts.push(Ast.pop(ctx));
677
+ Ast.push(ctx, {
678
+ tag: "PROG",
679
+ elts
680
+ });
681
+ }
682
+ }
683
+ //# sourceMappingURL=ast.js.map