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/fesm2020/mevento.mjs
CHANGED
|
@@ -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": "
|
|
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
|
|
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
|
|
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
|
-
|
|
973
|
-
this.
|
|
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 (
|
|
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
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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.
|
|
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
|
|
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
|
|
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
|