mevento 2.0.6 → 2.1.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/esm2020/lib/mevento.mjs +132 -33
- package/fesm2015/mevento.mjs +133 -33
- package/fesm2015/mevento.mjs.map +1 -1
- package/fesm2020/mevento.mjs +131 -32
- package/fesm2020/mevento.mjs.map +1 -1
- package/package.json +1 -1
package/fesm2020/mevento.mjs
CHANGED
|
@@ -178,6 +178,15 @@ class Lexer {
|
|
|
178
178
|
this._currentChar = this._source[this._position].charCodeAt(0);
|
|
179
179
|
this._col++;
|
|
180
180
|
}
|
|
181
|
+
_jump(n) {
|
|
182
|
+
this._position += n;
|
|
183
|
+
if (this._position >= this._source.length) {
|
|
184
|
+
this._currentChar = -1;
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this._currentChar = this._source[this._position].charCodeAt(0);
|
|
188
|
+
this._col += n;
|
|
189
|
+
}
|
|
181
190
|
_pick() {
|
|
182
191
|
if (this._position + 1 >= this._source.length) {
|
|
183
192
|
return -1;
|
|
@@ -311,28 +320,62 @@ class Lexer {
|
|
|
311
320
|
const lastL = this._line;
|
|
312
321
|
while (this._currentChar !== -1) {
|
|
313
322
|
const next = String.fromCharCode(this._pick());
|
|
314
|
-
if (this._currentChar
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
'0'
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
'
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
'
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
'
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
323
|
+
if (this._currentChar == Chars.backslash) {
|
|
324
|
+
switch (next) {
|
|
325
|
+
case '\\':
|
|
326
|
+
ret += "\\";
|
|
327
|
+
break;
|
|
328
|
+
case '0':
|
|
329
|
+
ret += "\0";
|
|
330
|
+
break;
|
|
331
|
+
case 'a':
|
|
332
|
+
ret += "\a";
|
|
333
|
+
break;
|
|
334
|
+
case 'b':
|
|
335
|
+
ret += "\b";
|
|
336
|
+
break;
|
|
337
|
+
case 'f':
|
|
338
|
+
ret += "\f";
|
|
339
|
+
break;
|
|
340
|
+
case 'n':
|
|
341
|
+
ret += "\n";
|
|
342
|
+
break;
|
|
343
|
+
case 'r':
|
|
344
|
+
ret += "\r";
|
|
345
|
+
break;
|
|
346
|
+
case 't':
|
|
347
|
+
ret += "\t";
|
|
348
|
+
break;
|
|
349
|
+
case 'u':
|
|
350
|
+
ret += String.fromCharCode(Number.parseInt(this._source.substring(this._position + 2, this._position + 6), 16));
|
|
351
|
+
this._jump(4);
|
|
352
|
+
// consume 4 unicode chars
|
|
353
|
+
break;
|
|
354
|
+
case 'v':
|
|
355
|
+
ret += "\v";
|
|
356
|
+
break;
|
|
357
|
+
case 'x':
|
|
358
|
+
ret += String.fromCharCode(Number.parseInt(this._source.substring(this._position + 2, this._position + 4), 16));
|
|
359
|
+
this._jump(2);
|
|
360
|
+
break;
|
|
361
|
+
default:
|
|
362
|
+
{
|
|
363
|
+
if (String.fromCharCode(startChar) == next) {
|
|
364
|
+
ret += String.fromCharCode(startChar);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
this._advance();
|
|
368
|
+
lastChar = this._currentChar;
|
|
369
|
+
ret += String.fromCharCode(this._currentChar);
|
|
370
|
+
this._advance();
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
335
374
|
}
|
|
375
|
+
// scape char
|
|
376
|
+
this._jump(2);
|
|
377
|
+
lastChar = this._currentChar;
|
|
378
|
+
continue;
|
|
336
379
|
}
|
|
337
380
|
if (this._currentChar === startChar && lastChar !== Chars.backslash) {
|
|
338
381
|
// end
|
|
@@ -798,8 +841,33 @@ class ContinueAST extends AST {
|
|
|
798
841
|
super(line, col);
|
|
799
842
|
}
|
|
800
843
|
}
|
|
844
|
+
class ListQueue {
|
|
845
|
+
constructor(capacity = Infinity) {
|
|
846
|
+
this.capacity = capacity;
|
|
847
|
+
this.storage = [];
|
|
848
|
+
}
|
|
849
|
+
push(item) {
|
|
850
|
+
if (this.size() === this.capacity) {
|
|
851
|
+
throw Error("Stack has reached max capacity, you cannot add more items");
|
|
852
|
+
}
|
|
853
|
+
this.storage.push(item);
|
|
854
|
+
}
|
|
855
|
+
pop() {
|
|
856
|
+
return this.storage.pop();
|
|
857
|
+
}
|
|
858
|
+
peek() {
|
|
859
|
+
return this.storage[this.size() - 1];
|
|
860
|
+
}
|
|
861
|
+
size() {
|
|
862
|
+
return this.storage.length;
|
|
863
|
+
}
|
|
864
|
+
get isEmpty() {
|
|
865
|
+
return this.storage.length === 0;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
801
868
|
class Parser {
|
|
802
869
|
constructor(lexer) {
|
|
870
|
+
this._loopTrack = new ListQueue();
|
|
803
871
|
this.currentToken = lexer.nextToken();
|
|
804
872
|
this.lexer = lexer;
|
|
805
873
|
}
|
|
@@ -873,10 +941,32 @@ class Parser {
|
|
|
873
941
|
return this._objectExpression();
|
|
874
942
|
case TokenType.IF:
|
|
875
943
|
return this._ifStatement();
|
|
944
|
+
case TokenType.WHILE_TILL:
|
|
945
|
+
return this._whileLoop(true);
|
|
946
|
+
case TokenType.FOR_LOOP:
|
|
947
|
+
return this._forLoop(true);
|
|
948
|
+
case TokenType.BREAK:
|
|
949
|
+
return this._breakExpression();
|
|
950
|
+
case TokenType.CONTINUE:
|
|
951
|
+
return this._continueExpression();
|
|
876
952
|
default:
|
|
877
953
|
return this._variable();
|
|
878
954
|
}
|
|
879
955
|
}
|
|
956
|
+
_breakExpression() {
|
|
957
|
+
if (this._loopTrack.isEmpty) {
|
|
958
|
+
error(this.currentToken);
|
|
959
|
+
}
|
|
960
|
+
this._eat(TokenType.BREAK);
|
|
961
|
+
return new BreakAST(this.currentToken?.line, this.currentToken?.col);
|
|
962
|
+
}
|
|
963
|
+
_continueExpression() {
|
|
964
|
+
if (this._loopTrack.isEmpty) {
|
|
965
|
+
error(this.currentToken);
|
|
966
|
+
}
|
|
967
|
+
this._eat(TokenType.CONTINUE);
|
|
968
|
+
return new ContinueAST(this.currentToken?.line, this.currentToken?.col);
|
|
969
|
+
}
|
|
880
970
|
_term() {
|
|
881
971
|
let node = this._factor();
|
|
882
972
|
node = this._tryParsingFunctionCall(node);
|
|
@@ -1111,12 +1201,20 @@ class Parser {
|
|
|
1111
1201
|
}
|
|
1112
1202
|
return new IfStatementAST(test, consequent, alternate);
|
|
1113
1203
|
}
|
|
1114
|
-
|
|
1204
|
+
_pushLoop() {
|
|
1205
|
+
this._loopTrack.push(true);
|
|
1206
|
+
}
|
|
1207
|
+
_popLoop() {
|
|
1208
|
+
this._loopTrack.pop();
|
|
1209
|
+
}
|
|
1210
|
+
_whileLoop(retain = false) {
|
|
1115
1211
|
const token = this.currentToken;
|
|
1116
1212
|
this._eat(TokenType.WHILE_TILL);
|
|
1213
|
+
this._pushLoop();
|
|
1117
1214
|
const test = this._expression();
|
|
1118
1215
|
const body = this.currentToken.type === TokenType.lbrace ? this._blockStatement() : this._expression();
|
|
1119
|
-
|
|
1216
|
+
this._popLoop();
|
|
1217
|
+
return new WhileLoopStatement(test, body, token, this.currentToken, retain);
|
|
1120
1218
|
}
|
|
1121
1219
|
_forOfIdentifier() {
|
|
1122
1220
|
switch (this.currentToken.type) {
|
|
@@ -1142,9 +1240,10 @@ class Parser {
|
|
|
1142
1240
|
* }
|
|
1143
1241
|
* (seginka|for) mali kono a
|
|
1144
1242
|
*/
|
|
1145
|
-
_forLoop() {
|
|
1243
|
+
_forLoop(retain = false) {
|
|
1146
1244
|
const startToken = this.currentToken;
|
|
1147
1245
|
this._eat(TokenType.FOR_LOOP);
|
|
1246
|
+
this._pushLoop();
|
|
1148
1247
|
let forOf = [TokenType.lparen].includes(this.currentToken.type);
|
|
1149
1248
|
let node;
|
|
1150
1249
|
if (forOf) {
|
|
@@ -1180,13 +1279,15 @@ class Parser {
|
|
|
1180
1279
|
update = new LiteralAST(new Token(TokenType.numberConst, 1, this.currentToken.line, this.currentToken.col), "1");
|
|
1181
1280
|
}
|
|
1182
1281
|
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1183
|
-
node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken);
|
|
1282
|
+
node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken, retain);
|
|
1283
|
+
this._popLoop();
|
|
1184
1284
|
}
|
|
1185
1285
|
else if (forOf) {
|
|
1186
1286
|
this._eat(TokenType.in);
|
|
1187
1287
|
const collection = this._expression();
|
|
1188
1288
|
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1189
|
-
node = new ForOfStatement(node, collection, body, startToken, this.currentToken);
|
|
1289
|
+
node = new ForOfStatement(node, collection, body, startToken, this.currentToken, retain);
|
|
1290
|
+
this._popLoop();
|
|
1190
1291
|
}
|
|
1191
1292
|
else {
|
|
1192
1293
|
error(this.currentToken);
|
|
@@ -1196,11 +1297,9 @@ class Parser {
|
|
|
1196
1297
|
_statement() {
|
|
1197
1298
|
switch (this.currentToken.type) {
|
|
1198
1299
|
case TokenType.BREAK:
|
|
1199
|
-
this.
|
|
1200
|
-
return new BreakAST(this.currentToken?.line, this.currentToken?.col);
|
|
1300
|
+
return this._breakExpression();
|
|
1201
1301
|
case TokenType.CONTINUE:
|
|
1202
|
-
this.
|
|
1203
|
-
return new ContinueAST(this.currentToken?.line, this.currentToken?.col);
|
|
1302
|
+
return this._continueExpression();
|
|
1204
1303
|
case TokenType.RETURN:
|
|
1205
1304
|
this._eat(TokenType.RETURN);
|
|
1206
1305
|
return this._return();
|
|
@@ -1648,7 +1747,7 @@ class MEvento extends NodeVisitor {
|
|
|
1648
1747
|
this.pushScope("ForLoopStatement");
|
|
1649
1748
|
const initialValue = this.visit(node.init.init);
|
|
1650
1749
|
this.changeVariable(loopIdentifier.value, initialValue);
|
|
1651
|
-
retainer?.push(initialValue)
|
|
1750
|
+
// retainer?.push(initialValue)
|
|
1652
1751
|
const test = () => {
|
|
1653
1752
|
const ret = this.visit(node.test);
|
|
1654
1753
|
if (isNum(ret)) {
|
|
@@ -2056,7 +2155,7 @@ class MEventoAsync extends MEvento {
|
|
|
2056
2155
|
this.pushScope("ForLoopStatement");
|
|
2057
2156
|
const initialValue = await this.visit(node.init.init);
|
|
2058
2157
|
this.changeVariable(loopIdentifier.value, initialValue);
|
|
2059
|
-
retainer?.push(initialValue)
|
|
2158
|
+
// retainer?.push(initialValue)
|
|
2060
2159
|
const test = async () => {
|
|
2061
2160
|
const ret = await this.visit(node.test);
|
|
2062
2161
|
if (isNum(ret)) {
|