mevento 1.0.0 → 1.2.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.
@@ -26,9 +26,7 @@ function hashCode(str) {
26
26
  return hash;
27
27
  for (i = 0; i < str.length; i++) {
28
28
  chr = str.charCodeAt(i);
29
- // tslint:disable-next-line:no-bitwise
30
29
  hash = ((hash << 5) - hash) + chr;
31
- // tslint:disable-next-line:no-bitwise
32
30
  hash |= 0; // Convert to 32bit integer
33
31
  }
34
32
  return hash;
@@ -71,6 +69,14 @@ TokenType.mult = 31;
71
69
  TokenType.mod = 32;
72
70
  TokenType.invalid = 33;
73
71
  TokenType.colon = 34;
72
+ TokenType.WHILE_TILL = 35;
73
+ TokenType.FOR_LOOP = 36;
74
+ TokenType.up = 37;
75
+ TokenType.down = 38;
76
+ TokenType.with = 39;
77
+ TokenType.in = 40;
78
+ TokenType.TILL = 41;
79
+ TokenType.BREAK = 42;
74
80
  class Token {
75
81
  constructor(type, value, line = 1, col = 1) {
76
82
  this.type = type;
@@ -474,15 +480,31 @@ Lexer._defaultLanguage = new LexerDictionary("en", {
474
480
  "true": "true",
475
481
  "false": "false",
476
482
  "null": "null",
483
+ "while": "while",
484
+ "for": "for",
485
+ "with": "with",
486
+ "up": "up",
487
+ "down": "down",
488
+ "till": "till",
489
+ "in": "in",
490
+ "break": "break",
477
491
  });
478
492
  Lexer.languages = [
479
493
  Lexer._defaultLanguage,
480
494
  new LexerDictionary("fr", {
481
495
  "si": "if",
482
496
  "sinon": "else",
483
- "vrai": "else",
497
+ "vrai": "true",
484
498
  "faux": "false",
485
499
  "nul": "null",
500
+ "tanque": "while",
501
+ "pour": "for",
502
+ "avec": "with",
503
+ "mon": "up",
504
+ "desc": "down",
505
+ "jusqua": "till",
506
+ "dans": "in",
507
+ "couper": "break",
486
508
  }),
487
509
  new LexerDictionary("bm", {
488
510
  "nii": "if",
@@ -490,6 +512,14 @@ Lexer.languages = [
490
512
  "tien": "true",
491
513
  "galon": "false",
492
514
  "gansan": "null",
515
+ "foo": "while",
516
+ "seginka": "for",
517
+ "niin": "with",
518
+ "kay": "up",
519
+ "kaj": "down",
520
+ "kata": "till",
521
+ "kono": "in",
522
+ "tike": "break",
493
523
  }),
494
524
  ];
495
525
  Lexer.RESERVED = {
@@ -498,6 +528,14 @@ Lexer.RESERVED = {
498
528
  "true": Token.from(TokenType.TRUE, true),
499
529
  "false": Token.from(TokenType.FALSE, false),
500
530
  "null": Token.from(TokenType.NULL, null),
531
+ "for": Token.from(TokenType.FOR_LOOP, "for"),
532
+ "while": Token.from(TokenType.WHILE_TILL, "while"),
533
+ "with": Token.from(TokenType.with, "with"),
534
+ "up": Token.from(TokenType.up, "up"),
535
+ "down": Token.from(TokenType.down, "down"),
536
+ "till": Token.from(TokenType.TILL, "till"),
537
+ "in": Token.from(TokenType.in, "in"),
538
+ "break": Token.from(TokenType.BREAK, "break"),
501
539
  };
502
540
  /**
503
541
  * Parser
@@ -612,7 +650,7 @@ class IfStatementAST extends AST {
612
650
  this.alternate = alternate;
613
651
  }
614
652
  toString() {
615
- return `if ${this.test} ${this.consequent} ${this.alternate !== null ? `else ${this.alternate} ` : ''}`;
653
+ return `if ${this.test} ${this.consequent} ${this.alternate ? `else ${this.alternate} ` : ''}`;
616
654
  }
617
655
  }
618
656
  class LogicalExpressionAST extends AST {
@@ -663,6 +701,47 @@ class ObjectProperty extends AST {
663
701
  this.key = key;
664
702
  }
665
703
  }
704
+ class WhileLoopStatement extends AST {
705
+ constructor(test, body, startToken, endToken, retain = false) {
706
+ super(startToken?.line, startToken?.col);
707
+ this.retain = false;
708
+ this.test = test;
709
+ this.body = body;
710
+ this.retain = retain;
711
+ }
712
+ }
713
+ class ForLoopStatement extends AST {
714
+ constructor(init, test, update, direction, body, startToken, endToken, retain = false) {
715
+ super(startToken?.line, startToken?.col);
716
+ this.init = init;
717
+ this.test = test;
718
+ this.update = update;
719
+ this.direction = direction;
720
+ this.body = body;
721
+ this.retain = retain;
722
+ }
723
+ }
724
+ class ForOfStatement extends AST {
725
+ constructor(identifier, collection, body, startToken, endToken, retain = false) {
726
+ super(startToken?.line, startToken?.col);
727
+ this.identifier = identifier;
728
+ this.collection = collection;
729
+ this.body = body;
730
+ this.retain = retain;
731
+ }
732
+ }
733
+ class TupleExpression extends AST {
734
+ constructor(first, second) {
735
+ super(first.line, first.col);
736
+ this.first = first;
737
+ this.second = second;
738
+ }
739
+ }
740
+ class BreakAST extends AST {
741
+ constructor(line, col) {
742
+ super(line, col);
743
+ }
744
+ }
666
745
  class Parser {
667
746
  constructor(lexer) {
668
747
  this.currentToken = lexer.nextToken();
@@ -796,7 +875,7 @@ class Parser {
796
875
  if (this.currentToken?.type != TokenType.rbrace) {
797
876
  properties.push(this._property());
798
877
  }
799
- while (this.currentToken?.type == TokenType.comma) {
878
+ while (this.currentToken?.type === TokenType.comma) {
800
879
  this._eat(TokenType.comma);
801
880
  properties.push(this._property());
802
881
  }
@@ -905,6 +984,8 @@ class Parser {
905
984
  break;
906
985
  }
907
986
  body.push(this._statement());
987
+ if (this._expect(TokenType.rbrace))
988
+ break;
908
989
  if (this.currentToken.type !== TokenType.eol &&
909
990
  this.currentToken.type !== TokenType.semi &&
910
991
  this.currentToken.type !== TokenType.eof) {
@@ -952,8 +1033,94 @@ class Parser {
952
1033
  }
953
1034
  return new IfStatementAST(test, consequent, alternate);
954
1035
  }
1036
+ _whileLoop() {
1037
+ const token = this.currentToken;
1038
+ this._eat(TokenType.WHILE_TILL);
1039
+ const test = this._expression();
1040
+ const body = this.currentToken.type === TokenType.lbrace ? this._blockStatement() : this._expression();
1041
+ return new WhileLoopStatement(test, body, token, this.currentToken);
1042
+ }
1043
+ _forOfIdentifier() {
1044
+ let node;
1045
+ switch (this.currentToken.type) {
1046
+ case TokenType.lparen: {
1047
+ // probable tuple
1048
+ this._eat(TokenType.lparen);
1049
+ const first = this._variable();
1050
+ this._eat(TokenType.comma);
1051
+ const second = this._variable();
1052
+ this._eat(TokenType.rparen);
1053
+ return new TupleExpression(first, second);
1054
+ }
1055
+ // TokenType.LBRACE -> objectPattern()
1056
+ // TokenType.LBRACKET -> arrayPattern()
1057
+ default:
1058
+ return this._variable();
1059
+ }
1060
+ }
1061
+ /**
1062
+ * # ForLoopStatement with step
1063
+ * (seginka|for) a=0 (foo|to) 10 (kay|kaj) niin 2 { # for a = 0; a<10; a+=2
1064
+ *
1065
+ * }
1066
+ * (seginka|for) mali kono a
1067
+ */
1068
+ _forLoop() {
1069
+ const startToken = this.currentToken;
1070
+ this._eat(TokenType.FOR_LOOP);
1071
+ let forOf = [TokenType.lparen].includes(this.currentToken.type);
1072
+ let node;
1073
+ if (forOf) {
1074
+ node = this._forOfIdentifier();
1075
+ }
1076
+ else {
1077
+ const expr = this._expression();
1078
+ if (!(expr instanceof AssignmentExpressionAST)) {
1079
+ forOf = true;
1080
+ }
1081
+ node = expr;
1082
+ }
1083
+ if (!forOf && node instanceof AssignmentExpressionAST) {
1084
+ // normal for
1085
+ this._eat(TokenType.TILL);
1086
+ const test = this._expression();
1087
+ let direction;
1088
+ if (this.currentToken.type === TokenType.up || this.currentToken.type === TokenType.down) {
1089
+ const t = this.currentToken;
1090
+ this._eat(t.type);
1091
+ direction = t;
1092
+ }
1093
+ else {
1094
+ direction = new Token(TokenType.up, "up");
1095
+ }
1096
+ let update;
1097
+ if (this._expect(TokenType.with)) {
1098
+ this._eat(TokenType.with);
1099
+ const expr = this._expression();
1100
+ update = expr;
1101
+ }
1102
+ else {
1103
+ update = new LiteralAST(new Token(TokenType.numberConst, 1, this.currentToken.line, this.currentToken.col), "1");
1104
+ }
1105
+ const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
1106
+ node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken);
1107
+ }
1108
+ else if (forOf) {
1109
+ this._eat(TokenType.in);
1110
+ const collection = this._expression();
1111
+ const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
1112
+ node = new ForOfStatement(node, collection, body, startToken, this.currentToken);
1113
+ }
1114
+ else {
1115
+ error(this.currentToken);
1116
+ }
1117
+ return node;
1118
+ }
955
1119
  _statement() {
956
1120
  switch (this.currentToken.type) {
1121
+ case TokenType.BREAK:
1122
+ this._eat(TokenType.BREAK);
1123
+ return new BreakAST(this.currentToken?.line, this.currentToken?.col);
957
1124
  case TokenType.semi:
958
1125
  this._eatSemi();
959
1126
  return this._statement();
@@ -962,6 +1129,10 @@ class Parser {
962
1129
  return this._statement();
963
1130
  case TokenType.IF:
964
1131
  return this._ifStatement();
1132
+ case TokenType.WHILE_TILL:
1133
+ return this._whileLoop();
1134
+ case TokenType.FOR_LOOP:
1135
+ return this._forLoop();
965
1136
  default:
966
1137
  return this._statementExpression();
967
1138
  }
@@ -969,32 +1140,31 @@ class Parser {
969
1140
  _expect(type) {
970
1141
  return this.currentToken?.type === type;
971
1142
  }
972
- _statements() {
973
- this._eatEOL();
1143
+ _definition() {
1144
+ this._eatSemiOrEOL();
974
1145
  if (this._expect(TokenType.eof)) {
975
1146
  return [];
976
1147
  }
977
1148
  const results = [this._statement()];
978
- while ((this.currentToken.type === TokenType.eol ||
979
- this.currentToken.type === TokenType.semi)) {
1149
+ while (true) {
980
1150
  this._eatSemiOrEOL();
981
1151
  if (this.currentToken.type === TokenType.eof) {
982
1152
  this._eat(TokenType.eof);
983
1153
  break;
984
1154
  }
985
1155
  results.push(this._statement());
986
- if (this.currentToken.type !== TokenType.eol &&
987
- this.currentToken.type !== TokenType.semi &&
988
- this.currentToken.type !== TokenType.eof) {
989
- error(this.currentToken);
990
- }
1156
+ // if (this.currentToken!.type !== TokenType.eol &&
1157
+ // this.currentToken!.type !== TokenType.semi &&
1158
+ // this.currentToken!.type !== TokenType.eof) {
1159
+ // error(this.currentToken!);
1160
+ // }
991
1161
  }
992
1162
  return results;
993
1163
  }
994
1164
  _root() {
995
1165
  const source = this.lexer.source;
996
1166
  const name = "<module>";
997
- const list = this._statements();
1167
+ const list = this._definition();
998
1168
  return new RootAST(list, name, source);
999
1169
  }
1000
1170
  parse() {
@@ -1014,6 +1184,8 @@ Parser._binopPrecdences = {
1014
1184
  [TokenType.div]: 40,
1015
1185
  [TokenType.mod]: 40,
1016
1186
  };
1187
+ class BreakBranch {
1188
+ }
1017
1189
  // AST Wallker
1018
1190
  class ANodeVisitor {
1019
1191
  constructor() {
@@ -1025,14 +1197,6 @@ class ANodeVisitor {
1025
1197
  this._nodesVisitors[methodName] = visitor;
1026
1198
  }
1027
1199
  }
1028
- class AsyncNodeVisitor extends ANodeVisitor {
1029
- async visit(node) {
1030
- const methodName = `visit${node.constructor.name}`;
1031
- // const fn = Object.getPrototypeOf(this)[methodName];
1032
- const fn = this._nodesVisitors[methodName];
1033
- return await fn?.call(this, node);
1034
- }
1035
- }
1036
1200
  class NodeVisitor extends ANodeVisitor {
1037
1201
  visit(node) {
1038
1202
  const methodName = `visit${node.constructor.name}`;
@@ -1045,6 +1209,7 @@ class MEvento extends NodeVisitor {
1045
1209
  constructor() {
1046
1210
  super();
1047
1211
  this._memory = {};
1212
+ this.debug = false;
1048
1213
  this._functionsRegistry = {};
1049
1214
  this.registerVisitor(RootAST, this.visitRootAST);
1050
1215
  this.registerVisitor(BlockStatementAST, this.visitBlockStatementAST);
@@ -1061,8 +1226,17 @@ class MEvento extends NodeVisitor {
1061
1226
  this.registerVisitor(ObjectProperty, this.visitObjectProperty);
1062
1227
  this.registerVisitor(ObjectExpression, this.visitObjectExpression);
1063
1228
  this.registerVisitor(ArrayExpression, this.visitArrayExpression);
1229
+ this.registerVisitor(WhileLoopStatement, this.visitWhileLoopStatement);
1230
+ this.registerVisitor(ForLoopStatement, this.visitForLoopStatement);
1231
+ this.registerVisitor(ForOfStatement, this.visitForOfStatement);
1232
+ this.registerVisitor(BreakAST, this.visitBreakAST);
1064
1233
  this._functionsRegistry = { ...MEvento._globalFunctionsRegistry };
1065
1234
  }
1235
+ log(message) {
1236
+ if (this.debug) {
1237
+ console.log(message);
1238
+ }
1239
+ }
1066
1240
  visitRootAST(node) {
1067
1241
  const list = node.body;
1068
1242
  let last;
@@ -1219,7 +1393,7 @@ class MEvento extends NodeVisitor {
1219
1393
  if (testBoolValue) {
1220
1394
  return this.visit(node.consequent);
1221
1395
  }
1222
- if (node.alternate !== null) {
1396
+ if (node.alternate) {
1223
1397
  return this.visit(node.alternate);
1224
1398
  }
1225
1399
  return null;
@@ -1267,6 +1441,85 @@ class MEvento extends NodeVisitor {
1267
1441
  const args = this.resolveArguments(node.elements);
1268
1442
  return args;
1269
1443
  }
1444
+ visitBreakAST(node) {
1445
+ return new BreakBranch();
1446
+ }
1447
+ visitWhileLoopStatement(node) {
1448
+ this.log(`WhileLoopStatement ${node.test} ${node.body}`);
1449
+ const retainer = node.retain ? [] : undefined;
1450
+ while (_boolValue(this.visit(node.test))) {
1451
+ const ret = this.visit(node.body);
1452
+ if (ret instanceof BreakBranch) {
1453
+ break;
1454
+ }
1455
+ retainer?.push(ret);
1456
+ }
1457
+ return retainer || null;
1458
+ }
1459
+ visitForLoopStatement(node) {
1460
+ const retainer = node.retain ? [] : undefined;
1461
+ const loopIdentifier = node.init.identifier;
1462
+ if (!(loopIdentifier instanceof IdentifierAST))
1463
+ throw new Error("Unexpected identifer found");
1464
+ const initialValue = this.visit(node.init.init);
1465
+ this._memory[loopIdentifier.value] = initialValue;
1466
+ retainer?.push(initialValue);
1467
+ const test = () => {
1468
+ const ret = this.visit(node.test);
1469
+ if (isNum(ret)) {
1470
+ const tmp = this._memory[loopIdentifier.value];
1471
+ return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1472
+ }
1473
+ return _boolValue(ret);
1474
+ };
1475
+ while (test()) {
1476
+ const ret = this.visit(node.body);
1477
+ if (ret instanceof BreakBranch) {
1478
+ break;
1479
+ }
1480
+ retainer?.push(ret);
1481
+ // update
1482
+ if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1483
+ // auto handle
1484
+ const tmp = this._memory[loopIdentifier.value];
1485
+ if (!isNum(tmp))
1486
+ throw Error("Can update value");
1487
+ this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1488
+ }
1489
+ else {
1490
+ this.visit(node.update);
1491
+ }
1492
+ }
1493
+ return retainer || null;
1494
+ }
1495
+ visitForOfStatement(node) {
1496
+ const collection = this.visit(node.collection);
1497
+ if (!Array.isArray(collection)) {
1498
+ throw Error("Can iterate non array object");
1499
+ }
1500
+ const retainer = node.retain ? [] : undefined;
1501
+ for (const it of collection) {
1502
+ this._declareForIdentifier(node.identifier, it);
1503
+ const ret = this.visit(node.body);
1504
+ if (ret instanceof BreakBranch) {
1505
+ break;
1506
+ }
1507
+ retainer?.push(ret);
1508
+ }
1509
+ return retainer || null;
1510
+ }
1511
+ _declareForIdentifier(node, value) {
1512
+ if (node instanceof TupleExpression) {
1513
+ if (!Array.isArray(value)) {
1514
+ throw Error("Unable to make a tuple from non Array element");
1515
+ }
1516
+ this._memory[node.first.value] = value[0];
1517
+ this._memory[node.second.value] = value[1];
1518
+ null;
1519
+ }
1520
+ this._memory[node.value] = value;
1521
+ null;
1522
+ }
1270
1523
  resolveArguments(args) {
1271
1524
  return args.map((it) => {
1272
1525
  return this.visit(it);
@@ -1476,7 +1729,7 @@ class MEventoAsync extends MEvento {
1476
1729
  if (testBoolValue) {
1477
1730
  return await this.visit(node.consequent);
1478
1731
  }
1479
- if (node.alternate !== null) {
1732
+ if (node.alternate) {
1480
1733
  return await this.visit(node.alternate);
1481
1734
  }
1482
1735
  return null;
@@ -1524,6 +1777,70 @@ class MEventoAsync extends MEvento {
1524
1777
  const args = await this.resolveArgumentsAsync(node.elements);
1525
1778
  return args;
1526
1779
  }
1780
+ async visitWhileLoopStatement(node) {
1781
+ this.log(`WhileLoopStatement ${node.test} ${node.body}`);
1782
+ const retainer = node.retain ? [] : undefined;
1783
+ while (_boolValue(this.visit(node.test))) {
1784
+ const ret = await this.visit(node.body);
1785
+ if (ret instanceof BreakBranch) {
1786
+ break;
1787
+ }
1788
+ retainer?.push(ret);
1789
+ }
1790
+ return retainer;
1791
+ }
1792
+ async visitForLoopStatement(node) {
1793
+ const retainer = node.retain ? [] : undefined;
1794
+ const loopIdentifier = node.init.identifier;
1795
+ if (!(loopIdentifier instanceof IdentifierAST))
1796
+ throw new Error("Unexpected identifer found");
1797
+ const initialValue = this.visit(node.init.init);
1798
+ this._memory[loopIdentifier.value] = initialValue;
1799
+ retainer?.push(initialValue);
1800
+ const test = () => {
1801
+ const ret = this.visit(node.test);
1802
+ if (isNum(ret)) {
1803
+ const tmp = this._memory[loopIdentifier.value];
1804
+ return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1805
+ }
1806
+ return _boolValue(ret);
1807
+ };
1808
+ while (test()) {
1809
+ const ret = await this.visit(node.body);
1810
+ if (ret instanceof BreakBranch) {
1811
+ break;
1812
+ }
1813
+ retainer?.push(ret);
1814
+ // update
1815
+ if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1816
+ // auto handle
1817
+ const tmp = this._memory[loopIdentifier.value];
1818
+ if (!isNum(tmp))
1819
+ throw Error("Can update value");
1820
+ this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1821
+ }
1822
+ else {
1823
+ this.visit(node.update);
1824
+ }
1825
+ }
1826
+ return retainer;
1827
+ }
1828
+ async visitForOfStatement(node) {
1829
+ const collection = this.visit(node.collection);
1830
+ if (!Array.isArray(collection)) {
1831
+ throw Error("Can iterate non array object");
1832
+ }
1833
+ const retainer = node.retain ? [] : undefined;
1834
+ for (const it of collection) {
1835
+ this._declareForIdentifier(node.identifier, it);
1836
+ const ret = await this.visit(node.body);
1837
+ if (ret instanceof BreakBranch) {
1838
+ break;
1839
+ }
1840
+ retainer?.push(ret);
1841
+ }
1842
+ return retainer;
1843
+ }
1527
1844
  async resolveArgumentsAsync(args) {
1528
1845
  return await Promise.all(args.map(async (it) => {
1529
1846
  return await this.visit(it);
@@ -1545,9 +1862,6 @@ class MEventoAsync extends MEvento {
1545
1862
  return await mevento.visit(module);
1546
1863
  }
1547
1864
  static newInstance() {
1548
- // const lexer = Lexer(source);
1549
- // const parser = Parser(lexer);
1550
- // const module = parser.parse();
1551
1865
  return new MEventoAsync();
1552
1866
  }
1553
1867
  clone() {
@@ -1566,5 +1880,5 @@ class MEventoAsync extends MEvento {
1566
1880
  * Generated bundle index. Do not edit.
1567
1881
  */
1568
1882
 
1569
- export { MEvento, MEventoAsync };
1883
+ export { AST, ArrayExpression, AssignmentExpressionAST, BinaryExpressionAST, BlockStatementAST, BreakAST, BreakBranch, CallExpressionAST, ExpressionStatementAST, ForLoopStatement, ForOfStatement, IdentifierAST, IfStatementAST, IndexAccessorAST, LexerDictionary, LiteralAST, LogicalExpressionAST, MEvento, MEventoAsync, NodeVisitor, ObjectExpression, ObjectProperty, RootAST, Token, TokenType, TupleExpression, UnaryExpressionAST, WhileLoopStatement };
1570
1884
  //# sourceMappingURL=mevento.mjs.map