mevento 2.0.5 → 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 +140 -41
- package/fesm2015/mevento.mjs +141 -41
- package/fesm2015/mevento.mjs.map +1 -1
- package/fesm2020/mevento.mjs +139 -40
- package/fesm2020/mevento.mjs.map +1 -1
- package/lib/mevento.d.ts +1 -2
- package/package.json +1 -1
package/fesm2015/mevento.mjs
CHANGED
|
@@ -181,6 +181,15 @@ class Lexer {
|
|
|
181
181
|
this._currentChar = this._source[this._position].charCodeAt(0);
|
|
182
182
|
this._col++;
|
|
183
183
|
}
|
|
184
|
+
_jump(n) {
|
|
185
|
+
this._position += n;
|
|
186
|
+
if (this._position >= this._source.length) {
|
|
187
|
+
this._currentChar = -1;
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this._currentChar = this._source[this._position].charCodeAt(0);
|
|
191
|
+
this._col += n;
|
|
192
|
+
}
|
|
184
193
|
_pick() {
|
|
185
194
|
if (this._position + 1 >= this._source.length) {
|
|
186
195
|
return -1;
|
|
@@ -315,28 +324,62 @@ class Lexer {
|
|
|
315
324
|
const lastL = this._line;
|
|
316
325
|
while (this._currentChar !== -1) {
|
|
317
326
|
const next = String.fromCharCode(this._pick());
|
|
318
|
-
if (this._currentChar
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
'0'
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
'
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
'
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
'
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
327
|
+
if (this._currentChar == Chars.backslash) {
|
|
328
|
+
switch (next) {
|
|
329
|
+
case '\\':
|
|
330
|
+
ret += "\\";
|
|
331
|
+
break;
|
|
332
|
+
case '0':
|
|
333
|
+
ret += "\0";
|
|
334
|
+
break;
|
|
335
|
+
case 'a':
|
|
336
|
+
ret += "\a";
|
|
337
|
+
break;
|
|
338
|
+
case 'b':
|
|
339
|
+
ret += "\b";
|
|
340
|
+
break;
|
|
341
|
+
case 'f':
|
|
342
|
+
ret += "\f";
|
|
343
|
+
break;
|
|
344
|
+
case 'n':
|
|
345
|
+
ret += "\n";
|
|
346
|
+
break;
|
|
347
|
+
case 'r':
|
|
348
|
+
ret += "\r";
|
|
349
|
+
break;
|
|
350
|
+
case 't':
|
|
351
|
+
ret += "\t";
|
|
352
|
+
break;
|
|
353
|
+
case 'u':
|
|
354
|
+
ret += String.fromCharCode(Number.parseInt(this._source.substring(this._position + 2, this._position + 6), 16));
|
|
355
|
+
this._jump(4);
|
|
356
|
+
// consume 4 unicode chars
|
|
357
|
+
break;
|
|
358
|
+
case 'v':
|
|
359
|
+
ret += "\v";
|
|
360
|
+
break;
|
|
361
|
+
case 'x':
|
|
362
|
+
ret += String.fromCharCode(Number.parseInt(this._source.substring(this._position + 2, this._position + 4), 16));
|
|
363
|
+
this._jump(2);
|
|
364
|
+
break;
|
|
365
|
+
default:
|
|
366
|
+
{
|
|
367
|
+
if (String.fromCharCode(startChar) == next) {
|
|
368
|
+
ret += String.fromCharCode(startChar);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
this._advance();
|
|
372
|
+
lastChar = this._currentChar;
|
|
373
|
+
ret += String.fromCharCode(this._currentChar);
|
|
374
|
+
this._advance();
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
339
378
|
}
|
|
379
|
+
// scape char
|
|
380
|
+
this._jump(2);
|
|
381
|
+
lastChar = this._currentChar;
|
|
382
|
+
continue;
|
|
340
383
|
}
|
|
341
384
|
if (this._currentChar === startChar && lastChar !== Chars.backslash) {
|
|
342
385
|
// end
|
|
@@ -802,8 +845,33 @@ class ContinueAST extends AST {
|
|
|
802
845
|
super(line, col);
|
|
803
846
|
}
|
|
804
847
|
}
|
|
848
|
+
class ListQueue {
|
|
849
|
+
constructor(capacity = Infinity) {
|
|
850
|
+
this.capacity = capacity;
|
|
851
|
+
this.storage = [];
|
|
852
|
+
}
|
|
853
|
+
push(item) {
|
|
854
|
+
if (this.size() === this.capacity) {
|
|
855
|
+
throw Error("Stack has reached max capacity, you cannot add more items");
|
|
856
|
+
}
|
|
857
|
+
this.storage.push(item);
|
|
858
|
+
}
|
|
859
|
+
pop() {
|
|
860
|
+
return this.storage.pop();
|
|
861
|
+
}
|
|
862
|
+
peek() {
|
|
863
|
+
return this.storage[this.size() - 1];
|
|
864
|
+
}
|
|
865
|
+
size() {
|
|
866
|
+
return this.storage.length;
|
|
867
|
+
}
|
|
868
|
+
get isEmpty() {
|
|
869
|
+
return this.storage.length === 0;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
805
872
|
class Parser {
|
|
806
873
|
constructor(lexer) {
|
|
874
|
+
this._loopTrack = new ListQueue();
|
|
807
875
|
this.currentToken = lexer.nextToken();
|
|
808
876
|
this.lexer = lexer;
|
|
809
877
|
}
|
|
@@ -881,10 +949,34 @@ class Parser {
|
|
|
881
949
|
return this._objectExpression();
|
|
882
950
|
case TokenType.IF:
|
|
883
951
|
return this._ifStatement();
|
|
952
|
+
case TokenType.WHILE_TILL:
|
|
953
|
+
return this._whileLoop(true);
|
|
954
|
+
case TokenType.FOR_LOOP:
|
|
955
|
+
return this._forLoop(true);
|
|
956
|
+
case TokenType.BREAK:
|
|
957
|
+
return this._breakExpression();
|
|
958
|
+
case TokenType.CONTINUE:
|
|
959
|
+
return this._continueExpression();
|
|
884
960
|
default:
|
|
885
961
|
return this._variable();
|
|
886
962
|
}
|
|
887
963
|
}
|
|
964
|
+
_breakExpression() {
|
|
965
|
+
var _a, _b;
|
|
966
|
+
if (this._loopTrack.isEmpty) {
|
|
967
|
+
error(this.currentToken);
|
|
968
|
+
}
|
|
969
|
+
this._eat(TokenType.BREAK);
|
|
970
|
+
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);
|
|
971
|
+
}
|
|
972
|
+
_continueExpression() {
|
|
973
|
+
var _a, _b;
|
|
974
|
+
if (this._loopTrack.isEmpty) {
|
|
975
|
+
error(this.currentToken);
|
|
976
|
+
}
|
|
977
|
+
this._eat(TokenType.CONTINUE);
|
|
978
|
+
return new ContinueAST((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.line, (_b = this.currentToken) === null || _b === void 0 ? void 0 : _b.col);
|
|
979
|
+
}
|
|
888
980
|
_term() {
|
|
889
981
|
let node = this._factor();
|
|
890
982
|
node = this._tryParsingFunctionCall(node);
|
|
@@ -1123,12 +1215,20 @@ class Parser {
|
|
|
1123
1215
|
}
|
|
1124
1216
|
return new IfStatementAST(test, consequent, alternate);
|
|
1125
1217
|
}
|
|
1126
|
-
|
|
1218
|
+
_pushLoop() {
|
|
1219
|
+
this._loopTrack.push(true);
|
|
1220
|
+
}
|
|
1221
|
+
_popLoop() {
|
|
1222
|
+
this._loopTrack.pop();
|
|
1223
|
+
}
|
|
1224
|
+
_whileLoop(retain = false) {
|
|
1127
1225
|
const token = this.currentToken;
|
|
1128
1226
|
this._eat(TokenType.WHILE_TILL);
|
|
1227
|
+
this._pushLoop();
|
|
1129
1228
|
const test = this._expression();
|
|
1130
1229
|
const body = this.currentToken.type === TokenType.lbrace ? this._blockStatement() : this._expression();
|
|
1131
|
-
|
|
1230
|
+
this._popLoop();
|
|
1231
|
+
return new WhileLoopStatement(test, body, token, this.currentToken, retain);
|
|
1132
1232
|
}
|
|
1133
1233
|
_forOfIdentifier() {
|
|
1134
1234
|
switch (this.currentToken.type) {
|
|
@@ -1154,9 +1254,10 @@ class Parser {
|
|
|
1154
1254
|
* }
|
|
1155
1255
|
* (seginka|for) mali kono a
|
|
1156
1256
|
*/
|
|
1157
|
-
_forLoop() {
|
|
1257
|
+
_forLoop(retain = false) {
|
|
1158
1258
|
const startToken = this.currentToken;
|
|
1159
1259
|
this._eat(TokenType.FOR_LOOP);
|
|
1260
|
+
this._pushLoop();
|
|
1160
1261
|
let forOf = [TokenType.lparen].includes(this.currentToken.type);
|
|
1161
1262
|
let node;
|
|
1162
1263
|
if (forOf) {
|
|
@@ -1192,13 +1293,15 @@ class Parser {
|
|
|
1192
1293
|
update = new LiteralAST(new Token(TokenType.numberConst, 1, this.currentToken.line, this.currentToken.col), "1");
|
|
1193
1294
|
}
|
|
1194
1295
|
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1195
|
-
node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken);
|
|
1296
|
+
node = new ForLoopStatement(node, test, update, direction, body, startToken, this.currentToken, retain);
|
|
1297
|
+
this._popLoop();
|
|
1196
1298
|
}
|
|
1197
1299
|
else if (forOf) {
|
|
1198
1300
|
this._eat(TokenType.in);
|
|
1199
1301
|
const collection = this._expression();
|
|
1200
1302
|
const body = (this.currentToken.type === TokenType.lbrace) ? this._blockStatement() : this._expression();
|
|
1201
|
-
node = new ForOfStatement(node, collection, body, startToken, this.currentToken);
|
|
1303
|
+
node = new ForOfStatement(node, collection, body, startToken, this.currentToken, retain);
|
|
1304
|
+
this._popLoop();
|
|
1202
1305
|
}
|
|
1203
1306
|
else {
|
|
1204
1307
|
error(this.currentToken);
|
|
@@ -1206,14 +1309,11 @@ class Parser {
|
|
|
1206
1309
|
return node;
|
|
1207
1310
|
}
|
|
1208
1311
|
_statement() {
|
|
1209
|
-
var _a, _b, _c, _d;
|
|
1210
1312
|
switch (this.currentToken.type) {
|
|
1211
1313
|
case TokenType.BREAK:
|
|
1212
|
-
this.
|
|
1213
|
-
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);
|
|
1314
|
+
return this._breakExpression();
|
|
1214
1315
|
case TokenType.CONTINUE:
|
|
1215
|
-
this.
|
|
1216
|
-
return new ContinueAST((_c = this.currentToken) === null || _c === void 0 ? void 0 : _c.line, (_d = this.currentToken) === null || _d === void 0 ? void 0 : _d.col);
|
|
1316
|
+
return this._continueExpression();
|
|
1217
1317
|
case TokenType.RETURN:
|
|
1218
1318
|
this._eat(TokenType.RETURN);
|
|
1219
1319
|
return this._return();
|
|
@@ -1498,17 +1598,17 @@ class MEvento extends NodeVisitor {
|
|
|
1498
1598
|
if (isNum(lValue) && isNum(rValue)) {
|
|
1499
1599
|
return lValue - rValue;
|
|
1500
1600
|
}
|
|
1501
|
-
if (isString(lValue) && isNum(rValue)) {
|
|
1502
|
-
return lValue * rValue;
|
|
1503
|
-
}
|
|
1504
|
-
if (isNum(lValue) && isString(rValue)) {
|
|
1505
|
-
return rValue * lValue;
|
|
1506
|
-
}
|
|
1507
1601
|
throw new Error(`Operation ${op.value} not allowed no num value`);
|
|
1508
1602
|
case TokenType.mult:
|
|
1509
1603
|
if (isNum(lValue) && isNum(rValue)) {
|
|
1510
1604
|
return lValue * rValue;
|
|
1511
1605
|
}
|
|
1606
|
+
if (isString(lValue) && isNum(rValue)) {
|
|
1607
|
+
return lValue.repeat(rValue);
|
|
1608
|
+
}
|
|
1609
|
+
if (isNum(lValue) && isString(rValue)) {
|
|
1610
|
+
return rValue.repeat(lValue);
|
|
1611
|
+
}
|
|
1512
1612
|
throw new Error(`Operation ${op.value} not allowed no num value`);
|
|
1513
1613
|
case TokenType.div:
|
|
1514
1614
|
if (isNum(lValue) && isNum(rValue)) {
|
|
@@ -1670,7 +1770,7 @@ class MEvento extends NodeVisitor {
|
|
|
1670
1770
|
this.pushScope("ForLoopStatement");
|
|
1671
1771
|
const initialValue = this.visit(node.init.init);
|
|
1672
1772
|
this.changeVariable(loopIdentifier.value, initialValue);
|
|
1673
|
-
|
|
1773
|
+
// retainer?.push(initialValue)
|
|
1674
1774
|
const test = () => {
|
|
1675
1775
|
const ret = this.visit(node.test);
|
|
1676
1776
|
if (isNum(ret)) {
|
|
@@ -1928,10 +2028,10 @@ class MEventoAsync extends MEvento {
|
|
|
1928
2028
|
return lValue - rValue;
|
|
1929
2029
|
}
|
|
1930
2030
|
if (isString(lValue) && isNum(rValue)) {
|
|
1931
|
-
return lValue
|
|
2031
|
+
return lValue.repeat(rValue);
|
|
1932
2032
|
}
|
|
1933
2033
|
if (isNum(lValue) && isString(rValue)) {
|
|
1934
|
-
return rValue
|
|
2034
|
+
return rValue.repeat(lValue);
|
|
1935
2035
|
}
|
|
1936
2036
|
throw new Error(`Operation ${op.value} not allowed no num value`);
|
|
1937
2037
|
case TokenType.mult:
|
|
@@ -2114,7 +2214,7 @@ class MEventoAsync extends MEvento {
|
|
|
2114
2214
|
this.pushScope("ForLoopStatement");
|
|
2115
2215
|
const initialValue = yield this.visit(node.init.init);
|
|
2116
2216
|
this.changeVariable(loopIdentifier.value, initialValue);
|
|
2117
|
-
|
|
2217
|
+
// retainer?.push(initialValue)
|
|
2118
2218
|
const test = () => __awaiter(this, void 0, void 0, function* () {
|
|
2119
2219
|
const ret = yield this.visit(node.test);
|
|
2120
2220
|
if (isNum(ret)) {
|