ion-oui
Version:
The client library of oui builder for ionic
1,338 lines (1,337 loc) • 66.4 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MEventoAsync = exports.MEvento = void 0;
function error(token) {
var text = "Invalid token ".concat(token.type, "[").concat(token.value, "] at ").concat(token.line, ", ").concat(token.col, "\n");
throw (text);
}
function isNum(value) {
return typeof value === 'number';
}
function isBoolean(value) {
return typeof value === 'boolean';
}
function isString(value) {
return typeof value === 'string';
}
function _boolValue(test) {
return test !== null &&
((isNum(test) && test !== 0) ||
(isString(test) && test.length > 0) ||
(isBoolean(test) && test));
}
;
function hashCode(str) {
var hash = 0;
var i = 0;
var chr;
if (str.length === 0)
return hash;
for (i = 0; i < str.length; i++) {
chr = str.charCodeAt(i);
// tslint:disable-next-line:no-bitwise
hash = ((hash << 5) - hash) + chr;
// tslint:disable-next-line:no-bitwise
hash |= 0; // Convert to 32bit integer
}
return hash;
}
;
var TokenType = /** @class */ (function () {
function TokenType() {
}
TokenType.id = 0;
TokenType.comma = 1;
TokenType.semi = 2;
TokenType.numberConst = 3;
TokenType.stringConst = 4;
TokenType.equal = 5;
TokenType.lparen = 6;
TokenType.rparen = 7;
TokenType.eol = 8;
TokenType.eof = 9;
TokenType.lbrace = 10;
TokenType.rbrace = 11;
TokenType.lbracket = 12;
TokenType.rbracket = 13;
TokenType.great = 14;
TokenType.greatEq = 15;
TokenType.less = 16;
TokenType.lessEq = 17;
TokenType.eqeq = 18;
TokenType.IF = 19;
TokenType.ELSE = 20;
TokenType.TRUE = 21;
TokenType.FALSE = 22;
TokenType.NULL = 23;
TokenType.not = 24;
TokenType.notEq = 25;
TokenType.and = 26;
TokenType.or = 27;
TokenType.plus = 28;
TokenType.minus = 29;
TokenType.div = 30;
TokenType.mult = 31;
TokenType.mod = 32;
TokenType.invalid = 33;
return TokenType;
}());
var Token = /** @class */ (function () {
function Token(type, value, line, col) {
if (line === void 0) { line = 1; }
if (col === void 0) { col = 1; }
this.type = type;
this.value = value;
this.line = line;
this.col = col;
}
Token.from = function (type, value) {
return new Token(type, value);
};
Token.prototype.toString = function () {
return "[".concat(this.type.toString(), ", ").concat(this.value, "]");
};
return Token;
}());
var Chars = /** @class */ (function () {
function Chars() {
}
Chars.equal = '='.charCodeAt(0);
Chars.comma = ','.charCodeAt(0);
Chars.semiColon = ';'.charCodeAt(0);
Chars.lparen = '('.charCodeAt(0);
Chars.rparen = ')'.charCodeAt(0);
Chars.backslash = '\\'.charCodeAt(0);
Chars.quote = '"'.charCodeAt(0);
Chars.squote = "'".charCodeAt(0);
Chars.plus = "+".charCodeAt(0);
Chars.minus = "-".charCodeAt(0);
Chars.star = "*".charCodeAt(0);
Chars.slash = "/".charCodeAt(0);
Chars.percent = "%".charCodeAt(0);
Chars.lbrace = "{".charCodeAt(0);
Chars.rbrace = "}".charCodeAt(0);
Chars.lbracket = "[".charCodeAt(0);
Chars.rbracket = "]".charCodeAt(0);
Chars.not = "!".charCodeAt(0);
Chars.great = ">".charCodeAt(0);
Chars.less = "<".charCodeAt(0);
Chars.and = "&".charCodeAt(0);
Chars.pipe = "|".charCodeAt(0);
return Chars;
}());
var LexerDictionary = /** @class */ (function () {
function LexerDictionary(lang, keywords) {
this.keywords = {};
this.keywords = __assign({}, keywords);
this.lang = lang;
}
return LexerDictionary;
}());
/**
* Lexing => Parsing ===> AST ===> Walking
*/
/**
* Lexer
*/
var Lexer = /** @class */ (function () {
function Lexer(source) {
this._position = 0;
this._line = 1;
this._col = 1;
this._currentChar = -1;
this._source = source;
this._currentChar = this._source[this._position].charCodeAt(0);
this._resolveLanguage();
}
Object.defineProperty(Lexer.prototype, "source", {
get: function () {
return this._source;
},
enumerable: false,
configurable: true
});
Lexer.prototype._resolveLanguage = function () {
var token = this.nextToken();
if (token.type === TokenType.less) {
// language setting
var idToken = this.nextToken();
if (idToken.type !== TokenType.id) {
error(token);
}
var lang_1 = idToken.value.toString();
this._language = Lexer.languages.find(function (element) { return element.lang === lang_1; }) || Lexer._defaultLanguage;
token = this.nextToken();
if (token.type !== TokenType.great) {
error(token);
}
}
else {
this._language = Lexer._defaultLanguage;
// reset reading
this._position = 0;
this._currentChar = this._source[this._position].charCodeAt(0);
}
};
Lexer.prototype._advance = function () {
this._position++;
if (this._position >= this._source.length) {
this._currentChar = -1;
return;
}
this._currentChar = this._source[this._position].charCodeAt(0);
this._col++;
};
Lexer.prototype._pick = function () {
if (this._position >= this._source.length) {
return -1;
}
return this._source[this._position].charCodeAt(0);
};
Lexer.prototype._isIdStart = function (code) {
if (code < 48) {
return code === 36;
}
if (code < 58) {
return true;
}
if (code < 65) {
return false;
}
if (code < 91) {
return true;
}
if (code < 97) {
return code === 95;
}
if (code < 123) {
return true;
}
return false;
};
Lexer.prototype._isId = function (code) {
if (code < 65) {
return code === 36;
}
if (code < 91) {
return true;
}
if (code < 97) {
return code === 95;
}
if (code < 123) {
return true;
}
return false;
};
Lexer.prototype._id = function () {
var ret = "";
var lastC = this._col;
var lastP = this._position;
var line = this._line;
while (this._isId(this._currentChar)) {
ret += String.fromCharCode(this._currentChar);
this._advance();
}
var translatedId = this._language
? (this._language.keywords[ret]) || ret
: ret;
return Lexer.RESERVED[translatedId] || new Token(TokenType.id, ret, line, lastC);
};
Lexer.prototype._isLineEnd = function (c) {
return c === 10 ||
c === 13 ||
['\n', '\r', '\u2028', '\u2029'].includes(String.fromCharCode(c));
};
Lexer.prototype._isWhiteSpace = function (c) {
return String.fromCharCode(c).trim() === "" &&
String.fromCharCode(c).length > 0;
};
Lexer.prototype._isDigit = function (c) {
// tslint:disable-next-line:no-bitwise
return c > 0 && (c ^ 0x30) <= 9;
};
Lexer.prototype._skipWhiteSpace = function () {
while (this._isWhiteSpace(this._currentChar) === true) {
this._advance();
}
};
Lexer.prototype._number = function () {
var ret = "";
var lastC = this._col;
var lastP = this._position;
var line = this._line;
var first = String.fromCharCode(this._currentChar);
this._advance();
var bc = String.fromCharCode(this._currentChar);
var base = 10;
if (first === '0' && ['b', 'B', 'x', 'X', 'o', 'O'].includes(bc)) {
// look ahead to see that the number is tagged
this._advance();
switch (bc.toLowerCase()) {
case 'b':
base = 2;
break;
case "o":
base = 8;
break;
case "x":
base = 16;
break;
default:
base = 10;
}
}
else {
ret += first;
base = 10;
}
while (this._isDigit(this._currentChar) ||
(base === 16 &&
['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f']
.includes(String.fromCharCode(this._currentChar)))) {
ret += String.fromCharCode(this._currentChar);
this._advance();
}
if (String.fromCharCode(this._currentChar) === '.' && this._isDigit(this._pick()) === true) {
if (base !== 10) {
error(new Token(TokenType.id, bc, line, lastP));
}
// floating number
ret += String.fromCharCode(this._currentChar);
this._advance();
while (this._isDigit(this._currentChar)) {
ret += String.fromCharCode(this._currentChar);
this._advance();
}
return new Token(TokenType.numberConst, parseFloat(ret), line, lastC);
}
return new Token(TokenType.numberConst, parseInt(ret, base), line, lastC);
};
Lexer.prototype._literalString = function (startChar) {
var ret = "";
var lastChar = -1;
var lastP = this._position;
var lastC = this._col;
var lastL = this._line;
while (this._currentChar !== -1) {
var next = String.fromCharCode(this._pick());
if (this._currentChar === Chars.backslash) {
// scape char
if ([
startChar,
'\\',
'0',
'a',
'b',
'e',
'f',
'n',
'r',
't',
'u',
'U',
'v',
'x'
].includes(next)) {
lastChar = this._currentChar;
this._advance();
continue;
}
}
if (this._currentChar === startChar && lastChar !== Chars.backslash) {
// end
break;
}
ret += String.fromCharCode(this._currentChar);
lastChar = this._currentChar;
this._advance();
}
return new Token(TokenType.stringConst, ret, lastL, lastC);
};
// f=SUBMIT_FORM(xxx);
// r = CALL_API(API_ID, f);
// DISPLAY("MSG #r")
Lexer.prototype.nextToken = function () {
var lastL = this._line;
var lastC = this._col;
var lastP = this._position;
while (this._currentChar !== -1) {
if (this._isLineEnd(this._currentChar)) {
this._line++;
this._col = 1;
this._advance();
return new Token(TokenType.eol, "\n", lastL, lastC);
}
if (this._isWhiteSpace(this._currentChar)) {
this._skipWhiteSpace();
continue;
}
if (this._isDigit(this._currentChar)) {
return this._number();
}
if (this._isIdStart(this._currentChar)) {
return this._id();
}
if (this._currentChar === Chars.equal) {
this._advance();
if (this._currentChar === Chars.equal) {
this._advance();
return new Token(TokenType.eqeq, "==", lastL, lastC);
}
return new Token(TokenType.equal, "=", lastL, lastC);
}
if (this._currentChar === Chars.great) {
this._advance();
if (this._currentChar === Chars.equal) {
this._advance();
return new Token(TokenType.greatEq, ">=", lastL, lastC);
}
return new Token(TokenType.great, ">", lastL, lastC);
}
if (this._currentChar === Chars.less) {
this._advance();
if (this._currentChar === Chars.equal) {
this._advance();
return new Token(TokenType.lessEq, "<=", lastL, lastC);
}
return new Token(TokenType.less, "<", lastL, lastC);
}
if (this._currentChar === Chars.semiColon) {
this._advance();
return new Token(TokenType.semi, ";", lastL, lastC);
}
if (this._currentChar === Chars.lparen) {
this._advance();
return new Token(TokenType.lparen, "(", lastL, lastC);
}
if (this._currentChar === Chars.rparen) {
this._advance();
return new Token(TokenType.rparen, ")", lastL, lastC);
}
if (this._currentChar === Chars.comma) {
this._advance();
return new Token(TokenType.comma, ",", lastL, lastC);
}
if (this._currentChar === Chars.lbrace) {
this._advance();
return new Token(TokenType.lbrace, "{", lastL, lastC);
}
if (this._currentChar === Chars.rbrace) {
this._advance();
return new Token(TokenType.rbrace, "}", lastL, lastC);
}
if (this._currentChar === Chars.lbracket) {
this._advance();
return new Token(TokenType.lbracket, "[", lastL, lastC);
}
if (this._currentChar === Chars.rbracket) {
this._advance();
return new Token(TokenType.rbracket, "]", lastL, lastC);
}
if (this._currentChar === Chars.plus) {
this._advance();
return new Token(TokenType.plus, "+", lastL, lastC);
}
if (this._currentChar === Chars.minus) {
this._advance();
return new Token(TokenType.minus, "-", lastL, lastC);
}
if (this._currentChar === Chars.slash) {
this._advance();
return new Token(TokenType.div, "/", lastL, lastC);
}
if (this._currentChar === Chars.star) {
this._advance();
return new Token(TokenType.mult, "*", lastL, lastC);
}
if (this._currentChar === Chars.percent) {
this._advance();
return new Token(TokenType.mod, "%", lastL, lastC);
}
if (this._currentChar === Chars.not) {
this._advance();
if (this._currentChar === Chars.equal) {
this._advance();
return new Token(TokenType.notEq, "!=", lastL, lastC);
}
return new Token(TokenType.not, "!", lastL, lastC);
}
if (this._currentChar === Chars.and && this._pick() === Chars.and) {
this._advance();
this._advance();
return new Token(TokenType.and, "&&", lastL, lastC);
}
if (this._currentChar === Chars.pipe && this._pick() === Chars.pipe) {
this._advance();
this._advance();
return new Token(TokenType.and, '||', lastL, lastC);
}
if (this._currentChar === Chars.quote || this._currentChar === Chars.squote) {
var startChar = this._currentChar;
this._advance();
var t = this._literalString(startChar);
this._advance();
return t;
}
return new Token(TokenType.invalid, String.fromCharCode(this._currentChar), lastL, lastC);
}
return new Token(TokenType.eof, "", lastL, lastC);
};
Lexer._defaultLanguage = new LexerDictionary("en", {
"if": "if",
"else": "else",
"true": "true",
"false": "false",
"null": "null",
});
Lexer.languages = [
Lexer._defaultLanguage,
new LexerDictionary("fr", {
"si": "if",
"sinon": "else",
"vrai": "else",
"faux": "false",
"nul": "null",
}),
new LexerDictionary("bm", {
"nii": "if",
"note": "else",
"tien": "true",
"galon": "false",
"gansan": "null",
}),
];
Lexer.RESERVED = {
"if": Token.from(TokenType.IF, "if"),
"else": Token.from(TokenType.ELSE, "else"),
"true": Token.from(TokenType.TRUE, true),
"false": Token.from(TokenType.FALSE, false),
"null": Token.from(TokenType.NULL, null),
};
return Lexer;
}());
/**
* Parser
*/
var AST = /** @class */ (function () {
function AST(line, col) {
this.line = line;
this.col = col;
}
AST.prototype.dump = function () {
return this.toString();
};
return AST;
}());
var RootAST = /** @class */ (function (_super) {
__extends(RootAST, _super);
function RootAST(body, name, source) {
var _this = _super.call(this, 1, 1) || this;
_this.body = body;
_this.name = name;
_this.source = source;
return _this;
}
RootAST.prototype.dump = function () {
var builder = "Module ".concat(this.name, " Start {");
for (var _i = 0, _a = this.body; _i < _a.length; _i++) {
var it_1 = _a[_i];
builder += "".concat(it_1.dump(), "\n");
}
builder += "}";
return builder;
};
return RootAST;
}(AST));
var BlockStatementAST = /** @class */ (function (_super) {
__extends(BlockStatementAST, _super);
function BlockStatementAST(body, token) {
var _this = _super.call(this, token.line, token.col) || this;
_this.body = body;
return _this;
}
BlockStatementAST.prototype.toString = function () {
return "{\n".concat(this.body.map(function (e) { return e.toString(); }).join("\n"), "}");
};
return BlockStatementAST;
}(AST));
var IdentifierAST = /** @class */ (function (_super) {
__extends(IdentifierAST, _super);
function IdentifierAST(token) {
var _this = _super.call(this, token.line, token.col) || this;
_this.value = token.value.toString();
return _this;
}
IdentifierAST.prototype.toString = function () {
return this.value;
};
return IdentifierAST;
}(AST));
var LiteralAST = /** @class */ (function (_super) {
__extends(LiteralAST, _super);
function LiteralAST(token, raw) {
var _this = _super.call(this, token.line, token.col) || this;
_this.value = token.value;
_this.raw = raw;
return _this;
}
LiteralAST.prototype.toString = function () {
return this.value.toString();
};
return LiteralAST;
}(AST));
var AssignmentExpressionAST = /** @class */ (function (_super) {
__extends(AssignmentExpressionAST, _super);
function AssignmentExpressionAST(identifier, init) {
var _this = _super.call(this, identifier.line, identifier.col) || this;
_this.identifier = identifier;
_this.init = init;
return _this;
}
AssignmentExpressionAST.prototype.toString = function () {
return "".concat(this.identifier, " = ").concat(this.init);
};
return AssignmentExpressionAST;
}(AST));
var ExpressionStatementAST = /** @class */ (function (_super) {
__extends(ExpressionStatementAST, _super);
function ExpressionStatementAST(expression) {
var _this = _super.call(this, expression.line, expression.col) || this;
_this.expression = expression;
return _this;
}
ExpressionStatementAST.prototype.toString = function () {
return this.expression.toString();
};
return ExpressionStatementAST;
}(AST));
var CallExpressionAST = /** @class */ (function (_super) {
__extends(CallExpressionAST, _super);
function CallExpressionAST(callee, ags) {
var _this = _super.call(this, callee.line, callee.col) || this;
_this.callee = callee;
_this.arguments = ags;
return _this;
}
CallExpressionAST.prototype.toString = function () {
return "".concat(this.callee.toString(), "(...").concat(this.arguments.length, ")");
};
return CallExpressionAST;
}(AST));
var BinaryExpressionAST = /** @class */ (function (_super) {
__extends(BinaryExpressionAST, _super);
function BinaryExpressionAST(left, operation, right) {
var _this = _super.call(this, left.line, left.col) || this;
_this.left = left;
_this.operation = operation;
_this.right = right;
return _this;
}
BinaryExpressionAST.prototype.toString = function () {
return "".concat(this.left, " ").concat(this.operation, " ").concat(this.right);
};
return BinaryExpressionAST;
}(AST));
var UnaryExpressionAST = /** @class */ (function (_super) {
__extends(UnaryExpressionAST, _super);
function UnaryExpressionAST(operation, argument) {
var _this = _super.call(this, operation.line, operation.col) || this;
_this.operation = operation, _this.argument = argument;
return _this;
}
UnaryExpressionAST.prototype.toString = function () {
return "".concat(this.operation, " ").concat(this.argument);
};
return UnaryExpressionAST;
}(AST));
var IfStatementAST = /** @class */ (function (_super) {
__extends(IfStatementAST, _super);
function IfStatementAST(test, consequent, alternate) {
var _this = _super.call(this, test.line, test.col) || this;
_this.test = test;
_this.consequent = consequent;
_this.alternate = alternate;
return _this;
}
IfStatementAST.prototype.toString = function () {
return "if ".concat(this.test, " ").concat(this.consequent, " ").concat(this.alternate !== null ? "else ".concat(this.alternate, " ") : '');
};
return IfStatementAST;
}(AST));
var LogicalExpressionAST = /** @class */ (function (_super) {
__extends(LogicalExpressionAST, _super);
function LogicalExpressionAST(left, operator, right) {
var _this = _super.call(this, left.line, left.col) || this;
_this.left = left;
_this.operator = operator;
_this.right = right;
return _this;
}
LogicalExpressionAST.prototype.toString = function () {
return "".concat(this.left, " ").concat(this.operator.value, " ").concat(this.right);
};
return LogicalExpressionAST;
}(AST));
var IndexAccessorAST = /** @class */ (function (_super) {
__extends(IndexAccessorAST, _super);
function IndexAccessorAST(owner, key) {
var _this = _super.call(this, owner.line, owner.col) || this;
_this.owner = owner;
_this.key = key;
return _this;
}
IndexAccessorAST.prototype.toString = function () {
return "".concat(this.owner, "[").concat(this.key, "]");
};
return IndexAccessorAST;
}(AST));
var Parser = /** @class */ (function () {
function Parser(lexer) {
this.currentToken = lexer.nextToken();
this.lexer = lexer;
}
Parser.prototype._eat = function (type) {
var _a;
if (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === type) {
this.currentToken = this.lexer.nextToken();
}
else {
error(this.currentToken);
}
};
Parser.prototype._eatEOL = function () {
var _a;
while (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === TokenType.eol) {
this._eat(TokenType.eol);
}
};
Parser.prototype._eatSemiOrEOL = function () {
var _a, _b;
while (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === TokenType.eol ||
((_b = this.currentToken) === null || _b === void 0 ? void 0 : _b.type) === TokenType.semi) {
this._eat(this.currentToken.type);
}
};
Parser.prototype._eatSemi = function () {
var _a;
while (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === TokenType.semi) {
this._eat(TokenType.semi);
}
};
Parser.prototype._variable = function () {
var node = new IdentifierAST(this.currentToken);
this._eat(TokenType.id);
return node;
};
Parser.prototype._factor = function () {
var token = this.currentToken;
switch (token.type) {
case TokenType.plus:
case TokenType.minus:
case TokenType.not:
this._eat(this.currentToken.type);
return new UnaryExpressionAST(this.currentToken, this._factor());
case TokenType.numberConst:
this._eat(TokenType.numberConst);
return new LiteralAST(token, token.value.toString());
case TokenType.stringConst:
this._eat(TokenType.stringConst);
return new LiteralAST(token, token.value.toString());
case TokenType.lparen:
this._eat(TokenType.lparen);
var node = this._expression();
this._eat(TokenType.rparen);
return node;
case TokenType.TRUE:
case TokenType.FALSE:
this._eat(this.currentToken.type);
return new LiteralAST(token, token.value.toString());
case TokenType.NULL:
this._eat(TokenType.NULL);
return new LiteralAST(token, "null");
default:
return this._variable();
}
};
Parser.prototype._term = function () {
var node = this._factor();
node = this._tryParsingMemberExpression(node);
node = this._tryParsingFunctionCall(node);
return node;
};
Parser.prototype._expression = function () {
var node = this._term();
node = this._tryBinaryExpression(0, node);
while ([TokenType.and, TokenType.or].includes(this.currentToken.type)) {
var token = this.currentToken;
this._eat(token.type);
node = new LogicalExpressionAST(node, token, this._expression());
}
if (this._expect(TokenType.equal)) {
if (node instanceof IdentifierAST) {
var token = this.currentToken;
this._eat(TokenType.equal);
node = new AssignmentExpressionAST(node, this._expression());
}
else {
throw new Error("Unexpected token");
}
}
return node;
};
Parser.prototype._tryParsingMemberExpression = function (n) {
var node = n;
while (this.currentToken.type === TokenType.lbracket) {
this._eat(TokenType.lbracket);
var key = this._expression();
node = new IndexAccessorAST(node, key);
this._eat(TokenType.rbracket);
}
return node;
};
Parser.prototype._tryBinaryExpression = function (prec, left) {
var node = left;
while (true) {
var currentPrec = Parser._binopPrecdences[this.currentToken.type] || -1;
if (currentPrec < prec)
return node;
var operator = this.currentToken;
this._eat(operator.type);
var right = this._term();
var nextPrec = Parser._binopPrecdences[this.currentToken.type] || -1;
if (currentPrec < nextPrec) {
var tmp = this._tryBinaryExpression(currentPrec + 1, right);
if (tmp === node)
return tmp;
right = tmp;
}
node = new BinaryExpressionAST(node, operator, right);
}
};
Parser.prototype._expressionsList = function () {
var _a;
this._eatEOL();
// if (expect(Lexer.TokenType.RPAREN)) return emptyList()
var expr = this._expression();
var result = [expr];
while (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === TokenType.comma) {
this._eat(TokenType.comma);
expr = this._expression();
result.push(expr);
}
return result;
};
Parser.prototype._callExpression = function (node) {
this._eat(TokenType.lparen);
var args = [];
if (!this._expect(TokenType.rparen)) {
args = this._expressionsList();
}
this._eat(TokenType.rparen);
if (!(node instanceof IdentifierAST)) {
error(this.currentToken);
}
return new CallExpressionAST(node, args);
};
Parser.prototype._tryParsingFunctionCall = function (n) {
var node = n;
while (this.currentToken.type === TokenType.lparen) {
// probable function call
node = this._callExpression(node);
}
return node;
};
Parser.prototype._statementExpression = function () {
var node = this._expression();
if (![TokenType.semi, TokenType.eol, TokenType.eof]
.includes(this.currentToken.type)) {
error(this.currentToken);
}
return node;
};
Parser.prototype._blockStatement = function (ignoreFirstBrace) {
var _a;
if (ignoreFirstBrace === void 0) { ignoreFirstBrace = false; }
if (!ignoreFirstBrace)
this._eat(TokenType.lbrace);
this._eatEOL();
if (this._expect(TokenType.rbrace)) {
this._eat(TokenType.rbrace);
return new BlockStatementAST([], this.currentToken);
}
// const body = _statements();
var body = [this._statement()];
while (this.currentToken.type === TokenType.eol ||
this.currentToken.type === TokenType.semi) {
this._eatSemiOrEOL();
if (this.currentToken.type === TokenType.rbrace || this.currentToken.type === TokenType.eof) {
// _eat(this.currentToken!.type);
break;
}
body.push(this._statement());
if (this.currentToken.type !== TokenType.eol &&
this.currentToken.type !== TokenType.semi &&
this.currentToken.type !== TokenType.eof) {
error(this.currentToken);
}
}
this._eat(TokenType.rbrace);
if (((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === TokenType.rbrace) {
// endBlock
this._eat(TokenType.rbrace);
}
return new BlockStatementAST(body, this.currentToken);
};
Parser.prototype._ifStatement = function () {
this._eat(TokenType.IF);
var withPar = this.currentToken.type === TokenType.lparen;
if (withPar) {
this._eat(TokenType.lparen);
}
var test = this._expression();
if (withPar) {
this._eat(TokenType.rparen);
}
var consequent;
if (this.currentToken.type === TokenType.lbrace) {
consequent = this._blockStatement();
}
else {
consequent = this._expression();
}
this._eatSemiOrEOL();
var alternate;
if (this.currentToken.type === TokenType.ELSE) {
this._eat(TokenType.ELSE);
switch (this.currentToken.type) {
case TokenType.IF:
alternate = this._ifStatement();
break;
case TokenType.lbrace:
alternate = this._blockStatement();
break;
default:
alternate = this._expression();
}
}
return new IfStatementAST(test, consequent, alternate);
};
Parser.prototype._statement = function () {
switch (this.currentToken.type) {
case TokenType.semi:
this._eatSemi();
return this._statement();
case TokenType.eol:
this._eatEOL();
return this._statement();
case TokenType.IF:
return this._ifStatement();
default:
return this._statementExpression();
}
};
Parser.prototype._expect = function (type) {
var _a;
return ((_a = this.currentToken) === null || _a === void 0 ? void 0 : _a.type) === type;
};
Parser.prototype._statements = function () {
this._eatEOL();
if (this._expect(TokenType.eof)) {
return [];
}
var results = [this._statement()];
while ((this.currentToken.type === TokenType.eol ||
this.currentToken.type === TokenType.semi)) {
this._eatSemiOrEOL();
if (this.currentToken.type === TokenType.eof) {
this._eat(TokenType.eof);
break;
}
results.push(this._statement());
if (this.currentToken.type !== TokenType.eol &&
this.currentToken.type !== TokenType.semi &&
this.currentToken.type !== TokenType.eof) {
error(this.currentToken);
}
}
return results;
};
Parser.prototype._root = function () {
var source = this.lexer.source;
var name = "<module>";
var list = this._statements();
return new RootAST(list, name, source);
};
Parser.prototype.parse = function () {
return this._root();
};
Parser._binopPrecdences = (_a = {},
_a[TokenType.eqeq] = 10,
_a[TokenType.great] = 10,
_a[TokenType.greatEq] = 10,
_a[TokenType.less] = 10,
_a[TokenType.lessEq] = 10,
_a[TokenType.plus] = 20,
_a[TokenType.minus] = 20,
_a[TokenType.mult] = 40,
_a[TokenType.div] = 40,
_a[TokenType.mod] = 40,
_a);
return Parser;
}());
// AST Wallker
var ANodeVisitor = /** @class */ (function () {
function ANodeVisitor() {
this._nodesVisitors = {};
}
ANodeVisitor.prototype.registerVisitor = function (type, visitor) {
var methodName = "visit".concat(type.name);
// console.log('Reg::::::', methodName, type);
this._nodesVisitors[methodName] = visitor;
};
return ANodeVisitor;
}());
var AsyncNodeVisitor = /** @class */ (function (_super) {
__extends(AsyncNodeVisitor, _super);
function AsyncNodeVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
AsyncNodeVisitor.prototype.visit = function (node) {
return __awaiter(this, void 0, void 0, function () {
var methodName, fn;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
methodName = "visit".concat(node.constructor.name);
fn = this._nodesVisitors[methodName];
return [4 /*yield*/, (fn === null || fn === void 0 ? void 0 : fn.call(this, node))];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
return AsyncNodeVisitor;
}(ANodeVisitor));
var NodeVisitor = /** @class */ (function (_super) {
__extends(NodeVisitor, _super);
function NodeVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
NodeVisitor.prototype.visit = function (node) {
var methodName = "visit".concat(node.constructor.name);
// const fn = Object.getPrototypeOf(this)[methodName];
var fn = this._nodesVisitors[methodName];
return fn === null || fn === void 0 ? void 0 : fn.call(this, node);
};
return NodeVisitor;
}(ANodeVisitor));
var MEvento = /** @class */ (function (_super) {
__extends(MEvento, _super);
function MEvento() {
var _this = _super.call(this) || this;
_this._memory = {};
_this._functionsRegistry = {};
_this.registerVisitor(RootAST, _this.visitRootAST);
_this.registerVisitor(BlockStatementAST, _this.visitBlockStatementAST);
_this.registerVisitor(IdentifierAST, _this.visitIdentifierAST);
_this.registerVisitor(LiteralAST, _this.visitLiteralAST);
_this.registerVisitor(AssignmentExpressionAST, _this.visitAssignmentExpressionAST);
_this.registerVisitor(ExpressionStatementAST, _this.visitExpressionStatementAST);
_this.registerVisitor(CallExpressionAST, _this.visitCallExpressionAST);
_this.registerVisitor(BinaryExpressionAST, _this.visitBinaryExpressionAST);
_this.registerVisitor(UnaryExpressionAST, _this.visitUnaryExpressionAST);
_this.registerVisitor(IfStatementAST, _this.visitIfStatementAST);
_this.registerVisitor(LogicalExpressionAST, _this.visitLogicalExpressionAST);
_this.registerVisitor(IndexAccessorAST, _this.visitIndexAccessorAST);
_this._functionsRegistry = __assign({}, MEvento._globalFunctionsRegistry);
return _this;
}
MEvento.prototype.visitRootAST = function (node) {
var list = node.body;
var last;
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
var n = list_1[_i];
last = this.visit(n);
}
return last;
};
MEvento.prototype.visitBlockStatementAST = function (node) {
var list = node.body;
var last;
for (var _i = 0, list_2 = list; _i < list_2.length; _i++) {
var n = list_2[_i];
last = this.visit(n);
}
return last;
};
MEvento.prototype.visitIdentifierAST = function (node) {
var id = node.value;
return this._memory[id];
};
MEvento.prototype.visitLiteralAST = function (node) {
var value = node.value;
return value;
};
MEvento.prototype.visitAssignmentExpressionAST = function (node) {
var id = node.identifier;
var init = node.init;
var value = this.visit(init);
this._memory[id.value] = value;
return value;
};
MEvento.prototype.visitExpressionStatementAST = function (node) {
var expr = node.expression;
return this.visit(expr);
};
MEvento.prototype.visitCallExpressionAST = function (node) {
var _this = this;
var callee = node.callee;
var args = node.arguments;
var calleeName = callee.value;
var fn = this._functionsRegistry[calleeName];
var argValues = args.map(function (e) { return _this.visit(e); });
// print("argValues::", argValues)
return fn === null || fn === void 0 ? void 0 : fn(argValues);
};
MEvento.prototype.visitBinaryExpressionAST = function (node) {
var left = node.left;
var right = node.right;
var op = node.operation;
var lValue = this.visit(left);
var rValue = this.visit(right);
switch (op.type) {
case TokenType.plus:
if (isNum(lValue) && isNum(rValue)) {
return lValue + rValue;
}
return "".concat(lValue).concat(rValue);
case TokenType.minus:
if (isNum(lValue) && isNum(rValue)) {
return lValue - rValue;
}
if (isString(lValue) && isNum(rValue)) {
return lValue * rValue;
}
if (isNum(lValue) && isString(rValue)) {
return rValue * lValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.mult:
if (isNum(lValue) && isNum(rValue)) {
return lValue * rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.div:
if (isNum(lValue) && isNum(rValue)) {
if (rValue === 0) {
throw new Error("Invalid division by 0");
}
return lValue / rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.mod:
if (isNum(lValue) && isNum(rValue)) {
return lValue % rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.great:
if (isNum(lValue) && isNum(rValue)) {
return lValue > rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.greatEq:
if (isNum(lValue) && isNum(rValue)) {
return lValue >= rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.less:
if (isNum(lValue) && isNum(rValue)) {
return lValue < rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.lessEq:
if (isNum(lValue) && isNum(rValue)) {
return lValue <= rValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
case TokenType.eqeq:
return lValue === rValue;
case TokenType.notEq:
return lValue !== rValue;
default:
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
}
};
MEvento.prototype.visitUnaryExpressionAST = function (node) {
var arg = node.argument;
var op = node.operation;
var argValue = this.visit(arg);
if (isNum(argValue)) {
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
}
if (op.type === TokenType.plus) {
return argValue;
}
else if (op.type === TokenType.minus) {
return -argValue;
}
throw new Error("Operation ".concat(op.value, " not allowed no num value"));
};
MEvento.prototype.visitIfStatementAST = function (node) {
var testNode = node.test;
var test = this.visit(testNode);
var testBoolValue = test !== null &&
((isNum(test) && test !== 0) ||
(isString(test) && test.length > 0) ||
(isBoolean(test) && test));
if (testBoolValue) {
return this.visit(node.consequent);
}
if (node.alternate !== null) {
return this.visit(node.alternate);
}
return null;
};
MEvento.prototype.visitLogicalExpressionAST = function (node) {
var leftNode = node.left;
var test = this.visit(leftNode);
var testBoolValue = _boolValue(test);
if (node.operator.type === TokenType.and) {
return testBoolValue && _boolValue(this.visit(node.right));
}
if (node.operator.type === TokenType.or) {
return testBoolValue || _boolValue(this.visit(node.right));
}
return false;
};
MEvento.prototype.visitIndexAccessorAST = function (node) {
var ownerNode = node.owner;
var owner = this.visit(ownerNode);
if (typeof owner === 'object') {
var key = this.visit(node.key);
return owner[key];
}
else if (Array.isArray(owner)) {
var key = this.visit(node.key);
return isNum(key) && owner.length < key && key >= 0 ? owner[key] : null;
}
return null;
};
MEvento.prototype.registerFunction = function (id, fn) {
this._functionsRegistry[id] = fn;
};
MEvento.prototype.unregisterFunction = function (id) {
delete this._functionsRegistry[id];
};
MEvento.prototype.execute = function (source, cache) {
if (cache === void 0) { cache = true; }
var module = MEvento.compile(source, cache);
return this.visit(module);
};
MEvento.compile = function (source, cache) {
if (cache === void 0) { cache = false; }
var hash = hashCode(source);
if (cache && this._cache.has(hash)) {
return this._cache.get(hash);
}
var lexer = new Lexer(source);
var parser = new Parser(lexer);
var module = parser.parse();
if (cache)
this._cache.set(hash, module);
return module;
};
MEvento.register = function (id, fn) {
MEvento._globalFunctionsRegistry[id] = fn;
};
MEvento.unregister = function (id) {
delete MEvento._globalFunctionsRegistry[id];
};
MEvento.run = function (source, cache) {
if (cache === void 0) { cache = false; }
var mevento = new MEvento();
var module = MEvento.compile(source, cache);
return mevento.visit(module);
};
MEvento.newInstance = function () {
// const lexer = Lexer(source);
// const parser = Parser(lexer);
// const module = parser.parse();
return new MEvento();
};
MEvento._globalFunctionsRegistry = {};
MEvento._cache = new Map();
return MEvento;
}(NodeVisitor));
exports.MEvento = MEvento;
var MEventoAsync = /** @class */ (function (_super) {
__extends(MEventoAsync, _super);
function MEventoAsync() {
return _super.call(this) || this;
}
MEventoAsync.prototype.visitRootAST = function (node) {
return __awaiter(this, void 0, void 0, function () {