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.
- package/README.md +47 -12
- package/esm2020/lib/mevento.mjs +345 -21
- package/fesm2015/mevento.mjs +351 -20
- package/fesm2015/mevento.mjs.map +1 -1
- package/fesm2020/mevento.mjs +344 -20
- package/fesm2020/mevento.mjs.map +1 -1
- package/lib/mevento.d.ts +37 -0
- package/package.json +1 -1
package/fesm2015/mevento.mjs
CHANGED
|
@@ -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": "
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
984
|
-
this.
|
|
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 (
|
|
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
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
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.
|
|
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
|
|
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
|
|
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() {
|