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.
- package/README.md +47 -12
- package/esm2020/lib/mevento.mjs +363 -49
- package/fesm2015/mevento.mjs +350 -31
- package/fesm2015/mevento.mjs.map +1 -1
- package/fesm2020/mevento.mjs +343 -29
- package/fesm2020/mevento.mjs.map +1 -1
- package/lib/mevento.d.ts +127 -16
- 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();
|
|
@@ -804,7 +883,7 @@ class Parser {
|
|
|
804
883
|
if (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) != TokenType.rbrace) {
|
|
805
884
|
properties.push(this._property());
|
|
806
885
|
}
|
|
807
|
-
while (((_b = this.currentToken) === null || _b === void 0 ? void 0 : _b.type)
|
|
886
|
+
while (((_b = this.currentToken) === null || _b === void 0 ? void 0 : _b.type) === TokenType.comma) {
|
|
808
887
|
this._eat(TokenType.comma);
|
|
809
888
|
properties.push(this._property());
|
|
810
889
|
}
|
|
@@ -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) {
|
|
@@ -962,8 +1043,95 @@ class Parser {
|
|
|
962
1043
|
}
|
|
963
1044
|
return new IfStatementAST(test, consequent, alternate);
|
|
964
1045
|
}
|
|
1046
|
+
_whileLoop() {
|
|
1047
|
+
const token = this.currentToken;
|
|
1048
|
+
this._eat(TokenType.WHILE_TILL);
|
|
1049
|
+
const test = this._expression();
|
|
1050
|
+
const body = this.currentToken.type === TokenType.lbrace ? this._blockStatement() : this._expression();
|
|
1051
|
+
return new WhileLoopStatement(test, body, token, this.currentToken);
|
|
1052
|
+
}
|
|
1053
|
+
_forOfIdentifier() {
|
|
1054
|
+
let node;
|
|
1055
|
+
switch (this.currentToken.type) {
|
|
1056
|
+
case TokenType.lparen: {
|
|
1057
|
+
// probable tuple
|
|
1058
|
+
this._eat(TokenType.lparen);
|
|
1059
|
+
const first = this._variable();
|
|
1060
|
+
this._eat(TokenType.comma);
|
|
1061
|
+
const second = this._variable();
|
|
1062
|
+
this._eat(TokenType.rparen);
|
|
1063
|
+
return new TupleExpression(first, second);
|
|
1064
|
+
}
|
|
1065
|
+
// TokenType.LBRACE -> objectPattern()
|
|
1066
|
+
// TokenType.LBRACKET -> arrayPattern()
|
|
1067
|
+
default:
|
|
1068
|
+
return this._variable();
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* # ForLoopStatement with step
|
|
1073
|
+
* (seginka|for) a=0 (foo|to) 10 (kay|kaj) niin 2 { # for a = 0; a<10; a+=2
|
|
1074
|
+
*
|
|
1075
|
+
* }
|
|
1076
|
+
* (seginka|for) mali kono a
|
|
1077
|
+
*/
|
|
1078
|
+
_forLoop() {
|
|
1079
|
+
const startToken = this.currentToken;
|
|
1080
|
+
this._eat(TokenType.FOR_LOOP);
|
|
1081
|
+
let forOf = [TokenType.lparen].includes(this.currentToken.type);
|
|
1082
|
+
let node;
|
|
1083
|
+
if (forOf) {
|
|
1084
|
+
node = this._forOfIdentifier();
|
|
1085
|
+
}
|
|
1086
|
+
else {
|
|
1087
|
+
const expr = this._expression();
|
|
1088
|
+
if (!(expr instanceof AssignmentExpressionAST)) {
|
|
1089
|
+
forOf = true;
|
|
1090
|
+
}
|
|
1091
|
+
node = expr;
|
|
1092
|
+
}
|
|
1093
|
+
if (!forOf && node instanceof AssignmentExpressionAST) {
|
|
1094
|
+
// normal for
|
|
1095
|
+
this._eat(TokenType.TILL);
|
|
1096
|
+
const test = this._expression();
|
|
1097
|
+
let direction;
|
|
1098
|
+
if (this.currentToken.type === TokenType.up || this.currentToken.type === TokenType.down) {
|
|
1099
|
+
const t = this.currentToken;
|
|
1100
|
+
this._eat(t.type);
|
|
1101
|
+
direction = t;
|
|
1102
|
+
}
|
|
1103
|
+
else {
|
|
1104
|
+
direction = new Token(TokenType.up, "up");
|
|
1105
|
+
}
|
|
1106
|
+
let update;
|
|
1107
|
+
if (this._expect(TokenType.with)) {
|
|
1108
|
+
this._eat(TokenType.with);
|
|
1109
|
+
const expr = this._expression();
|
|
1110
|
+
update = expr;
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
update = new LiteralAST(new Token(TokenType.numberConst, 1, this.currentToken.line, this.currentToken.col), "1");
|
|
1114
|
+
}
|
|
1115
|
+
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1116
|
+
node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken);
|
|
1117
|
+
}
|
|
1118
|
+
else if (forOf) {
|
|
1119
|
+
this._eat(TokenType.in);
|
|
1120
|
+
const collection = this._expression();
|
|
1121
|
+
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1122
|
+
node = new ForOfStatement(node, collection, body, startToken, this.currentToken);
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
error(this.currentToken);
|
|
1126
|
+
}
|
|
1127
|
+
return node;
|
|
1128
|
+
}
|
|
965
1129
|
_statement() {
|
|
1130
|
+
var _a, _b;
|
|
966
1131
|
switch (this.currentToken.type) {
|
|
1132
|
+
case TokenType.BREAK:
|
|
1133
|
+
this._eat(TokenType.BREAK);
|
|
1134
|
+
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
1135
|
case TokenType.semi:
|
|
968
1136
|
this._eatSemi();
|
|
969
1137
|
return this._statement();
|
|
@@ -972,6 +1140,10 @@ class Parser {
|
|
|
972
1140
|
return this._statement();
|
|
973
1141
|
case TokenType.IF:
|
|
974
1142
|
return this._ifStatement();
|
|
1143
|
+
case TokenType.WHILE_TILL:
|
|
1144
|
+
return this._whileLoop();
|
|
1145
|
+
case TokenType.FOR_LOOP:
|
|
1146
|
+
return this._forLoop();
|
|
975
1147
|
default:
|
|
976
1148
|
return this._statementExpression();
|
|
977
1149
|
}
|
|
@@ -980,32 +1152,31 @@ class Parser {
|
|
|
980
1152
|
var _a;
|
|
981
1153
|
return ((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === type;
|
|
982
1154
|
}
|
|
983
|
-
|
|
984
|
-
this.
|
|
1155
|
+
_definition() {
|
|
1156
|
+
this._eatSemiOrEOL();
|
|
985
1157
|
if (this._expect(TokenType.eof)) {
|
|
986
1158
|
return [];
|
|
987
1159
|
}
|
|
988
1160
|
const results = [this._statement()];
|
|
989
|
-
while (
|
|
990
|
-
this.currentToken.type === TokenType.semi)) {
|
|
1161
|
+
while (true) {
|
|
991
1162
|
this._eatSemiOrEOL();
|
|
992
1163
|
if (this.currentToken.type === TokenType.eof) {
|
|
993
1164
|
this._eat(TokenType.eof);
|
|
994
1165
|
break;
|
|
995
1166
|
}
|
|
996
1167
|
results.push(this._statement());
|
|
997
|
-
if (this.currentToken
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
}
|
|
1168
|
+
// if (this.currentToken!.type !== TokenType.eol &&
|
|
1169
|
+
// this.currentToken!.type !== TokenType.semi &&
|
|
1170
|
+
// this.currentToken!.type !== TokenType.eof) {
|
|
1171
|
+
// error(this.currentToken!);
|
|
1172
|
+
// }
|
|
1002
1173
|
}
|
|
1003
1174
|
return results;
|
|
1004
1175
|
}
|
|
1005
1176
|
_root() {
|
|
1006
1177
|
const source = this.lexer.source;
|
|
1007
1178
|
const name = "<module>";
|
|
1008
|
-
const list = this.
|
|
1179
|
+
const list = this._definition();
|
|
1009
1180
|
return new RootAST(list, name, source);
|
|
1010
1181
|
}
|
|
1011
1182
|
parse() {
|
|
@@ -1025,6 +1196,8 @@ Parser._binopPrecdences = {
|
|
|
1025
1196
|
[TokenType.div]: 40,
|
|
1026
1197
|
[TokenType.mod]: 40,
|
|
1027
1198
|
};
|
|
1199
|
+
class BreakBranch {
|
|
1200
|
+
}
|
|
1028
1201
|
// AST Wallker
|
|
1029
1202
|
class ANodeVisitor {
|
|
1030
1203
|
constructor() {
|
|
@@ -1036,16 +1209,6 @@ class ANodeVisitor {
|
|
|
1036
1209
|
this._nodesVisitors[methodName] = visitor;
|
|
1037
1210
|
}
|
|
1038
1211
|
}
|
|
1039
|
-
class AsyncNodeVisitor extends ANodeVisitor {
|
|
1040
|
-
visit(node) {
|
|
1041
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1042
|
-
const methodName = `visit${node.constructor.name}`;
|
|
1043
|
-
// const fn = Object.getPrototypeOf(this)[methodName];
|
|
1044
|
-
const fn = this._nodesVisitors[methodName];
|
|
1045
|
-
return yield (fn === null || fn === void 0 ? void 0 : fn.call(this, node));
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
1212
|
class NodeVisitor extends ANodeVisitor {
|
|
1050
1213
|
visit(node) {
|
|
1051
1214
|
const methodName = `visit${node.constructor.name}`;
|
|
@@ -1058,6 +1221,7 @@ class MEvento extends NodeVisitor {
|
|
|
1058
1221
|
constructor() {
|
|
1059
1222
|
super();
|
|
1060
1223
|
this._memory = {};
|
|
1224
|
+
this.debug = false;
|
|
1061
1225
|
this._functionsRegistry = {};
|
|
1062
1226
|
this.registerVisitor(RootAST, this.visitRootAST);
|
|
1063
1227
|
this.registerVisitor(BlockStatementAST, this.visitBlockStatementAST);
|
|
@@ -1074,8 +1238,17 @@ class MEvento extends NodeVisitor {
|
|
|
1074
1238
|
this.registerVisitor(ObjectProperty, this.visitObjectProperty);
|
|
1075
1239
|
this.registerVisitor(ObjectExpression, this.visitObjectExpression);
|
|
1076
1240
|
this.registerVisitor(ArrayExpression, this.visitArrayExpression);
|
|
1241
|
+
this.registerVisitor(WhileLoopStatement, this.visitWhileLoopStatement);
|
|
1242
|
+
this.registerVisitor(ForLoopStatement, this.visitForLoopStatement);
|
|
1243
|
+
this.registerVisitor(ForOfStatement, this.visitForOfStatement);
|
|
1244
|
+
this.registerVisitor(BreakAST, this.visitBreakAST);
|
|
1077
1245
|
this._functionsRegistry = Object.assign({}, MEvento._globalFunctionsRegistry);
|
|
1078
1246
|
}
|
|
1247
|
+
log(message) {
|
|
1248
|
+
if (this.debug) {
|
|
1249
|
+
console.log(message);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1079
1252
|
visitRootAST(node) {
|
|
1080
1253
|
const list = node.body;
|
|
1081
1254
|
let last;
|
|
@@ -1232,7 +1405,7 @@ class MEvento extends NodeVisitor {
|
|
|
1232
1405
|
if (testBoolValue) {
|
|
1233
1406
|
return this.visit(node.consequent);
|
|
1234
1407
|
}
|
|
1235
|
-
if (node.alternate
|
|
1408
|
+
if (node.alternate) {
|
|
1236
1409
|
return this.visit(node.alternate);
|
|
1237
1410
|
}
|
|
1238
1411
|
return null;
|
|
@@ -1280,6 +1453,85 @@ class MEvento extends NodeVisitor {
|
|
|
1280
1453
|
const args = this.resolveArguments(node.elements);
|
|
1281
1454
|
return args;
|
|
1282
1455
|
}
|
|
1456
|
+
visitBreakAST(node) {
|
|
1457
|
+
return new BreakBranch();
|
|
1458
|
+
}
|
|
1459
|
+
visitWhileLoopStatement(node) {
|
|
1460
|
+
this.log(`WhileLoopStatement ${node.test} ${node.body}`);
|
|
1461
|
+
const retainer = node.retain ? [] : undefined;
|
|
1462
|
+
while (_boolValue(this.visit(node.test))) {
|
|
1463
|
+
const ret = this.visit(node.body);
|
|
1464
|
+
if (ret instanceof BreakBranch) {
|
|
1465
|
+
break;
|
|
1466
|
+
}
|
|
1467
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1468
|
+
}
|
|
1469
|
+
return retainer || null;
|
|
1470
|
+
}
|
|
1471
|
+
visitForLoopStatement(node) {
|
|
1472
|
+
const retainer = node.retain ? [] : undefined;
|
|
1473
|
+
const loopIdentifier = node.init.identifier;
|
|
1474
|
+
if (!(loopIdentifier instanceof IdentifierAST))
|
|
1475
|
+
throw new Error("Unexpected identifer found");
|
|
1476
|
+
const initialValue = this.visit(node.init.init);
|
|
1477
|
+
this._memory[loopIdentifier.value] = initialValue;
|
|
1478
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(initialValue);
|
|
1479
|
+
const test = () => {
|
|
1480
|
+
const ret = this.visit(node.test);
|
|
1481
|
+
if (isNum(ret)) {
|
|
1482
|
+
const tmp = this._memory[loopIdentifier.value];
|
|
1483
|
+
return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
|
|
1484
|
+
}
|
|
1485
|
+
return _boolValue(ret);
|
|
1486
|
+
};
|
|
1487
|
+
while (test()) {
|
|
1488
|
+
const ret = this.visit(node.body);
|
|
1489
|
+
if (ret instanceof BreakBranch) {
|
|
1490
|
+
break;
|
|
1491
|
+
}
|
|
1492
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1493
|
+
// update
|
|
1494
|
+
if (node.update instanceof LiteralAST && isNum(node.update.value)) {
|
|
1495
|
+
// auto handle
|
|
1496
|
+
const tmp = this._memory[loopIdentifier.value];
|
|
1497
|
+
if (!isNum(tmp))
|
|
1498
|
+
throw Error("Can update value");
|
|
1499
|
+
this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
|
|
1500
|
+
}
|
|
1501
|
+
else {
|
|
1502
|
+
this.visit(node.update);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
return retainer || null;
|
|
1506
|
+
}
|
|
1507
|
+
visitForOfStatement(node) {
|
|
1508
|
+
const collection = this.visit(node.collection);
|
|
1509
|
+
if (!Array.isArray(collection)) {
|
|
1510
|
+
throw Error("Can iterate non array object");
|
|
1511
|
+
}
|
|
1512
|
+
const retainer = node.retain ? [] : undefined;
|
|
1513
|
+
for (const it of collection) {
|
|
1514
|
+
this._declareForIdentifier(node.identifier, it);
|
|
1515
|
+
const ret = this.visit(node.body);
|
|
1516
|
+
if (ret instanceof BreakBranch) {
|
|
1517
|
+
break;
|
|
1518
|
+
}
|
|
1519
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1520
|
+
}
|
|
1521
|
+
return retainer || null;
|
|
1522
|
+
}
|
|
1523
|
+
_declareForIdentifier(node, value) {
|
|
1524
|
+
if (node instanceof TupleExpression) {
|
|
1525
|
+
if (!Array.isArray(value)) {
|
|
1526
|
+
throw Error("Unable to make a tuple from non Array element");
|
|
1527
|
+
}
|
|
1528
|
+
this._memory[node.first.value] = value[0];
|
|
1529
|
+
this._memory[node.second.value] = value[1];
|
|
1530
|
+
null;
|
|
1531
|
+
}
|
|
1532
|
+
this._memory[node.value] = value;
|
|
1533
|
+
null;
|
|
1534
|
+
}
|
|
1283
1535
|
resolveArguments(args) {
|
|
1284
1536
|
return args.map((it) => {
|
|
1285
1537
|
return this.visit(it);
|
|
@@ -1508,7 +1760,7 @@ class MEventoAsync extends MEvento {
|
|
|
1508
1760
|
if (testBoolValue) {
|
|
1509
1761
|
return yield this.visit(node.consequent);
|
|
1510
1762
|
}
|
|
1511
|
-
if (node.alternate
|
|
1763
|
+
if (node.alternate) {
|
|
1512
1764
|
return yield this.visit(node.alternate);
|
|
1513
1765
|
}
|
|
1514
1766
|
return null;
|
|
@@ -1567,6 +1819,76 @@ class MEventoAsync extends MEvento {
|
|
|
1567
1819
|
return args;
|
|
1568
1820
|
});
|
|
1569
1821
|
}
|
|
1822
|
+
visitWhileLoopStatement(node) {
|
|
1823
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1824
|
+
this.log(`WhileLoopStatement ${node.test} ${node.body}`);
|
|
1825
|
+
const retainer = node.retain ? [] : undefined;
|
|
1826
|
+
while (_boolValue(this.visit(node.test))) {
|
|
1827
|
+
const ret = yield this.visit(node.body);
|
|
1828
|
+
if (ret instanceof BreakBranch) {
|
|
1829
|
+
break;
|
|
1830
|
+
}
|
|
1831
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1832
|
+
}
|
|
1833
|
+
return retainer;
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
visitForLoopStatement(node) {
|
|
1837
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1838
|
+
const retainer = node.retain ? [] : undefined;
|
|
1839
|
+
const loopIdentifier = node.init.identifier;
|
|
1840
|
+
if (!(loopIdentifier instanceof IdentifierAST))
|
|
1841
|
+
throw new Error("Unexpected identifer found");
|
|
1842
|
+
const initialValue = this.visit(node.init.init);
|
|
1843
|
+
this._memory[loopIdentifier.value] = initialValue;
|
|
1844
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(initialValue);
|
|
1845
|
+
const test = () => {
|
|
1846
|
+
const ret = this.visit(node.test);
|
|
1847
|
+
if (isNum(ret)) {
|
|
1848
|
+
const tmp = this._memory[loopIdentifier.value];
|
|
1849
|
+
return node.direction.type === TokenType.up ? ret >= tmp : ret <= tmp;
|
|
1850
|
+
}
|
|
1851
|
+
return _boolValue(ret);
|
|
1852
|
+
};
|
|
1853
|
+
while (test()) {
|
|
1854
|
+
const ret = yield this.visit(node.body);
|
|
1855
|
+
if (ret instanceof BreakBranch) {
|
|
1856
|
+
break;
|
|
1857
|
+
}
|
|
1858
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1859
|
+
// update
|
|
1860
|
+
if (node.update instanceof LiteralAST && isNum(node.update.value)) {
|
|
1861
|
+
// auto handle
|
|
1862
|
+
const tmp = this._memory[loopIdentifier.value];
|
|
1863
|
+
if (!isNum(tmp))
|
|
1864
|
+
throw Error("Can update value");
|
|
1865
|
+
this._memory[loopIdentifier.value] = node.direction.type === TokenType.up ? tmp + node.update.value : tmp - node.update.value;
|
|
1866
|
+
}
|
|
1867
|
+
else {
|
|
1868
|
+
this.visit(node.update);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
return retainer;
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
visitForOfStatement(node) {
|
|
1875
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1876
|
+
const collection = this.visit(node.collection);
|
|
1877
|
+
if (!Array.isArray(collection)) {
|
|
1878
|
+
throw Error("Can iterate non array object");
|
|
1879
|
+
}
|
|
1880
|
+
const retainer = node.retain ? [] : undefined;
|
|
1881
|
+
for (const it of collection) {
|
|
1882
|
+
this._declareForIdentifier(node.identifier, it);
|
|
1883
|
+
const ret = yield this.visit(node.body);
|
|
1884
|
+
if (ret instanceof BreakBranch) {
|
|
1885
|
+
break;
|
|
1886
|
+
}
|
|
1887
|
+
retainer === null || retainer === void 0 ? void 0 : retainer.push(ret);
|
|
1888
|
+
}
|
|
1889
|
+
return retainer;
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1570
1892
|
resolveArgumentsAsync(args) {
|
|
1571
1893
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1572
1894
|
return yield Promise.all(args.map((it) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1594,9 +1916,6 @@ class MEventoAsync extends MEvento {
|
|
|
1594
1916
|
});
|
|
1595
1917
|
}
|
|
1596
1918
|
static newInstance() {
|
|
1597
|
-
// const lexer = Lexer(source);
|
|
1598
|
-
// const parser = Parser(lexer);
|
|
1599
|
-
// const module = parser.parse();
|
|
1600
1919
|
return new MEventoAsync();
|
|
1601
1920
|
}
|
|
1602
1921
|
clone() {
|
|
@@ -1615,5 +1934,5 @@ class MEventoAsync extends MEvento {
|
|
|
1615
1934
|
* Generated bundle index. Do not edit.
|
|
1616
1935
|
*/
|
|
1617
1936
|
|
|
1618
|
-
export { MEvento, MEventoAsync };
|
|
1937
|
+
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 };
|
|
1619
1938
|
//# sourceMappingURL=mevento.mjs.map
|