mevento 1.4.0 → 1.9.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.
@@ -77,6 +77,7 @@ TokenType.with = 39;
77
77
  TokenType.in = 40;
78
78
  TokenType.TILL = 41;
79
79
  TokenType.BREAK = 42;
80
+ TokenType.CONTINUE = 43;
80
81
  class Token {
81
82
  constructor(type, value, line = 1, col = 1) {
82
83
  this.type = type;
@@ -151,7 +152,7 @@ class Lexer {
151
152
  error(token);
152
153
  }
153
154
  const lang = idToken.value.toString();
154
- this._language = Lexer.languages.find((element) => element.lang === lang) || Lexer._defaultLanguage;
155
+ this._language = Lexer.languages.find((element) => element.lang === lang) ?? Lexer._defaultLanguage;
155
156
  token = this.nextToken();
156
157
  if (token.type !== TokenType.great) {
157
158
  error(token);
@@ -225,9 +226,9 @@ class Lexer {
225
226
  this._advance();
226
227
  }
227
228
  const translatedId = this._language
228
- ? (this._language.keywords[ret]) || ret
229
+ ? (this._language.keywords[ret]) ?? ret
229
230
  : ret;
230
- return Lexer.RESERVED[translatedId] || new Token(TokenType.id, ret, line, lastC);
231
+ return Lexer.RESERVED[translatedId] ?? new Token(TokenType.id, ret, line, lastC);
231
232
  }
232
233
  _isLineEnd(c) {
233
234
  return c === 10 ||
@@ -488,6 +489,7 @@ Lexer._defaultLanguage = new LexerDictionary("en", {
488
489
  "till": "till",
489
490
  "in": "in",
490
491
  "break": "break",
492
+ "continue": "continue",
491
493
  });
492
494
  Lexer.languages = [
493
495
  Lexer._defaultLanguage,
@@ -500,11 +502,12 @@ Lexer.languages = [
500
502
  "tanque": "while",
501
503
  "pour": "for",
502
504
  "avec": "with",
503
- "mon": "up",
505
+ "mont": "up",
504
506
  "desc": "down",
505
507
  "jusqua": "till",
506
508
  "dans": "in",
507
509
  "couper": "break",
510
+ "continuer": "continue",
508
511
  }),
509
512
  new LexerDictionary("bm", {
510
513
  "nii": "if",
@@ -520,6 +523,7 @@ Lexer.languages = [
520
523
  "kata": "till",
521
524
  "kono": "in",
522
525
  "tike": "break",
526
+ "ipan": "continue",
523
527
  }),
524
528
  ];
525
529
  Lexer.RESERVED = {
@@ -536,6 +540,7 @@ Lexer.RESERVED = {
536
540
  "till": Token.from(TokenType.TILL, "till"),
537
541
  "in": Token.from(TokenType.in, "in"),
538
542
  "break": Token.from(TokenType.BREAK, "break"),
543
+ "continue": Token.from(TokenType.CONTINUE, "continue"),
539
544
  };
540
545
  /**
541
546
  * Parser
@@ -742,6 +747,11 @@ class BreakAST extends AST {
742
747
  super(line, col);
743
748
  }
744
749
  }
750
+ class ContinueAST extends AST {
751
+ constructor(line, col) {
752
+ super(line, col);
753
+ }
754
+ }
745
755
  class Parser {
746
756
  constructor(lexer) {
747
757
  this.currentToken = lexer.nextToken();
@@ -976,8 +986,7 @@ class Parser {
976
986
  }
977
987
  // const body = _statements();
978
988
  const body = [this._statement()];
979
- while (this.currentToken.type === TokenType.eol ||
980
- this.currentToken.type === TokenType.semi) {
989
+ while (true) {
981
990
  this._eatSemiOrEOL();
982
991
  if (this.currentToken.type === TokenType.rbrace || this.currentToken.type === TokenType.eof) {
983
992
  // _eat(this.currentToken!.type);
@@ -1041,7 +1050,6 @@ class Parser {
1041
1050
  return new WhileLoopStatement(test, body, token, this.currentToken);
1042
1051
  }
1043
1052
  _forOfIdentifier() {
1044
- let node;
1045
1053
  switch (this.currentToken.type) {
1046
1054
  case TokenType.lparen: {
1047
1055
  // probable tuple
@@ -1121,6 +1129,9 @@ class Parser {
1121
1129
  case TokenType.BREAK:
1122
1130
  this._eat(TokenType.BREAK);
1123
1131
  return new BreakAST(this.currentToken?.line, this.currentToken?.col);
1132
+ case TokenType.CONTINUE:
1133
+ this._eat(TokenType.CONTINUE);
1134
+ return new ContinueAST(this.currentToken?.line, this.currentToken?.col);
1124
1135
  case TokenType.semi:
1125
1136
  this._eatSemi();
1126
1137
  return this._statement();
@@ -1152,7 +1163,12 @@ class Parser {
1152
1163
  this._eat(TokenType.eof);
1153
1164
  break;
1154
1165
  }
1155
- results.push(this._statement());
1166
+ if (this.currentToken.type === TokenType.lbrace) {
1167
+ results.push(this._blockStatement());
1168
+ }
1169
+ else {
1170
+ results.push(this._statement());
1171
+ }
1156
1172
  // if (this.currentToken!.type !== TokenType.eol &&
1157
1173
  // this.currentToken!.type !== TokenType.semi &&
1158
1174
  // this.currentToken!.type !== TokenType.eof) {
@@ -1184,7 +1200,11 @@ Parser._binopPrecdences = {
1184
1200
  [TokenType.div]: 40,
1185
1201
  [TokenType.mod]: 40,
1186
1202
  };
1187
- class BreakBranch {
1203
+ class LoopControl {
1204
+ }
1205
+ class BreakBranch extends LoopControl {
1206
+ }
1207
+ class ContinueBranch extends LoopControl {
1188
1208
  }
1189
1209
  // AST Wallker
1190
1210
  class ANodeVisitor {
@@ -1219,6 +1239,7 @@ class NodeVisitor extends ANodeVisitor {
1219
1239
  this.registerVisitor(ForLoopStatement, this.visitForLoopStatement);
1220
1240
  this.registerVisitor(ForOfStatement, this.visitForOfStatement);
1221
1241
  this.registerVisitor(BreakAST, this.visitBreakAST);
1242
+ this.registerVisitor(ContinueAST, this.visitContinueAST);
1222
1243
  }
1223
1244
  visit(node) {
1224
1245
  const methodName = `visit${node.constructor.name}`;
@@ -1236,14 +1257,58 @@ class NodeVisitor extends ANodeVisitor {
1236
1257
  else { }
1237
1258
  }
1238
1259
  }
1260
+ class MEventScope {
1261
+ constructor(name, memory, parent) {
1262
+ this.memory = {};
1263
+ this.name = name;
1264
+ this.memory = memory;
1265
+ this.parent = parent;
1266
+ }
1267
+ resolve(key) {
1268
+ return Object.keys(this.memory).includes(key) ? this.memory[key] : (this.parent ? this.parent.resolve(key) : null);
1269
+ }
1270
+ change(key, value, declare = true) {
1271
+ if (Object.keys(this.memory).includes(key)) {
1272
+ // change here
1273
+ this.memory[key] = value;
1274
+ return true;
1275
+ }
1276
+ if (this.parent && this.parent.change(key, value, false)) {
1277
+ return true;
1278
+ }
1279
+ if (!declare) {
1280
+ return false;
1281
+ }
1282
+ this.memory[key] = value;
1283
+ return true;
1284
+ }
1285
+ }
1239
1286
  class MEvento extends NodeVisitor {
1240
1287
  constructor() {
1241
1288
  super();
1242
- this._memory = {};
1289
+ this.rootScope = new MEventScope("Program", {});
1290
+ this.currentScrope = this.rootScope;
1243
1291
  this.debug = false;
1244
1292
  this._functionsRegistry = {};
1245
1293
  this._functionsRegistry = { ...MEvento._globalFunctionsRegistry };
1246
1294
  }
1295
+ resolve(name) {
1296
+ return this.currentScrope?.resolve(name) ?? null;
1297
+ }
1298
+ changeVariable(name, value) {
1299
+ if (this.currentScrope?.change(name, value)) {
1300
+ return value;
1301
+ }
1302
+ else
1303
+ return null;
1304
+ }
1305
+ pushScope(name) {
1306
+ const scope = new MEventScope(name, {}, this.currentScrope);
1307
+ this.currentScrope = scope;
1308
+ }
1309
+ popScope() {
1310
+ this.currentScrope = this.currentScrope?.parent;
1311
+ }
1247
1312
  log(message) {
1248
1313
  if (this.debug) {
1249
1314
  console.log(message);
@@ -1260,14 +1325,19 @@ class MEvento extends NodeVisitor {
1260
1325
  visitBlockStatementAST(node) {
1261
1326
  const list = node.body;
1262
1327
  let last;
1328
+ this.pushScope("Block");
1263
1329
  for (const n of list) {
1264
1330
  last = this.visit(n);
1331
+ if (last instanceof LoopControl) {
1332
+ break;
1333
+ }
1265
1334
  }
1335
+ this.popScope();
1266
1336
  return last;
1267
1337
  }
1268
1338
  visitIdentifierAST(node) {
1269
1339
  const id = node.value;
1270
- return this._memory[id];
1340
+ return this.currentScrope?.resolve(id) ?? null;
1271
1341
  }
1272
1342
  visitLiteralAST(node) {
1273
1343
  const value = node.value;
@@ -1285,7 +1355,7 @@ class MEvento extends NodeVisitor {
1285
1355
  }
1286
1356
  else if (id instanceof IdentifierAST) {
1287
1357
  value = this.visit(init);
1288
- this._memory[id.value] = value;
1358
+ this.changeVariable(id.value, value);
1289
1359
  }
1290
1360
  return value;
1291
1361
  }
@@ -1455,45 +1525,59 @@ class MEvento extends NodeVisitor {
1455
1525
  if (ret instanceof BreakBranch) {
1456
1526
  break;
1457
1527
  }
1528
+ if (ret instanceof ContinueBranch) {
1529
+ continue;
1530
+ }
1458
1531
  retainer?.push(ret);
1459
1532
  }
1460
- return retainer || null;
1533
+ return retainer ?? null;
1461
1534
  }
1462
1535
  visitForLoopStatement(node) {
1463
1536
  const retainer = node.retain ? [] : undefined;
1464
1537
  const loopIdentifier = node.init.identifier;
1465
1538
  if (!(loopIdentifier instanceof IdentifierAST))
1466
1539
  throw new Error("Unexpected identifer found");
1540
+ this.pushScope("ForLoopStatement");
1467
1541
  const initialValue = this.visit(node.init.init);
1468
- this._memory[loopIdentifier.value] = initialValue;
1542
+ this.changeVariable(loopIdentifier.value, initialValue);
1469
1543
  retainer?.push(initialValue);
1470
1544
  const test = () => {
1471
1545
  const ret = this.visit(node.test);
1472
1546
  if (isNum(ret)) {
1473
- const tmp = this._memory[loopIdentifier.value];
1547
+ const tmp = this.resolve(loopIdentifier.value);
1474
1548
  return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1475
1549
  }
1476
1550
  return _boolValue(ret);
1477
1551
  };
1552
+ const update = () => {
1553
+ const updateValue = this.visit(node.update);
1554
+ if (isNum(updateValue)) {
1555
+ // auto handle
1556
+ const tmp = this.resolve(loopIdentifier.value);
1557
+ if (!isNum(tmp))
1558
+ throw Error("Cant update value");
1559
+ this.changeVariable(loopIdentifier.value, node.direction.type === TokenType.up ? tmp + updateValue : tmp - updateValue);
1560
+ // console.log('Update loop from ' + tmp + ' to ' + this.resolve(loopIdentifier.value))
1561
+ }
1562
+ else {
1563
+ throw Error("Update value cant be non number");
1564
+ }
1565
+ };
1478
1566
  while (test()) {
1479
1567
  const ret = this.visit(node.body);
1480
1568
  if (ret instanceof BreakBranch) {
1481
1569
  break;
1482
1570
  }
1571
+ if (ret instanceof ContinueBranch) {
1572
+ update();
1573
+ continue;
1574
+ }
1483
1575
  retainer?.push(ret);
1484
1576
  // update
1485
- if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1486
- // auto handle
1487
- const tmp = this._memory[loopIdentifier.value];
1488
- if (!isNum(tmp))
1489
- throw Error("Can update value");
1490
- this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1491
- }
1492
- else {
1493
- this.visit(node.update);
1494
- }
1577
+ update();
1495
1578
  }
1496
- return retainer || null;
1579
+ this.popScope();
1580
+ return retainer ?? null;
1497
1581
  }
1498
1582
  visitForOfStatement(node) {
1499
1583
  const collection = this.visit(node.collection);
@@ -1501,27 +1585,33 @@ class MEvento extends NodeVisitor {
1501
1585
  throw Error("Can iterate non array object");
1502
1586
  }
1503
1587
  const retainer = node.retain ? [] : undefined;
1588
+ this.pushScope("ForOfStatement");
1504
1589
  for (const it of collection) {
1505
1590
  this._declareForIdentifier(node.identifier, it);
1506
1591
  const ret = this.visit(node.body);
1507
1592
  if (ret instanceof BreakBranch) {
1508
1593
  break;
1509
1594
  }
1595
+ if (ret instanceof ContinueBranch) {
1596
+ continue;
1597
+ }
1510
1598
  retainer?.push(ret);
1511
1599
  }
1512
- return retainer || null;
1600
+ this.popScope();
1601
+ return retainer ?? null;
1602
+ }
1603
+ visitContinueAST(node) {
1604
+ return new ContinueBranch();
1513
1605
  }
1514
1606
  _declareForIdentifier(node, value) {
1515
1607
  if (node instanceof TupleExpression) {
1516
1608
  if (!Array.isArray(value)) {
1517
1609
  throw Error("Unable to make a tuple from non Array element");
1518
1610
  }
1519
- this._memory[node.first.value] = value[0];
1520
- this._memory[node.second.value] = value[1];
1521
- null;
1611
+ this.changeVariable(node.first.value, value[0]);
1612
+ this.changeVariable(node.second.value, value[1]);
1522
1613
  }
1523
- this._memory[node.value] = value;
1524
- null;
1614
+ this.changeVariable(node.value, value);
1525
1615
  }
1526
1616
  resolveArguments(args) {
1527
1617
  return args.map((it) => {
@@ -1570,12 +1660,12 @@ class MEvento extends NodeVisitor {
1570
1660
  clone() {
1571
1661
  var ret = new MEvento();
1572
1662
  ret._functionsRegistry = { ...this._functionsRegistry };
1573
- ret._memory = { ...this._memory };
1663
+ ret.rootScope.memory = { ...this.rootScope.memory };
1574
1664
  return ret;
1575
1665
  }
1576
1666
  newAsyncInstance() {
1577
1667
  const asyncIns = MEventoAsync.newInstance();
1578
- asyncIns._memory = this._memory;
1668
+ asyncIns.rootScope.memory = this.rootScope.memory;
1579
1669
  /// ????
1580
1670
  asyncIns._functionsRegistry = this._functionsRegistry;
1581
1671
  return asyncIns;
@@ -1599,14 +1689,19 @@ class MEventoAsync extends MEvento {
1599
1689
  async visitBlockStatementAST(node) {
1600
1690
  const list = node.body;
1601
1691
  let last;
1692
+ this.pushScope("Block");
1602
1693
  for (const n of list) {
1603
1694
  last = await this.visit(n);
1695
+ if (last instanceof LoopControl) {
1696
+ break;
1697
+ }
1604
1698
  }
1699
+ this.popScope();
1605
1700
  return last;
1606
1701
  }
1607
1702
  async visitIdentifierAST(node) {
1608
1703
  const id = node.value;
1609
- return this._memory[id];
1704
+ return this.resolve(id);
1610
1705
  }
1611
1706
  async visitLiteralAST(node) {
1612
1707
  const value = node.value;
@@ -1624,7 +1719,7 @@ class MEventoAsync extends MEvento {
1624
1719
  }
1625
1720
  else if (id instanceof IdentifierAST) {
1626
1721
  value = await this.visit(init);
1627
- this._memory[id.value] = value;
1722
+ this.changeVariable(id.value, value);
1628
1723
  }
1629
1724
  return value;
1630
1725
  }
@@ -1714,6 +1809,9 @@ class MEventoAsync extends MEvento {
1714
1809
  const arg = node.argument;
1715
1810
  const op = node.operation;
1716
1811
  const argValue = await this.visit(arg);
1812
+ if (op.type === TokenType.not) {
1813
+ return _boolValue(argValue) === false;
1814
+ }
1717
1815
  if (isNum(argValue)) {
1718
1816
  throw new Error(`Operation ${op.value} not allowed no num value`);
1719
1817
  }
@@ -1783,11 +1881,14 @@ class MEventoAsync extends MEvento {
1783
1881
  async visitWhileLoopStatement(node) {
1784
1882
  this.log(`WhileLoopStatement ${node.test} ${node.body}`);
1785
1883
  const retainer = node.retain ? [] : undefined;
1786
- while (_boolValue(this.visit(node.test))) {
1884
+ while (_boolValue(await this.visit(node.test))) {
1787
1885
  const ret = await this.visit(node.body);
1788
1886
  if (ret instanceof BreakBranch) {
1789
1887
  break;
1790
1888
  }
1889
+ if (ret instanceof ContinueBranch) {
1890
+ continue;
1891
+ }
1791
1892
  retainer?.push(ret);
1792
1893
  }
1793
1894
  return retainer;
@@ -1797,51 +1898,66 @@ class MEventoAsync extends MEvento {
1797
1898
  const loopIdentifier = node.init.identifier;
1798
1899
  if (!(loopIdentifier instanceof IdentifierAST))
1799
1900
  throw new Error("Unexpected identifer found");
1800
- const initialValue = this.visit(node.init.init);
1801
- this._memory[loopIdentifier.value] = initialValue;
1901
+ this.pushScope("ForLoopStatement");
1902
+ const initialValue = await this.visit(node.init.init);
1903
+ this.changeVariable(loopIdentifier.value, initialValue);
1802
1904
  retainer?.push(initialValue);
1803
- const test = () => {
1804
- const ret = this.visit(node.test);
1905
+ const test = async () => {
1906
+ const ret = await this.visit(node.test);
1805
1907
  if (isNum(ret)) {
1806
- const tmp = this._memory[loopIdentifier.value];
1908
+ const tmp = this.resolve(loopIdentifier.value);
1807
1909
  return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
1808
1910
  }
1809
1911
  return _boolValue(ret);
1810
1912
  };
1811
- while (test()) {
1913
+ const update = async () => {
1914
+ const updateValue = await this.visit(node.update);
1915
+ if (isNum(updateValue)) {
1916
+ // auto handle
1917
+ const tmp = this.resolve(loopIdentifier.value);
1918
+ if (!isNum(tmp))
1919
+ throw Error("Cant update value");
1920
+ this.changeVariable(loopIdentifier.value, node.direction.type === TokenType.up ? tmp + updateValue : tmp - updateValue);
1921
+ }
1922
+ else {
1923
+ throw Error("Update value cant be non number");
1924
+ }
1925
+ };
1926
+ while (await test()) {
1812
1927
  const ret = await this.visit(node.body);
1813
1928
  if (ret instanceof BreakBranch) {
1814
1929
  break;
1815
1930
  }
1931
+ if (ret instanceof ContinueBranch) {
1932
+ await update();
1933
+ continue;
1934
+ }
1816
1935
  retainer?.push(ret);
1817
1936
  // update
1818
- if (node.update instanceof LiteralAST && isNum(node.update.value)) {
1819
- // auto handle
1820
- const tmp = this._memory[loopIdentifier.value];
1821
- if (!isNum(tmp))
1822
- throw Error("Can update value");
1823
- this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
1824
- }
1825
- else {
1826
- this.visit(node.update);
1827
- }
1937
+ await update();
1828
1938
  }
1829
- return retainer;
1939
+ this.popScope();
1940
+ return retainer ?? null;
1830
1941
  }
1831
1942
  async visitForOfStatement(node) {
1832
- const collection = this.visit(node.collection);
1943
+ const collection = await this.visit(node.collection);
1833
1944
  if (!Array.isArray(collection)) {
1834
1945
  throw Error("Can iterate non array object");
1835
1946
  }
1836
1947
  const retainer = node.retain ? [] : undefined;
1948
+ this.pushScope("ForOfStatement");
1837
1949
  for (const it of collection) {
1838
1950
  this._declareForIdentifier(node.identifier, it);
1839
1951
  const ret = await this.visit(node.body);
1840
1952
  if (ret instanceof BreakBranch) {
1841
1953
  break;
1842
1954
  }
1955
+ if (ret instanceof ContinueBranch) {
1956
+ continue;
1957
+ }
1843
1958
  retainer?.push(ret);
1844
1959
  }
1960
+ this.popScope();
1845
1961
  return retainer;
1846
1962
  }
1847
1963
  async resolveArgumentsAsync(args) {
@@ -1870,7 +1986,7 @@ class MEventoAsync extends MEvento {
1870
1986
  clone() {
1871
1987
  var ret = new MEventoAsync();
1872
1988
  ret._functionsRegistry = { ...this._functionsRegistry };
1873
- ret._memory = { ...this._memory };
1989
+ ret.rootScope.memory = { ...this.rootScope.memory };
1874
1990
  return ret;
1875
1991
  }
1876
1992
  }
@@ -1883,5 +1999,5 @@ class MEventoAsync extends MEvento {
1883
1999
  * Generated bundle index. Do not edit.
1884
2000
  */
1885
2001
 
1886
- 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 };
2002
+ export { AST, ArrayExpression, AssignmentExpressionAST, BinaryExpressionAST, BlockStatementAST, BreakAST, BreakBranch, CallExpressionAST, ContinueAST, ContinueBranch, ExpressionStatementAST, ForLoopStatement, ForOfStatement, IdentifierAST, IfStatementAST, IndexAccessorAST, LexerDictionary, LiteralAST, LogicalExpressionAST, LoopControl, MEventScope, MEvento, MEventoAsync, NodeVisitor, ObjectExpression, ObjectProperty, RootAST, Token, TokenType, TupleExpression, UnaryExpressionAST, WhileLoopStatement };
1887
2003
  //# sourceMappingURL=mevento.mjs.map