mevento 1.0.0 → 1.2.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.
@@ -28,9 +28,7 @@ function hashCode(str) {
28
28
  return hash;
29
29
  for (i = 0; i < str.length; i++) {
30
30
  chr = str.charCodeAt(i);
31
- // tslint:disable-next-line:no-bitwise
32
31
  hash = ((hash << 5) - hash) + chr;
33
- // tslint:disable-next-line:no-bitwise
34
32
  hash |= 0; // Convert to 32bit integer
35
33
  }
36
34
  return hash;
@@ -73,6 +71,14 @@ TokenType.mult = 31;
73
71
  TokenType.mod = 32;
74
72
  TokenType.invalid = 33;
75
73
  TokenType.colon = 34;
74
+ TokenType.WHILE_TILL = 35;
75
+ TokenType.FOR_LOOP = 36;
76
+ TokenType.up = 37;
77
+ TokenType.down = 38;
78
+ TokenType.with = 39;
79
+ TokenType.in = 40;
80
+ TokenType.TILL = 41;
81
+ TokenType.BREAK = 42;
76
82
  class Token {
77
83
  constructor(type, value, line = 1, col = 1) {
78
84
  this.type = type;
@@ -476,15 +482,31 @@ Lexer._defaultLanguage = new LexerDictionary("en", {
476
482
  "true": "true",
477
483
  "false": "false",
478
484
  "null": "null",
485
+ "while": "while",
486
+ "for": "for",
487
+ "with": "with",
488
+ "up": "up",
489
+ "down": "down",
490
+ "till": "till",
491
+ "in": "in",
492
+ "break": "break",
479
493
  });
480
494
  Lexer.languages = [
481
495
  Lexer._defaultLanguage,
482
496
  new LexerDictionary("fr", {
483
497
  "si": "if",
484
498
  "sinon": "else",
485
- "vrai": "else",
499
+ "vrai": "true",
486
500
  "faux": "false",
487
501
  "nul": "null",
502
+ "tanque": "while",
503
+ "pour": "for",
504
+ "avec": "with",
505
+ "mon": "up",
506
+ "desc": "down",
507
+ "jusqua": "till",
508
+ "dans": "in",
509
+ "couper": "break",
488
510
  }),
489
511
  new LexerDictionary("bm", {
490
512
  "nii": "if",
@@ -492,6 +514,14 @@ Lexer.languages = [
492
514
  "tien": "true",
493
515
  "galon": "false",
494
516
  "gansan": "null",
517
+ "foo": "while",
518
+ "seginka": "for",
519
+ "niin": "with",
520
+ "kay": "up",
521
+ "kaj": "down",
522
+ "kata": "till",
523
+ "kono": "in",
524
+ "tike": "break",
495
525
  }),
496
526
  ];
497
527
  Lexer.RESERVED = {
@@ -500,6 +530,14 @@ Lexer.RESERVED = {
500
530
  "true": Token.from(TokenType.TRUE, true),
501
531
  "false": Token.from(TokenType.FALSE, false),
502
532
  "null": Token.from(TokenType.NULL, null),
533
+ "for": Token.from(TokenType.FOR_LOOP, "for"),
534
+ "while": Token.from(TokenType.WHILE_TILL, "while"),
535
+ "with": Token.from(TokenType.with, "with"),
536
+ "up": Token.from(TokenType.up, "up"),
537
+ "down": Token.from(TokenType.down, "down"),
538
+ "till": Token.from(TokenType.TILL, "till"),
539
+ "in": Token.from(TokenType.in, "in"),
540
+ "break": Token.from(TokenType.BREAK, "break"),
503
541
  };
504
542
  /**
505
543
  * Parser
@@ -614,7 +652,7 @@ class IfStatementAST extends AST {
614
652
  this.alternate = alternate;
615
653
  }
616
654
  toString() {
617
- return `if ${this.test} ${this.consequent} ${this.alternate !== null ? `else ${this.alternate} ` : ''}`;
655
+ return `if ${this.test} ${this.consequent} ${this.alternate ? `else ${this.alternate} ` : ''}`;
618
656
  }
619
657
  }
620
658
  class LogicalExpressionAST extends AST {
@@ -665,6 +703,47 @@ class ObjectProperty extends AST {
665
703
  this.key = key;
666
704
  }
667
705
  }
706
+ class WhileLoopStatement extends AST {
707
+ constructor(test, body, startToken, endToken, retain = false) {
708
+ super(startToken === null || startToken === void 0 ? void 0 : startToken.line, startToken === null || startToken === void 0 ? void 0 : startToken.col);
709
+ this.retain = false;
710
+ this.test = test;
711
+ this.body = body;
712
+ this.retain = retain;
713
+ }
714
+ }
715
+ class ForLoopStatement extends AST {
716
+ constructor(init, test, update, direction, body, startToken, endToken, retain = false) {
717
+ super(startToken === null || startToken === void 0 ? void 0 : startToken.line, startToken === null || startToken === void 0 ? void 0 : startToken.col);
718
+ this.init = init;
719
+ this.test = test;
720
+ this.update = update;
721
+ this.direction = direction;
722
+ this.body = body;
723
+ this.retain = retain;
724
+ }
725
+ }
726
+ class ForOfStatement extends AST {
727
+ constructor(identifier, collection, body, startToken, endToken, retain = false) {
728
+ super(startToken === null || startToken === void 0 ? void 0 : startToken.line, startToken === null || startToken === void 0 ? void 0 : startToken.col);
729
+ this.identifier = identifier;
730
+ this.collection = collection;
731
+ this.body = body;
732
+ this.retain = retain;
733
+ }
734
+ }
735
+ class TupleExpression extends AST {
736
+ constructor(first, second) {
737
+ super(first.line, first.col);
738
+ this.first = first;
739
+ this.second = second;
740
+ }
741
+ }
742
+ class BreakAST extends AST {
743
+ constructor(line, col) {
744
+ super(line, col);
745
+ }
746
+ }
668
747
  class Parser {
669
748
  constructor(lexer) {
670
749
  this.currentToken = lexer.nextToken();
@@ -915,6 +994,8 @@ class Parser {
915
994
  break;
916
995
  }
917
996
  body.push(this._statement());
997
+ if (this._expect(TokenType.rbrace))
998
+ break;
918
999
  if (this.currentToken.type !== TokenType.eol &&
919
1000
  this.currentToken.type !== TokenType.semi &&
920
1001
  this.currentToken.type !== TokenType.eof) {
@@ -926,7 +1007,8 @@ class Parser {
926
1007
  // endBlock
927
1008
  this._eat(TokenType.rbrace);
928
1009
  }
929
- return new BlockStatementAST(body, this.currentToken);
1010
+ const ret = new BlockStatementAST(body, this.currentToken);
1011
+ return ret;
930
1012
  }
931
1013
  _ifStatement() {
932
1014
  this._eat(TokenType.IF);
@@ -962,8 +1044,95 @@ class Parser {
962
1044
  }
963
1045
  return new IfStatementAST(test, consequent, alternate);
964
1046
  }
1047
+ _whileLoop() {
1048
+ const token = this.currentToken;
1049
+ this._eat(TokenType.WHILE_TILL);
1050
+ const test = this._expression();
1051
+ const body = this.currentToken.type == TokenType.lbrace ? this._blockStatement() : this._expression();
1052
+ return new WhileLoopStatement(test, body, token, this.currentToken);
1053
+ }
1054
+ _forOfIdentifier() {
1055
+ let node;
1056
+ switch (this.currentToken.type) {
1057
+ case TokenType.lparen: {
1058
+ // probable tuple
1059
+ this._eat(TokenType.lparen);
1060
+ const first = this._variable();
1061
+ this._eat(TokenType.comma);
1062
+ const second = this._variable();
1063
+ this._eat(TokenType.rparen);
1064
+ return new TupleExpression(first, second);
1065
+ }
1066
+ // TokenType.LBRACE -> objectPattern()
1067
+ // TokenType.LBRACKET -> arrayPattern()
1068
+ default:
1069
+ return this._variable();
1070
+ }
1071
+ }
1072
+ /**
1073
+ * # ForLoopStatement with step
1074
+ * (seginka|for) a=0 (foo|to) 10 (kay|kaj) niin 2 { # for a = 0; a<10; a+=2
1075
+ *
1076
+ * }
1077
+ * (seginka|for) mali kono a
1078
+ */
1079
+ _forLoop() {
1080
+ const startToken = this.currentToken;
1081
+ this._eat(TokenType.FOR_LOOP);
1082
+ let forOf = [TokenType.lparen].includes(this.currentToken.type);
1083
+ let node;
1084
+ if (forOf) {
1085
+ node = this._forOfIdentifier();
1086
+ }
1087
+ else {
1088
+ const expr = this._expression();
1089
+ if (!(expr instanceof AssignmentExpressionAST)) {
1090
+ forOf = true;
1091
+ }
1092
+ node = expr;
1093
+ }
1094
+ if (!forOf && node instanceof AssignmentExpressionAST) {
1095
+ // normal for
1096
+ this._eat(TokenType.TILL);
1097
+ const test = this._expression();
1098
+ let direction;
1099
+ if (this.currentToken.type === TokenType.up || this.currentToken.type === TokenType.down) {
1100
+ const t = this.currentToken;
1101
+ this._eat(t.type);
1102
+ direction = t;
1103
+ }
1104
+ else {
1105
+ direction = new Token(TokenType.up, "up");
1106
+ }
1107
+ let update;
1108
+ if (this._expect(TokenType.with)) {
1109
+ this._eat(TokenType.with);
1110
+ const expr = this._expression();
1111
+ update = expr;
1112
+ }
1113
+ else {
1114
+ update = new LiteralAST(new Token(TokenType.numberConst, 1, this.currentToken.line, this.currentToken.col), "1");
1115
+ }
1116
+ const body = (this.currentToken.type == TokenType.lbrace) ? this._blockStatement() : this._expression();
1117
+ node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken);
1118
+ }
1119
+ else if (forOf) {
1120
+ this._eat(TokenType.in);
1121
+ const collection = this._expression();
1122
+ const body = (this.currentToken.type == TokenType.lbrace) ? this._blockStatement() : this._expression();
1123
+ node = new ForOfStatement(node, collection, body, startToken, this.currentToken);
1124
+ }
1125
+ else {
1126
+ error(this.currentToken);
1127
+ }
1128
+ return node;
1129
+ }
965
1130
  _statement() {
1131
+ var _a, _b;
966
1132
  switch (this.currentToken.type) {
1133
+ case TokenType.BREAK:
1134
+ this._eat(TokenType.BREAK);
1135
+ return new BreakAST((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.line, (_b = this.currentToken) === null || _b === void 0 ? void 0 : _b.col);
967
1136
  case TokenType.semi:
968
1137
  this._eatSemi();
969
1138
  return this._statement();
@@ -972,6 +1141,10 @@ class Parser {
972
1141
  return this._statement();
973
1142
  case TokenType.IF:
974
1143
  return this._ifStatement();
1144
+ case TokenType.WHILE_TILL:
1145
+ return this._whileLoop();
1146
+ case TokenType.FOR_LOOP:
1147
+ return this._forLoop();
975
1148
  default:
976
1149
  return this._statementExpression();
977
1150
  }
@@ -980,32 +1153,31 @@ class Parser {
980
1153
  var _a;
981
1154
  return ((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === type;
982
1155
  }
983
- _statements() {
984
- this._eatEOL();
1156
+ _definition() {
1157
+ this._eatSemiOrEOL();
985
1158
  if (this._expect(TokenType.eof)) {
986
1159
  return [];
987
1160
  }
988
1161
  const results = [this._statement()];
989
- while ((this.currentToken.type === TokenType.eol ||
990
- this.currentToken.type === TokenType.semi)) {
1162
+ while (true) {
991
1163
  this._eatSemiOrEOL();
992
1164
  if (this.currentToken.type === TokenType.eof) {
993
1165
  this._eat(TokenType.eof);
994
1166
  break;
995
1167
  }
996
1168
  results.push(this._statement());
997
- if (this.currentToken.type !== TokenType.eol &&
998
- this.currentToken.type !== TokenType.semi &&
999
- this.currentToken.type !== TokenType.eof) {
1000
- error(this.currentToken);
1001
- }
1169
+ // if (this.currentToken!.type !== TokenType.eol &&
1170
+ // this.currentToken!.type !== TokenType.semi &&
1171
+ // this.currentToken!.type !== TokenType.eof) {
1172
+ // error(this.currentToken!);
1173
+ // }
1002
1174
  }
1003
1175
  return results;
1004
1176
  }
1005
1177
  _root() {
1006
1178
  const source = this.lexer.source;
1007
1179
  const name = "<module>";
1008
- const list = this._statements();
1180
+ const list = this._definition();
1009
1181
  return new RootAST(list, name, source);
1010
1182
  }
1011
1183
  parse() {
@@ -1025,6 +1197,8 @@ Parser._binopPrecdences = {
1025
1197
  [TokenType.div]: 40,
1026
1198
  [TokenType.mod]: 40,
1027
1199
  };
1200
+ class BreakBranch {
1201
+ }
1028
1202
  // AST Wallker
1029
1203
  class ANodeVisitor {
1030
1204
  constructor() {
@@ -1048,6 +1222,7 @@ class AsyncNodeVisitor extends ANodeVisitor {
1048
1222
  }
1049
1223
  class NodeVisitor extends ANodeVisitor {
1050
1224
  visit(node) {
1225
+ // console.log('node::', node);
1051
1226
  const methodName = `visit${node.constructor.name}`;
1052
1227
  // const fn = Object.getPrototypeOf(this)[methodName];
1053
1228
  const fn = this._nodesVisitors[methodName];
@@ -1058,6 +1233,7 @@ class MEvento extends NodeVisitor {
1058
1233
  constructor() {
1059
1234
  super();
1060
1235
  this._memory = {};
1236
+ this.debug = false;
1061
1237
  this._functionsRegistry = {};
1062
1238
  this.registerVisitor(RootAST, this.visitRootAST);
1063
1239
  this.registerVisitor(BlockStatementAST, this.visitBlockStatementAST);
@@ -1074,8 +1250,17 @@ class MEvento extends NodeVisitor {
1074
1250
  this.registerVisitor(ObjectProperty, this.visitObjectProperty);
1075
1251
  this.registerVisitor(ObjectExpression, this.visitObjectExpression);
1076
1252
  this.registerVisitor(ArrayExpression, this.visitArrayExpression);
1253
+ this.registerVisitor(WhileLoopStatement, this.visitWhileLoopStatement);
1254
+ this.registerVisitor(ForLoopStatement, this.visitForLoopStatement);
1255
+ this.registerVisitor(ForOfStatement, this.visitForOfStatement);
1256
+ this.registerVisitor(BreakAST, this.visitBreakAST);
1077
1257
  this._functionsRegistry = Object.assign({}, MEvento._globalFunctionsRegistry);
1078
1258
  }
1259
+ log(message) {
1260
+ if (this.debug) {
1261
+ console.log(message);
1262
+ }
1263
+ }
1079
1264
  visitRootAST(node) {
1080
1265
  const list = node.body;
1081
1266
  let last;
@@ -1232,7 +1417,7 @@ class MEvento extends NodeVisitor {
1232
1417
  if (testBoolValue) {
1233
1418
  return this.visit(node.consequent);
1234
1419
  }
1235
- if (node.alternate !== null) {
1420
+ if (node.alternate) {
1236
1421
  return this.visit(node.alternate);
1237
1422
  }
1238
1423
  return null;
@@ -1280,6 +1465,85 @@ class MEvento extends NodeVisitor {
1280
1465
  const args = this.resolveArguments(node.elements);
1281
1466
  return args;
1282
1467
  }
1468
+ visitBreakAST(node) {
1469
+ return new BreakBranch();
1470
+ }
1471
+ visitWhileLoopStatement(node) {
1472
+ this.log(`WhileLoopStatement ${node.test} ${node.body}`);
1473
+ const retainer = node.retain ? [] : undefined;
1474
+ while (_boolValue(this.visit(node.test))) {
1475
+ const ret = this.visit(node.body);
1476
+ if (ret instanceof BreakBranch) {
1477
+ break;
1478
+ }
1479
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1480
+ }
1481
+ return retainer || null;
1482
+ }
1483
+ visitForLoopStatement(node) {
1484
+ const retainer = node.retain ? [] : undefined;
1485
+ const loopIdentifier = node.init.identifier;
1486
+ if (!(loopIdentifier instanceof IdentifierAST))
1487
+ throw new Error("Unexpected identifer found");
1488
+ const initialValue = this.visit(node.init.init);
1489
+ this._memory[loopIdentifier.value] = initialValue;
1490
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(initialValue);
1491
+ const test = () => {
1492
+ const ret = this.visit(node.test);
1493
+ if (isNum(ret)) {
1494
+ const tmp = this._memory[loopIdentifier.value];
1495
+ return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1496
+ }
1497
+ return _boolValue(ret);
1498
+ };
1499
+ while (test()) {
1500
+ const ret = this.visit(node.body);
1501
+ if (ret instanceof BreakBranch) {
1502
+ break;
1503
+ }
1504
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1505
+ // update
1506
+ if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1507
+ // auto handle
1508
+ const tmp = this._memory[loopIdentifier.value];
1509
+ if (!isNum(tmp))
1510
+ throw Error("Can update value");
1511
+ this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1512
+ }
1513
+ else {
1514
+ this.visit(node.update);
1515
+ }
1516
+ }
1517
+ return retainer || null;
1518
+ }
1519
+ visitForOfStatement(node) {
1520
+ const collection = this.visit(node.collection);
1521
+ if (!Array.isArray(collection)) {
1522
+ throw Error("Can iterate non array object");
1523
+ }
1524
+ const retainer = node.retain ? [] : undefined;
1525
+ for (const it of collection) {
1526
+ this._declareForIdentifier(node.identifier, it);
1527
+ const ret = this.visit(node.body);
1528
+ if (ret instanceof BreakBranch) {
1529
+ break;
1530
+ }
1531
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1532
+ }
1533
+ return retainer || null;
1534
+ }
1535
+ _declareForIdentifier(node, value) {
1536
+ if (node instanceof TupleExpression) {
1537
+ if (!Array.isArray(value)) {
1538
+ throw Error("Unable to make a tuple from non Array element");
1539
+ }
1540
+ this._memory[node.first.value] = value[0];
1541
+ this._memory[node.second.value] = value[1];
1542
+ null;
1543
+ }
1544
+ this._memory[node.value] = value;
1545
+ null;
1546
+ }
1283
1547
  resolveArguments(args) {
1284
1548
  return args.map((it) => {
1285
1549
  return this.visit(it);
@@ -1508,7 +1772,7 @@ class MEventoAsync extends MEvento {
1508
1772
  if (testBoolValue) {
1509
1773
  return yield this.visit(node.consequent);
1510
1774
  }
1511
- if (node.alternate !== null) {
1775
+ if (node.alternate) {
1512
1776
  return yield this.visit(node.alternate);
1513
1777
  }
1514
1778
  return null;
@@ -1567,6 +1831,76 @@ class MEventoAsync extends MEvento {
1567
1831
  return args;
1568
1832
  });
1569
1833
  }
1834
+ visitWhileLoopStatement(node) {
1835
+ return __awaiter(this, void 0, void 0, function* () {
1836
+ this.log(`WhileLoopStatement ${node.test} ${node.body}`);
1837
+ const retainer = node.retain ? [] : undefined;
1838
+ while (_boolValue(this.visit(node.test))) {
1839
+ const ret = yield this.visit(node.body);
1840
+ if (ret instanceof BreakBranch) {
1841
+ break;
1842
+ }
1843
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1844
+ }
1845
+ return retainer;
1846
+ });
1847
+ }
1848
+ visitForLoopStatement(node) {
1849
+ return __awaiter(this, void 0, void 0, function* () {
1850
+ const retainer = node.retain ? [] : undefined;
1851
+ const loopIdentifier = node.init.identifier;
1852
+ if (!(loopIdentifier instanceof IdentifierAST))
1853
+ throw new Error("Unexpected identifer found");
1854
+ const initialValue = this.visit(node.init.init);
1855
+ this._memory[loopIdentifier.value] = initialValue;
1856
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(initialValue);
1857
+ const test = () => {
1858
+ const ret = this.visit(node.test);
1859
+ if (isNum(ret)) {
1860
+ const tmp = this._memory[loopIdentifier.value];
1861
+ return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1862
+ }
1863
+ return _boolValue(ret);
1864
+ };
1865
+ while (test()) {
1866
+ const ret = yield this.visit(node.body);
1867
+ if (ret instanceof BreakBranch) {
1868
+ break;
1869
+ }
1870
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1871
+ // update
1872
+ if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1873
+ // auto handle
1874
+ const tmp = this._memory[loopIdentifier.value];
1875
+ if (!isNum(tmp))
1876
+ throw Error("Can update value");
1877
+ this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1878
+ }
1879
+ else {
1880
+ this.visit(node.update);
1881
+ }
1882
+ }
1883
+ return retainer;
1884
+ });
1885
+ }
1886
+ visitForOfStatement(node) {
1887
+ return __awaiter(this, void 0, void 0, function* () {
1888
+ const collection = this.visit(node.collection);
1889
+ if (!Array.isArray(collection)) {
1890
+ throw Error("Can iterate non array object");
1891
+ }
1892
+ const retainer = node.retain ? [] : undefined;
1893
+ for (const it of collection) {
1894
+ this._declareForIdentifier(node.identifier, it);
1895
+ const ret = yield this.visit(node.body);
1896
+ if (ret instanceof BreakBranch) {
1897
+ break;
1898
+ }
1899
+ retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
1900
+ }
1901
+ return retainer;
1902
+ });
1903
+ }
1570
1904
  resolveArgumentsAsync(args) {
1571
1905
  return __awaiter(this, void 0, void 0, function* () {
1572
1906
  return yield Promise.all(args.map((it) => __awaiter(this, void 0, void 0, function* () {
@@ -1594,9 +1928,6 @@ class MEventoAsync extends MEvento {
1594
1928
  });
1595
1929
  }
1596
1930
  static newInstance() {
1597
- // const lexer = Lexer(source);
1598
- // const parser = Parser(lexer);
1599
- // const module = parser.parse();
1600
1931
  return new MEventoAsync();
1601
1932
  }
1602
1933
  clone() {