@graffiticode/basis 1.5.12 → 1.5.13

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 +4 -1
  2. package/src/compiler.js +141 -21
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graffiticode/basis",
3
3
  "type": "module",
4
- "version": "1.5.12",
4
+ "version": "1.5.13",
5
5
  "description": "The basis library for creating Graffiticode languages",
6
6
  "main": "index.js",
7
7
  "scripts": {
@@ -26,5 +26,8 @@
26
26
  "https": "^1.0.0",
27
27
  "jest": "^27.0.1",
28
28
  "react": "^17.0.2"
29
+ },
30
+ "dependencies": {
31
+ "decimal.js": "^10.5.0"
29
32
  }
30
33
  }
package/src/compiler.js CHANGED
@@ -1,5 +1,6 @@
1
1
  /* Copyright (c) 2021, ARTCOMPILER INC */
2
2
  import {assert, message, messages, reserveCodeRange} from "./share.js";
3
+ import Decimal from 'decimal.js';
3
4
  reserveCodeRange(1000, 1999, "compile");
4
5
  messages[1001] = "Node ID %1 not found in pool.";
5
6
  messages[1002] = "Invalid tag in node with Node ID %1.";
@@ -308,6 +309,35 @@ export class Checker extends Visitor {
308
309
  const val = node;
309
310
  resume(err, val);
310
311
  }
312
+ RANGE(node, options, resume) {
313
+ this.visit(node.elts[0], options, (err1, val1) => {
314
+ this.visit(node.elts[1], options, (err2, val2) => {
315
+ this.visit(node.elts[2], options, (err3, val3) => {
316
+ const err = [].concat(err1).concat(err2).concat(err3);
317
+ const val = node;
318
+ resume(err, val);
319
+ });
320
+ });
321
+ });
322
+ }
323
+ EQ(node, options, resume) {
324
+ this.visit(node.elts[0], options, (err1, val1) => {
325
+ this.visit(node.elts[1], options, (err2, val2) => {
326
+ const err = [].concat(err1).concat(err2);
327
+ const val = node;
328
+ resume(err, val);
329
+ });
330
+ });
331
+ }
332
+ MOD(node, options, resume) {
333
+ this.visit(node.elts[0], options, (err1, val1) => {
334
+ this.visit(node.elts[1], options, (err2, val2) => {
335
+ const err = [].concat(err1).concat(err2);
336
+ const val = node;
337
+ resume(err, val);
338
+ });
339
+ });
340
+ }
311
341
  }
312
342
 
313
343
  function enterEnv(ctx, name, paramc) {
@@ -556,8 +586,12 @@ export class Transformer extends Visitor {
556
586
  this.visit(node.elts[0], options, (e0, v0) => {
557
587
  this.visit(node.elts[1], options, (e1, v1) => {
558
588
  const err = [].concat(e0).concat(e1);
559
- const val = +v0 + +v1;
560
- resume(err, val);
589
+ try {
590
+ const val = new Decimal(v0).plus(new Decimal(v1)).toNumber();
591
+ resume(err, val);
592
+ } catch (e) {
593
+ resume([...err, `Error in ADD operation: ${e.message}`], NaN);
594
+ }
561
595
  });
562
596
  });
563
597
  }
@@ -565,8 +599,12 @@ export class Transformer extends Visitor {
565
599
  this.visit(node.elts[0], options, (e0, v0) => {
566
600
  this.visit(node.elts[1], options, (e1, v1) => {
567
601
  const err = [].concat(e0).concat(e1);
568
- const val = +v0 - +v1;
569
- resume(err, val);
602
+ try {
603
+ const val = new Decimal(v0).minus(new Decimal(v1)).toNumber();
604
+ resume(err, val);
605
+ } catch (e) {
606
+ resume([...err, `Error in SUB operation: ${e.message}`], NaN);
607
+ }
570
608
  });
571
609
  });
572
610
  }
@@ -574,8 +612,12 @@ export class Transformer extends Visitor {
574
612
  this.visit(node.elts[0], options, (e0, v0) => {
575
613
  this.visit(node.elts[1], options, (e1, v1) => {
576
614
  const err = [].concat(e0).concat(e1);
577
- const val = +v0 < +v1;
578
- resume(err, val);
615
+ try {
616
+ const val = new Decimal(v0).lessThan(new Decimal(v1));
617
+ resume(err, val);
618
+ } catch (e) {
619
+ resume([...err, `Error in LT operation: ${e.message}`], false);
620
+ }
579
621
  });
580
622
  });
581
623
  }
@@ -623,30 +665,57 @@ export class Transformer extends Visitor {
623
665
  MUL(node, options, resume) {
624
666
  this.visit(node.elts[0], options, (err1, val1) => {
625
667
  this.visit(node.elts[1], options, (err2, val2) => {
626
- if (isNaN(+val1)) {
627
- err1 = err1.concat(error("MUL first argument must be a number: ", JSON.stringify(node, null, 2)));
628
- }
629
- if (isNaN(+val2)) {
630
- err2 = err2.concat(error("MUL second argument must be a number: ", JSON.stringify(node, null, 2)));
668
+ let err = [].concat(err1).concat(err2);
669
+ try {
670
+ const val = new Decimal(val1).times(new Decimal(val2)).toNumber();
671
+ resume(err, val);
672
+ } catch (e) {
673
+ if (isNaN(+val1)) {
674
+ err = err.concat(error("MUL first argument must be a number: ", JSON.stringify(node, null, 2)));
675
+ }
676
+ if (isNaN(+val2)) {
677
+ err = err.concat(error("MUL second argument must be a number: ", JSON.stringify(node, null, 2)));
678
+ }
679
+ resume([...err, `Error in MUL operation: ${e.message}`], NaN);
631
680
  }
632
- const err = [].concat(err1).concat(err2);
633
- const val = +val1 * +val2;
634
- resume(err, val);
635
681
  });
636
682
  });
637
683
  }
638
684
  POW(node, options, resume) {
639
685
  this.visit(node.elts[0], options, (err1, val1) => {
640
686
  this.visit(node.elts[1], options, (err2, val2) => {
641
- if (isNaN(+val1)) {
642
- err1 = err1.concat(error("Argument must be a number.", node.elts[0]));
687
+ let err = [].concat(err1).concat(err2);
688
+ try {
689
+ const val = new Decimal(val1).pow(new Decimal(val2)).toNumber();
690
+ resume(err, val);
691
+ } catch (e) {
692
+ if (isNaN(+val1)) {
693
+ err = err.concat(error("POW first argument must be a number: ", JSON.stringify(node, null, 2)));
694
+ }
695
+ if (isNaN(+val2)) {
696
+ err = err.concat(error("POW second argument must be a number: ", JSON.stringify(node, null, 2)));
697
+ }
698
+ resume([...err, `Error in POW operation: ${e.message}`], NaN);
643
699
  }
644
- if (isNaN(+val2)) {
645
- err2 = err2.concat(error("Argument must be a number.", node.elts[1]));
700
+ });
701
+ });
702
+ }
703
+ MOD(node, options, resume) {
704
+ this.visit(node.elts[0], options, (err1, val1) => {
705
+ this.visit(node.elts[1], options, (err2, val2) => {
706
+ let err = [].concat(err1).concat(err2);
707
+ try {
708
+ const val = new Decimal(val1).mod(new Decimal(val2)).toNumber();
709
+ resume(err, val);
710
+ } catch (e) {
711
+ if (isNaN(+val1)) {
712
+ err = err.concat(error("MOD first argument must be a number: ", JSON.stringify(node, null, 2)));
713
+ }
714
+ if (isNaN(+val2)) {
715
+ err = err.concat(error("MOD second argument must be a number: ", JSON.stringify(node, null, 2)));
716
+ }
717
+ resume([...err, `Error in MOD operation: ${e.message}`], NaN);
646
718
  }
647
- const err = [].concat(err1).concat(err2);
648
- const val = node;
649
- resume(err, val);
650
719
  });
651
720
  });
652
721
  }
@@ -884,6 +953,57 @@ export class Transformer extends Visitor {
884
953
  resume(err, val);
885
954
  })
886
955
  }
956
+ EQ(node, options, resume) {
957
+ this.visit(node.elts[0], options, (e0, v0) => {
958
+ this.visit(node.elts[1], options, (e1, v1) => {
959
+ const err = [].concat(e0).concat(e1);
960
+ try {
961
+ const val = new Decimal(v0).equals(new Decimal(v1));
962
+ resume(err, val);
963
+ } catch (e) {
964
+ resume([...err, `Error in EQ operation: ${e.message}`], false);
965
+ }
966
+ });
967
+ });
968
+ }
969
+ RANGE(node, options, resume) {
970
+ this.visit(node.elts[0], options, (e0, v0) => {
971
+ this.visit(node.elts[1], options, (e1, v1) => {
972
+ this.visit(node.elts[2], options, (e2, v2) => {
973
+ const err = [].concat(e0).concat(e1).concat(e2);
974
+ try {
975
+ const start = new Decimal(v0);
976
+ const end = new Decimal(v1);
977
+ const step = new Decimal(v2);
978
+
979
+ if (step.isZero()) {
980
+ resume([...err, 'Error in RANGE operation: step cannot be zero'], []);
981
+ return;
982
+ }
983
+
984
+ const result = [];
985
+ let current = start;
986
+
987
+ if (step.isPositive()) {
988
+ while (current.lessThan(end)) {
989
+ result.push(current.toNumber());
990
+ current = current.plus(step);
991
+ }
992
+ } else {
993
+ while (current.greaterThan(end)) {
994
+ result.push(current.toNumber());
995
+ current = current.plus(step);
996
+ }
997
+ }
998
+
999
+ resume(err, result);
1000
+ } catch (e) {
1001
+ resume([...err, `Error in RANGE operation: ${e.message}`], []);
1002
+ }
1003
+ });
1004
+ });
1005
+ });
1006
+ }
887
1007
  }
888
1008
 
889
1009
  export class Renderer {