@graffiticode/basis 1.5.9 → 1.5.11

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/compiler.js +139 -24
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graffiticode/basis",
3
3
  "type": "module",
4
- "version": "1.5.9",
4
+ "version": "1.5.11",
5
5
  "description": "The basis library for creating Graffiticode languages",
6
6
  "main": "index.js",
7
7
  "scripts": {
package/src/compiler.js CHANGED
@@ -170,12 +170,30 @@ export class Checker extends Visitor {
170
170
  ADD(node, options, resume) {
171
171
  this.visit(node.elts[0], options, (err1, val1) => {
172
172
  this.visit(node.elts[1], options, (err2, val2) => {
173
- if (isNaN(+val1)) {
174
- err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
175
- }
176
- if (isNaN(+val2)) {
177
- err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
178
- }
173
+ const err = [].concat(err1).concat(err2);
174
+ const val = node;
175
+ resume(err, val);
176
+ });
177
+ });
178
+ }
179
+ SUB(node, options, resume) {
180
+ this.visit(node.elts[0], options, (err1, val1) => {
181
+ this.visit(node.elts[1], options, (err2, val2) => {
182
+ const err = [].concat(err1).concat(err2);
183
+ const val = node;
184
+ resume(err, val);
185
+ });
186
+ });
187
+ }
188
+ LT(node, options, resume) {
189
+ this.visit(node.elts[0], options, (err1, val1) => {
190
+ this.visit(node.elts[1], options, (err2, val2) => {
191
+ // if (isNaN(+val1)) {
192
+ // err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
193
+ // }
194
+ // if (isNaN(+val2)) {
195
+ // err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
196
+ // }
179
197
  const err = [].concat(err1).concat(err2);
180
198
  const val = node;
181
199
  resume(err, val);
@@ -205,12 +223,6 @@ export class Checker extends Visitor {
205
223
  MUL(node, options, resume) {
206
224
  this.visit(node.elts[0], options, (err1, val1) => {
207
225
  this.visit(node.elts[1], options, (err2, val2) => {
208
- if (isNaN(+val1)) {
209
- err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
210
- }
211
- if (isNaN(+val2)) {
212
- err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
213
- }
214
226
  const err = [].concat(err1).concat(err2);
215
227
  const val = node;
216
228
  resume(err, val);
@@ -220,12 +232,6 @@ export class Checker extends Visitor {
220
232
  POW(node, options, resume) {
221
233
  this.visit(node.elts[0], options, (err1, val1) => {
222
234
  this.visit(node.elts[1], options, (err2, val2) => {
223
- if (isNaN(+val1)) {
224
- err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
225
- }
226
- if (isNaN(+val2)) {
227
- err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
228
- }
229
235
  const err = [].concat(err1).concat(err2);
230
236
  const val = node;
231
237
  resume(err, val);
@@ -272,6 +278,11 @@ export class Checker extends Visitor {
272
278
  const val = node;
273
279
  resume(err, val);
274
280
  }
281
+ REDUCE(node, options, resume) {
282
+ const err = [];
283
+ const val = node;
284
+ resume(err, val);
285
+ }
275
286
  STYLE(node, options, resume) {
276
287
  const err = [];
277
288
  const val = node;
@@ -292,6 +303,11 @@ export class Checker extends Visitor {
292
303
  const val = node;
293
304
  resume(err, val);
294
305
  }
306
+ PRINT(node, options, resume) {
307
+ const err = [];
308
+ const val = node;
309
+ resume(err, val);
310
+ }
295
311
  }
296
312
 
297
313
  function enterEnv(ctx, name, paramc) {
@@ -466,7 +482,7 @@ export class Transformer extends Visitor {
466
482
  enterEnv(options, "lambda", params.length);
467
483
  params.forEach((param, i) => {
468
484
  // let inits = this.nodePool[node.elts[3]].elts;
469
- if (args[i]) {
485
+ if (args[i] !== undefined) {
470
486
  // Got an arg so use it.
471
487
  addWord(options, param, {
472
488
  name: param,
@@ -514,7 +530,7 @@ export class Transformer extends Visitor {
514
530
  IDENT(node, options, resume) {
515
531
  let word = findWord(options, node.elts[0]);
516
532
  const err = [];
517
- const val = word && word.val || node.elts[0];
533
+ const val = word?.val !== undefined ? word.val : node.elts[0];
518
534
  resume(err, val);
519
535
  }
520
536
  STR(node, options, resume) {
@@ -545,6 +561,24 @@ export class Transformer extends Visitor {
545
561
  });
546
562
  });
547
563
  }
564
+ SUB(node, options, resume) {
565
+ this.visit(node.elts[0], options, (e0, v0) => {
566
+ this.visit(node.elts[1], options, (e1, v1) => {
567
+ const err = [].concat(e0).concat(e1);
568
+ const val = +v0 - +v1;
569
+ resume(err, val);
570
+ });
571
+ });
572
+ }
573
+ LT(node, options, resume) {
574
+ this.visit(node.elts[0], options, (e0, v0) => {
575
+ this.visit(node.elts[1], options, (e1, v1) => {
576
+ const err = [].concat(e0).concat(e1);
577
+ const val = +v0 < +v1;
578
+ resume(err, val);
579
+ });
580
+ });
581
+ }
548
582
  BOOL(node, options, resume) {
549
583
  const err = [];
550
584
  const val = node.elts[0];
@@ -590,10 +624,10 @@ export class Transformer extends Visitor {
590
624
  this.visit(node.elts[0], options, (err1, val1) => {
591
625
  this.visit(node.elts[1], options, (err2, val2) => {
592
626
  if (isNaN(+val1)) {
593
- err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
627
+ err1 = err1.concat(error("MUL first argument must be a number: ", JSON.stringify(node, null, 2)));
594
628
  }
595
629
  if (isNaN(+val2)) {
596
- err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
630
+ err2 = err2.concat(error("MUL second argument must be a number: ", JSON.stringify(node, null, 2)));
597
631
  }
598
632
  const err = [].concat(err1).concat(err2);
599
633
  const val = +val1 * +val2;
@@ -663,7 +697,6 @@ export class Transformer extends Visitor {
663
697
  this.visit(node.elts[1], options, (e1, v1) => {
664
698
  options.args = v1;
665
699
  this.visit(node.elts[0], options, (e0, v0) => {
666
- //exitEnv(options);
667
700
  const err = [].concat(e1).concat(e0);
668
701
  const val = v0;
669
702
  resume(err, val);
@@ -671,6 +704,8 @@ export class Transformer extends Visitor {
671
704
  });
672
705
  }
673
706
  MAP(node, options, resume) {
707
+ // FIXME make async
708
+ options.SYNC = true;
674
709
  this.visit(node.elts[1], options, (e1, v1) => {
675
710
  let err = [];
676
711
  let val = [];
@@ -686,6 +721,55 @@ export class Transformer extends Visitor {
686
721
  });
687
722
  });
688
723
  });
724
+ options.SYNC = false;
725
+ }
726
+ FILTER(node, options, resume) {
727
+ // FIXME make async
728
+ options.SYNC = true;
729
+ this.visit(node.elts[1], options, (e1, v1) => {
730
+ let err = [];
731
+ let val = [];
732
+ v1.forEach(args => {
733
+ options.args = args;
734
+ options = JSON.parse(JSON.stringify(options)); // Copy option arg support async.
735
+ this.visit(node.elts[0], options, (e0, v0) => {
736
+ if (!!v0) {
737
+ val.push(args);
738
+ } else {
739
+ val.push(null);
740
+ }
741
+ err = err.concat(e0);
742
+ if (val.length === v1.length) {
743
+ val = val.filter(v => v !== null);
744
+ resume(err, val);
745
+ }
746
+ });
747
+ });
748
+ });
749
+ options.SYNC = false;
750
+ }
751
+ REDUCE(node, options, resume) {
752
+ // FIXME make async
753
+ // reduce (fn) acc list
754
+ options.SYNC = true;
755
+ this.visit(node.elts[1], options, (e1, v1) => {
756
+ this.visit(node.elts[2], options, (e2, v2) => {
757
+ let err = [];
758
+ let val = v1;
759
+ v2.forEach((args, index) => {
760
+ options.args = [val, args];
761
+ options = JSON.parse(JSON.stringify(options)); // Copy option arg support async.
762
+ this.visit(node.elts[0], options, (e0, v0) => {
763
+ val = v0;
764
+ err = err.concat(e0);
765
+ if (index === v2.length - 1) {
766
+ resume(err, val);
767
+ }
768
+ });
769
+ });
770
+ });
771
+ });
772
+ options.SYNC = false;
689
773
  }
690
774
  STYLE(node, options, resume) {
691
775
  const err = [];
@@ -698,7 +782,7 @@ export class Transformer extends Visitor {
698
782
  this.visit(node.elts[0], options, (e0, v0) => {
699
783
  const e0Node = this.node(node.elts[0]);
700
784
  const expr = (
701
- e0Node.tag === 'NUM' ||
785
+ e0Node.tag === 'BOOL' ||
702
786
  e0Node.tag === 'NUM'
703
787
  ) && e0Node || {
704
788
  tag: 'STR', elts: [`${v0}`]
@@ -753,6 +837,37 @@ export class Transformer extends Visitor {
753
837
  }
754
838
  });
755
839
  }
840
+ GET(node, options, resume) {
841
+ this.visit(node.elts[0], options, (e0, v0) => {
842
+ this.visit(node.elts[1], options, (e1, v1) => {
843
+ const err = [...e0, ...e1];
844
+ assert(typeof v0 === "object", "Type Error: expected v0 to be an object.");
845
+ assert(typeof v1 === "string", "Type Error: expected v1 to be a string.");
846
+ const val = v0[v1];
847
+ resume(err, val);
848
+ });
849
+ });
850
+ }
851
+ NTH(node, options, resume) {
852
+ this.visit(node.elts[0], options, (e0, v0) => {
853
+ this.visit(node.elts[1], options, (e1, v1) => {
854
+ const err = [...e0, ...e1];
855
+ assert(typeof v0 === "number", "Type Error: expected v0 to be a number. Got " + (typeof v0));
856
+ assert(typeof v1 === "object", "Type Error: expected v1 to be an object. Got " + (typeof v1));
857
+ const val = v1[v0];
858
+ resume(err, val);
859
+ });
860
+ });
861
+ }
862
+ PRINT(node, options, resume) {
863
+ this.visit(node.elts[0], options, (e0, v0) => {
864
+ const err = e0;
865
+ const val = {
866
+ print: v0,
867
+ };
868
+ resume(err, val);
869
+ })
870
+ }
756
871
  }
757
872
 
758
873
  export class Renderer {