UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

443 lines 16.6 kB
'use strict';var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc); switch (arguments.length) { case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target); case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0); case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); } }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var decorators_1 = require('angular2/src/core/di/decorators'); var collection_1 = require("angular2/src/facade/collection"); var lang_1 = require("angular2/src/facade/lang"); var exceptions_1 = require('angular2/src/facade/exceptions'); (function (TokenType) { TokenType[TokenType["Character"] = 0] = "Character"; TokenType[TokenType["Identifier"] = 1] = "Identifier"; TokenType[TokenType["Keyword"] = 2] = "Keyword"; TokenType[TokenType["String"] = 3] = "String"; TokenType[TokenType["Operator"] = 4] = "Operator"; TokenType[TokenType["Number"] = 5] = "Number"; })(exports.TokenType || (exports.TokenType = {})); var TokenType = exports.TokenType; var Lexer = (function () { function Lexer() { } Lexer.prototype.tokenize = function (text) { var scanner = new _Scanner(text); var tokens = []; var token = scanner.scanToken(); while (token != null) { tokens.push(token); token = scanner.scanToken(); } return tokens; }; Lexer = __decorate([ decorators_1.Injectable(), __metadata('design:paramtypes', []) ], Lexer); return Lexer; })(); exports.Lexer = Lexer; var Token = (function () { function Token(index, type, numValue, strValue) { this.index = index; this.type = type; this.numValue = numValue; this.strValue = strValue; } Token.prototype.isCharacter = function (code) { return (this.type == TokenType.Character && this.numValue == code); }; Token.prototype.isNumber = function () { return (this.type == TokenType.Number); }; Token.prototype.isString = function () { return (this.type == TokenType.String); }; Token.prototype.isOperator = function (operater) { return (this.type == TokenType.Operator && this.strValue == operater); }; Token.prototype.isIdentifier = function () { return (this.type == TokenType.Identifier); }; Token.prototype.isKeyword = function () { return (this.type == TokenType.Keyword); }; Token.prototype.isKeywordVar = function () { return (this.type == TokenType.Keyword && this.strValue == "var"); }; Token.prototype.isKeywordNull = function () { return (this.type == TokenType.Keyword && this.strValue == "null"); }; Token.prototype.isKeywordUndefined = function () { return (this.type == TokenType.Keyword && this.strValue == "undefined"); }; Token.prototype.isKeywordTrue = function () { return (this.type == TokenType.Keyword && this.strValue == "true"); }; Token.prototype.isKeywordFalse = function () { return (this.type == TokenType.Keyword && this.strValue == "false"); }; Token.prototype.toNumber = function () { // -1 instead of NULL ok? return (this.type == TokenType.Number) ? this.numValue : -1; }; Token.prototype.toString = function () { switch (this.type) { case TokenType.Character: case TokenType.Identifier: case TokenType.Keyword: case TokenType.Operator: case TokenType.String: return this.strValue; case TokenType.Number: return this.numValue.toString(); default: return null; } }; return Token; })(); exports.Token = Token; function newCharacterToken(index, code) { return new Token(index, TokenType.Character, code, lang_1.StringWrapper.fromCharCode(code)); } function newIdentifierToken(index, text) { return new Token(index, TokenType.Identifier, 0, text); } function newKeywordToken(index, text) { return new Token(index, TokenType.Keyword, 0, text); } function newOperatorToken(index, text) { return new Token(index, TokenType.Operator, 0, text); } function newStringToken(index, text) { return new Token(index, TokenType.String, 0, text); } function newNumberToken(index, n) { return new Token(index, TokenType.Number, n, ""); } exports.EOF = new Token(-1, TokenType.Character, 0, ""); exports.$EOF = 0; exports.$TAB = 9; exports.$LF = 10; exports.$VTAB = 11; exports.$FF = 12; exports.$CR = 13; exports.$SPACE = 32; exports.$BANG = 33; exports.$DQ = 34; exports.$HASH = 35; exports.$$ = 36; exports.$PERCENT = 37; exports.$AMPERSAND = 38; exports.$SQ = 39; exports.$LPAREN = 40; exports.$RPAREN = 41; exports.$STAR = 42; exports.$PLUS = 43; exports.$COMMA = 44; exports.$MINUS = 45; exports.$PERIOD = 46; exports.$SLASH = 47; exports.$COLON = 58; exports.$SEMICOLON = 59; exports.$LT = 60; exports.$EQ = 61; exports.$GT = 62; exports.$QUESTION = 63; var $0 = 48; var $9 = 57; var $A = 65, $E = 69, $Z = 90; exports.$LBRACKET = 91; exports.$BACKSLASH = 92; exports.$RBRACKET = 93; var $CARET = 94; var $_ = 95; var $a = 97, $e = 101, $f = 102, $n = 110, $r = 114, $t = 116, $u = 117, $v = 118, $z = 122; exports.$LBRACE = 123; exports.$BAR = 124; exports.$RBRACE = 125; var $NBSP = 160; var ScannerError = (function (_super) { __extends(ScannerError, _super); function ScannerError(message) { _super.call(this); this.message = message; } ScannerError.prototype.toString = function () { return this.message; }; return ScannerError; })(exceptions_1.BaseException); exports.ScannerError = ScannerError; var _Scanner = (function () { function _Scanner(input) { this.input = input; this.peek = 0; this.index = -1; this.length = input.length; this.advance(); } _Scanner.prototype.advance = function () { this.peek = ++this.index >= this.length ? exports.$EOF : lang_1.StringWrapper.charCodeAt(this.input, this.index); }; _Scanner.prototype.scanToken = function () { var input = this.input, length = this.length, peek = this.peek, index = this.index; // Skip whitespace. while (peek <= exports.$SPACE) { if (++index >= length) { peek = exports.$EOF; break; } else { peek = lang_1.StringWrapper.charCodeAt(input, index); } } this.peek = peek; this.index = index; if (index >= length) { return null; } // Handle identifiers and numbers. if (isIdentifierStart(peek)) return this.scanIdentifier(); if (isDigit(peek)) return this.scanNumber(index); var start = index; switch (peek) { case exports.$PERIOD: this.advance(); return isDigit(this.peek) ? this.scanNumber(start) : newCharacterToken(start, exports.$PERIOD); case exports.$LPAREN: case exports.$RPAREN: case exports.$LBRACE: case exports.$RBRACE: case exports.$LBRACKET: case exports.$RBRACKET: case exports.$COMMA: case exports.$COLON: case exports.$SEMICOLON: return this.scanCharacter(start, peek); case exports.$SQ: case exports.$DQ: return this.scanString(); case exports.$HASH: case exports.$PLUS: case exports.$MINUS: case exports.$STAR: case exports.$SLASH: case exports.$PERCENT: case $CARET: return this.scanOperator(start, lang_1.StringWrapper.fromCharCode(peek)); case exports.$QUESTION: return this.scanComplexOperator(start, '?', exports.$PERIOD, '.'); case exports.$LT: case exports.$GT: return this.scanComplexOperator(start, lang_1.StringWrapper.fromCharCode(peek), exports.$EQ, '='); case exports.$BANG: case exports.$EQ: return this.scanComplexOperator(start, lang_1.StringWrapper.fromCharCode(peek), exports.$EQ, '=', exports.$EQ, '='); case exports.$AMPERSAND: return this.scanComplexOperator(start, '&', exports.$AMPERSAND, '&'); case exports.$BAR: return this.scanComplexOperator(start, '|', exports.$BAR, '|'); case $NBSP: while (isWhitespace(this.peek)) this.advance(); return this.scanToken(); } this.error("Unexpected character [" + lang_1.StringWrapper.fromCharCode(peek) + "]", 0); return null; }; _Scanner.prototype.scanCharacter = function (start, code) { assert(this.peek == code); this.advance(); return newCharacterToken(start, code); }; _Scanner.prototype.scanOperator = function (start, str) { assert(this.peek == lang_1.StringWrapper.charCodeAt(str, 0)); assert(collection_1.SetWrapper.has(OPERATORS, str)); this.advance(); return newOperatorToken(start, str); }; /** * Tokenize a 2/3 char long operator * * @param start start index in the expression * @param one first symbol (always part of the operator) * @param twoCode code point for the second symbol * @param two second symbol (part of the operator when the second code point matches) * @param threeCode code point for the third symbol * @param three third symbol (part of the operator when provided and matches source expression) * @returns {Token} */ _Scanner.prototype.scanComplexOperator = function (start, one, twoCode, two, threeCode, three) { assert(this.peek == lang_1.StringWrapper.charCodeAt(one, 0)); this.advance(); var str = one; if (this.peek == twoCode) { this.advance(); str += two; } if (lang_1.isPresent(threeCode) && this.peek == threeCode) { this.advance(); str += three; } assert(collection_1.SetWrapper.has(OPERATORS, str)); return newOperatorToken(start, str); }; _Scanner.prototype.scanIdentifier = function () { assert(isIdentifierStart(this.peek)); var start = this.index; this.advance(); while (isIdentifierPart(this.peek)) this.advance(); var str = this.input.substring(start, this.index); if (collection_1.SetWrapper.has(KEYWORDS, str)) { return newKeywordToken(start, str); } else { return newIdentifierToken(start, str); } }; _Scanner.prototype.scanNumber = function (start) { assert(isDigit(this.peek)); var simple = (this.index === start); this.advance(); // Skip initial digit. while (true) { if (isDigit(this.peek)) { } else if (this.peek == exports.$PERIOD) { simple = false; } else if (isExponentStart(this.peek)) { this.advance(); if (isExponentSign(this.peek)) this.advance(); if (!isDigit(this.peek)) this.error('Invalid exponent', -1); simple = false; } else { break; } this.advance(); } var str = this.input.substring(start, this.index); // TODO var value = simple ? lang_1.NumberWrapper.parseIntAutoRadix(str) : lang_1.NumberWrapper.parseFloat(str); return newNumberToken(start, value); }; _Scanner.prototype.scanString = function () { assert(this.peek == exports.$SQ || this.peek == exports.$DQ); var start = this.index; var quote = this.peek; this.advance(); // Skip initial quote. var buffer; var marker = this.index; var input = this.input; while (this.peek != quote) { if (this.peek == exports.$BACKSLASH) { if (buffer == null) buffer = new lang_1.StringJoiner(); buffer.add(input.substring(marker, this.index)); this.advance(); var unescapedCode; if (this.peek == $u) { // 4 character hex code for unicode character. var hex = input.substring(this.index + 1, this.index + 5); try { unescapedCode = lang_1.NumberWrapper.parseInt(hex, 16); } catch (e) { this.error("Invalid unicode escape [\\u" + hex + "]", 0); } for (var i = 0; i < 5; i++) { this.advance(); } } else { unescapedCode = unescape(this.peek); this.advance(); } buffer.add(lang_1.StringWrapper.fromCharCode(unescapedCode)); marker = this.index; } else if (this.peek == exports.$EOF) { this.error('Unterminated quote', 0); } else { this.advance(); } } var last = input.substring(marker, this.index); this.advance(); // Skip terminating quote. // Compute the unescaped string value. var unescaped = last; if (buffer != null) { buffer.add(last); unescaped = buffer.toString(); } return newStringToken(start, unescaped); }; _Scanner.prototype.error = function (message, offset) { var position = this.index + offset; throw new ScannerError("Lexer Error: " + message + " at column " + position + " in expression [" + this.input + "]"); }; return _Scanner; })(); function isWhitespace(code) { return (code >= exports.$TAB && code <= exports.$SPACE) || (code == $NBSP); } function isIdentifierStart(code) { return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || (code == $_) || (code == exports.$$); } function isIdentifierPart(code) { return ($a <= code && code <= $z) || ($A <= code && code <= $Z) || ($0 <= code && code <= $9) || (code == $_) || (code == exports.$$); } function isDigit(code) { return $0 <= code && code <= $9; } function isExponentStart(code) { return code == $e || code == $E; } function isExponentSign(code) { return code == exports.$MINUS || code == exports.$PLUS; } function unescape(code) { switch (code) { case $n: return exports.$LF; case $f: return exports.$FF; case $r: return exports.$CR; case $t: return exports.$TAB; case $v: return exports.$VTAB; default: return code; } } var OPERATORS = collection_1.SetWrapper.createFromList([ '+', '-', '*', '/', '%', '^', '=', '==', '!=', '===', '!==', '<', '>', '<=', '>=', '&&', '||', '&', '|', '!', '?', '#', '?.' ]); var KEYWORDS = collection_1.SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false', 'if', 'else']); //# sourceMappingURL=lexer.js.map