Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: sky/framework/sky-element/third_party/esprima/esprima.sky

Issue 698653002: Add initial SkyElement & city-list example (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: moar cleanup Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sky/framework/sky-element/third_party/esprima/esprima.sky
diff --git a/sky/framework/sky-element/third_party/esprima/esprima.sky b/sky/framework/sky-element/third_party/esprima/esprima.sky
new file mode 100644
index 0000000000000000000000000000000000000000..0ac5dedc9a98f23c157bbfa67bd04d2489081aba
--- /dev/null
+++ b/sky/framework/sky-element/third_party/esprima/esprima.sky
@@ -0,0 +1,1042 @@
+<script>
+
+/*
+ Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
+ Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
+ Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
+ Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
+ Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
+ Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
+ Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
+ Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
+ Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+var Token,
+ TokenName,
+ Syntax,
+ Messages,
+ source,
+ index,
+ length,
+ delegate,
+ lookahead,
+ state;
+
+Token = {
+ BooleanLiteral: 1,
+ EOF: 2,
+ Identifier: 3,
+ Keyword: 4,
+ NullLiteral: 5,
+ NumericLiteral: 6,
+ Punctuator: 7,
+ StringLiteral: 8
+};
+
+TokenName = {};
+TokenName[Token.BooleanLiteral] = 'Boolean';
+TokenName[Token.EOF] = '<end>';
+TokenName[Token.Identifier] = 'Identifier';
+TokenName[Token.Keyword] = 'Keyword';
+TokenName[Token.NullLiteral] = 'Null';
+TokenName[Token.NumericLiteral] = 'Numeric';
+TokenName[Token.Punctuator] = 'Punctuator';
+TokenName[Token.StringLiteral] = 'String';
+
+Syntax = {
+ ArrayExpression: 'ArrayExpression',
+ BinaryExpression: 'BinaryExpression',
+ CallExpression: 'CallExpression',
+ ConditionalExpression: 'ConditionalExpression',
+ EmptyStatement: 'EmptyStatement',
+ ExpressionStatement: 'ExpressionStatement',
+ Identifier: 'Identifier',
+ Literal: 'Literal',
+ LabeledStatement: 'LabeledStatement',
+ LogicalExpression: 'LogicalExpression',
+ MemberExpression: 'MemberExpression',
+ ObjectExpression: 'ObjectExpression',
+ Program: 'Program',
+ Property: 'Property',
+ ThisExpression: 'ThisExpression',
+ UnaryExpression: 'UnaryExpression'
+};
+
+// Error messages should be identical to V8.
+Messages = {
+ UnexpectedToken: 'Unexpected token %0',
+ UnknownLabel: 'Undefined label \'%0\'',
+ Redeclaration: '%0 \'%1\' has already been declared'
+};
+
+// Ensure the condition is true, otherwise throw an error.
+// This is only to have a better contract semantic, i.e. another safety net
+// to catch a logic error. The condition shall be fulfilled in normal case.
+// Do NOT use this to enforce a certain condition on any user input.
+
+function assert(condition, message) {
+ if (!condition) {
+ throw new Error('ASSERT: ' + message);
+ }
+}
+
+function isDecimalDigit(ch) {
+ return (ch >= 48 && ch <= 57); // 0..9
+}
+
+
+// 7.2 White Space
+
+function isWhiteSpace(ch) {
+ return (ch === 32) || // space
+ (ch === 9) || // tab
+ (ch === 0xB) ||
+ (ch === 0xC) ||
+ (ch === 0xA0) ||
+ (ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);
+}
+
+// 7.3 Line Terminators
+
+function isLineTerminator(ch) {
+ return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);
+}
+
+// 7.6 Identifier Names and Identifiers
+
+function isIdentifierStart(ch) {
+ return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch >= 97 && ch <= 122); // a..z
+}
+
+function isIdentifierPart(ch) {
+ return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore)
+ (ch >= 65 && ch <= 90) || // A..Z
+ (ch >= 97 && ch <= 122) || // a..z
+ (ch >= 48 && ch <= 57); // 0..9
+}
+
+// 7.6.1.1 Keywords
+
+function isKeyword(id) {
+ return (id === 'this')
+}
+
+// 7.4 Comments
+
+function skipWhitespace() {
+ while (index < length && isWhiteSpace(source.charCodeAt(index))) {
+ ++index;
+ }
+}
+
+function getIdentifier() {
+ var start, ch;
+
+ start = index++;
+ while (index < length) {
+ ch = source.charCodeAt(index);
+ if (isIdentifierPart(ch)) {
+ ++index;
+ } else {
+ break;
+ }
+ }
+
+ return source.slice(start, index);
+}
+
+function scanIdentifier() {
+ var start, id, type;
+
+ start = index;
+
+ id = getIdentifier();
+
+ // There is no keyword or literal with only one character.
+ // Thus, it must be an identifier.
+ if (id.length === 1) {
+ type = Token.Identifier;
+ } else if (isKeyword(id)) {
+ type = Token.Keyword;
+ } else if (id === 'null') {
+ type = Token.NullLiteral;
+ } else if (id === 'true' || id === 'false') {
+ type = Token.BooleanLiteral;
+ } else {
+ type = Token.Identifier;
+ }
+
+ return {
+ type: type,
+ value: id,
+ range: [start, index]
+ };
+}
+
+
+// 7.7 Punctuators
+
+function scanPunctuator() {
+ var start = index,
+ code = source.charCodeAt(index),
+ code2,
+ ch1 = source[index],
+ ch2;
+
+ switch (code) {
+
+ // Check for most common single-character punctuators.
+ case 46: // . dot
+ case 40: // ( open bracket
+ case 41: // ) close bracket
+ case 59: // ; semicolon
+ case 44: // , comma
+ case 123: // { open curly brace
+ case 125: // } close curly brace
+ case 91: // [
+ case 93: // ]
+ case 58: // :
+ case 63: // ?
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: String.fromCharCode(code),
+ range: [start, index]
+ };
+
+ default:
+ code2 = source.charCodeAt(index + 1);
+
+ // '=' (char #61) marks an assignment or comparison operator.
+ if (code2 === 61) {
+ switch (code) {
+ case 37: // %
+ case 38: // &
+ case 42: // *:
+ case 43: // +
+ case 45: // -
+ case 47: // /
+ case 60: // <
+ case 62: // >
+ case 124: // |
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: String.fromCharCode(code) + String.fromCharCode(code2),
+ range: [start, index]
+ };
+
+ case 33: // !
+ case 61: // =
+ index += 2;
+
+ // !== and ===
+ if (source.charCodeAt(index) === 61) {
+ ++index;
+ }
+ return {
+ type: Token.Punctuator,
+ value: source.slice(start, index),
+ range: [start, index]
+ };
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ // Peek more characters.
+
+ ch2 = source[index + 1];
+
+ // Other 2-character punctuators: && ||
+
+ if (ch1 === ch2 && ('&|'.indexOf(ch1) >= 0)) {
+ index += 2;
+ return {
+ type: Token.Punctuator,
+ value: ch1 + ch2,
+ range: [start, index]
+ };
+ }
+
+ if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
+ ++index;
+ return {
+ type: Token.Punctuator,
+ value: ch1,
+ range: [start, index]
+ };
+ }
+
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+}
+
+// 7.8.3 Numeric Literals
+function scanNumericLiteral() {
+ var number, start, ch;
+
+ ch = source[index];
+ assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
+ 'Numeric literal must start with a decimal digit or a decimal point');
+
+ start = index;
+ number = '';
+ if (ch !== '.') {
+ number = source[index++];
+ ch = source[index];
+
+ // Hex number starts with '0x'.
+ // Octal number starts with '0'.
+ if (number === '0') {
+ // decimal number starts with '0' such as '09' is illegal.
+ if (ch && isDecimalDigit(ch.charCodeAt(0))) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === '.') {
+ number += source[index++];
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ ch = source[index];
+ }
+
+ if (ch === 'e' || ch === 'E') {
+ number += source[index++];
+
+ ch = source[index];
+ if (ch === '+' || ch === '-') {
+ number += source[index++];
+ }
+ if (isDecimalDigit(source.charCodeAt(index))) {
+ while (isDecimalDigit(source.charCodeAt(index))) {
+ number += source[index++];
+ }
+ } else {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+ }
+
+ if (isIdentifierStart(source.charCodeAt(index))) {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+
+ return {
+ type: Token.NumericLiteral,
+ value: parseFloat(number),
+ range: [start, index]
+ };
+}
+
+// 7.8.4 String Literals
+
+function scanStringLiteral() {
+ var str = '', quote, start, ch, octal = false;
+
+ quote = source[index];
+ assert((quote === '\'' || quote === '"'),
+ 'String literal must starts with a quote');
+
+ start = index;
+ ++index;
+
+ while (index < length) {
+ ch = source[index++];
+
+ if (ch === quote) {
+ quote = '';
+ break;
+ } else if (ch === '\\') {
+ ch = source[index++];
+ if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
+ switch (ch) {
+ case 'n':
+ str += '\n';
+ break;
+ case 'r':
+ str += '\r';
+ break;
+ case 't':
+ str += '\t';
+ break;
+ case 'b':
+ str += '\b';
+ break;
+ case 'f':
+ str += '\f';
+ break;
+ case 'v':
+ str += '\x0B';
+ break;
+
+ default:
+ str += ch;
+ break;
+ }
+ } else {
+ if (ch === '\r' && source[index] === '\n') {
+ ++index;
+ }
+ }
+ } else if (isLineTerminator(ch.charCodeAt(0))) {
+ break;
+ } else {
+ str += ch;
+ }
+ }
+
+ if (quote !== '') {
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+ }
+
+ return {
+ type: Token.StringLiteral,
+ value: str,
+ octal: octal,
+ range: [start, index]
+ };
+}
+
+function isIdentifierName(token) {
+ return token.type === Token.Identifier ||
+ token.type === Token.Keyword ||
+ token.type === Token.BooleanLiteral ||
+ token.type === Token.NullLiteral;
+}
+
+function advance() {
+ var ch;
+
+ skipWhitespace();
+
+ if (index >= length) {
+ return {
+ type: Token.EOF,
+ range: [index, index]
+ };
+ }
+
+ ch = source.charCodeAt(index);
+
+ // Very common: ( and ) and ;
+ if (ch === 40 || ch === 41 || ch === 58) {
+ return scanPunctuator();
+ }
+
+ // String literal starts with single quote (#39) or double quote (#34).
+ if (ch === 39 || ch === 34) {
+ return scanStringLiteral();
+ }
+
+ if (isIdentifierStart(ch)) {
+ return scanIdentifier();
+ }
+
+ // Dot (.) char #46 can also start a floating-point number, hence the need
+ // to check the next character.
+ if (ch === 46) {
+ if (isDecimalDigit(source.charCodeAt(index + 1))) {
+ return scanNumericLiteral();
+ }
+ return scanPunctuator();
+ }
+
+ if (isDecimalDigit(ch)) {
+ return scanNumericLiteral();
+ }
+
+ return scanPunctuator();
+}
+
+function lex() {
+ var token;
+
+ token = lookahead;
+ index = token.range[1];
+
+ lookahead = advance();
+
+ index = token.range[1];
+
+ return token;
+}
+
+function peek() {
+ var pos;
+
+ pos = index;
+ lookahead = advance();
+ index = pos;
+}
+
+// Throw an exception
+
+function throwError(token, messageFormat) {
+ var error,
+ args = Array.prototype.slice.call(arguments, 2),
+ msg = messageFormat.replace(
+ /%(\d)/g,
+ function (whole, index) {
+ assert(index < args.length, 'Message reference must be in range');
+ return args[index];
+ }
+ );
+
+ error = new Error(msg);
+ error.index = index;
+ error.description = msg;
+ throw error;
+}
+
+// Throw an exception because of the token.
+
+function throwUnexpected(token) {
+ throwError(token, Messages.UnexpectedToken, token.value);
+}
+
+// Expect the next token to match the specified punctuator.
+// If not, an exception will be thrown.
+
+function expect(value) {
+ var token = lex();
+ if (token.type !== Token.Punctuator || token.value !== value) {
+ throwUnexpected(token);
+ }
+}
+
+// Return true if the next token matches the specified punctuator.
+
+function match(value) {
+ return lookahead.type === Token.Punctuator && lookahead.value === value;
+}
+
+// Return true if the next token matches the specified keyword
+
+function matchKeyword(keyword) {
+ return lookahead.type === Token.Keyword && lookahead.value === keyword;
+}
+
+function consumeSemicolon() {
+ // Catch the very common case first: immediately a semicolon (char #59).
+ if (source.charCodeAt(index) === 59) {
+ lex();
+ return;
+ }
+
+ skipWhitespace();
+
+ if (match(';')) {
+ lex();
+ return;
+ }
+
+ if (lookahead.type !== Token.EOF && !match('}')) {
+ throwUnexpected(lookahead);
+ }
+}
+
+// 11.1.4 Array Initialiser
+
+function parseArrayInitialiser() {
+ var elements = [];
+
+ expect('[');
+
+ while (!match(']')) {
+ if (match(',')) {
+ lex();
+ elements.push(null);
+ } else {
+ elements.push(parseExpression());
+
+ if (!match(']')) {
+ expect(',');
+ }
+ }
+ }
+
+ expect(']');
+
+ return delegate.createArrayExpression(elements);
+}
+
+// 11.1.5 Object Initialiser
+
+function parseObjectPropertyKey() {
+ var token;
+
+ skipWhitespace();
+ token = lex();
+
+ // Note: This function is called only from parseObjectProperty(), where
+ // EOF and Punctuator tokens are already filtered out.
+ if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
+ return delegate.createLiteral(token);
+ }
+
+ return delegate.createIdentifier(token.value);
+}
+
+function parseObjectProperty() {
+ var token, key;
+
+ token = lookahead;
+ skipWhitespace();
+
+ if (token.type === Token.EOF || token.type === Token.Punctuator) {
+ throwUnexpected(token);
+ }
+
+ key = parseObjectPropertyKey();
+ expect(':');
+ return delegate.createProperty('init', key, parseExpression());
+}
+
+function parseObjectInitialiser() {
+ var properties = [];
+
+ expect('{');
+
+ while (!match('}')) {
+ properties.push(parseObjectProperty());
+
+ if (!match('}')) {
+ expect(',');
+ }
+ }
+
+ expect('}');
+
+ return delegate.createObjectExpression(properties);
+}
+
+// 11.1.6 The Grouping Operator
+
+function parseGroupExpression() {
+ var expr;
+
+ expect('(');
+
+ expr = parseExpression();
+
+ expect(')');
+
+ return expr;
+}
+
+
+// 11.1 Primary Expressions
+
+function parsePrimaryExpression() {
+ var type, token, expr;
+
+ if (match('(')) {
+ return parseGroupExpression();
+ }
+
+ type = lookahead.type;
+
+ if (type === Token.Identifier) {
+ expr = delegate.createIdentifier(lex().value);
+ } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
+ expr = delegate.createLiteral(lex());
+ } else if (type === Token.Keyword) {
+ if (matchKeyword('this')) {
+ lex();
+ expr = delegate.createThisExpression();
+ }
+ } else if (type === Token.BooleanLiteral) {
+ token = lex();
+ token.value = (token.value === 'true');
+ expr = delegate.createLiteral(token);
+ } else if (type === Token.NullLiteral) {
+ token = lex();
+ token.value = null;
+ expr = delegate.createLiteral(token);
+ } else if (match('[')) {
+ expr = parseArrayInitialiser();
+ } else if (match('{')) {
+ expr = parseObjectInitialiser();
+ }
+
+ if (expr) {
+ return expr;
+ }
+
+ throwUnexpected(lex());
+}
+
+// 11.2 Left-Hand-Side Expressions
+
+function parseArguments() {
+ var args = [];
+
+ expect('(');
+
+ if (!match(')')) {
+ while (index < length) {
+ args.push(parseExpression());
+ if (match(')')) {
+ break;
+ }
+ expect(',');
+ }
+ }
+
+ expect(')');
+
+ return args;
+}
+
+function parseNonComputedProperty() {
+ var token;
+
+ token = lex();
+
+ if (!isIdentifierName(token)) {
+ throwUnexpected(token);
+ }
+
+ return delegate.createIdentifier(token.value);
+}
+
+function parseNonComputedMember() {
+ expect('.');
+
+ return parseNonComputedProperty();
+}
+
+function parseComputedMember() {
+ var expr;
+
+ expect('[');
+
+ expr = parseExpression();
+
+ expect(']');
+
+ return expr;
+}
+
+function parseLeftHandSideExpression() {
+ var expr, args, property;
+
+ expr = parsePrimaryExpression();
+
+ while (true) {
+ if (match('[')) {
+ property = parseComputedMember();
+ expr = delegate.createMemberExpression('[', expr, property);
+ } else if (match('.')) {
+ property = parseNonComputedMember();
+ expr = delegate.createMemberExpression('.', expr, property);
+ } else if (match('(')) {
+ args = parseArguments();
+ expr = delegate.createCallExpression(expr, args);
+ } else {
+ break;
+ }
+ }
+
+ return expr;
+}
+
+// 11.3 Postfix Expressions
+
+var parsePostfixExpression = parseLeftHandSideExpression;
+
+// 11.4 Unary Operators
+
+function parseUnaryExpression() {
+ var token, expr;
+
+ if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
+ expr = parsePostfixExpression();
+ } else if (match('+') || match('-') || match('!')) {
+ token = lex();
+ expr = parseUnaryExpression();
+ expr = delegate.createUnaryExpression(token.value, expr);
+ } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
+ throwError({}, Messages.UnexpectedToken);
+ } else {
+ expr = parsePostfixExpression();
+ }
+
+ return expr;
+}
+
+function binaryPrecedence(token) {
+ var prec = 0;
+
+ if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
+ return 0;
+ }
+
+ switch (token.value) {
+ case '||':
+ prec = 1;
+ break;
+
+ case '&&':
+ prec = 2;
+ break;
+
+ case '==':
+ case '!=':
+ case '===':
+ case '!==':
+ prec = 6;
+ break;
+
+ case '<':
+ case '>':
+ case '<=':
+ case '>=':
+ case 'instanceof':
+ prec = 7;
+ break;
+
+ case 'in':
+ prec = 7;
+ break;
+
+ case '+':
+ case '-':
+ prec = 9;
+ break;
+
+ case '*':
+ case '/':
+ case '%':
+ prec = 11;
+ break;
+
+ default:
+ break;
+ }
+
+ return prec;
+}
+
+// 11.5 Multiplicative Operators
+// 11.6 Additive Operators
+// 11.7 Bitwise Shift Operators
+// 11.8 Relational Operators
+// 11.9 Equality Operators
+// 11.10 Binary Bitwise Operators
+// 11.11 Binary Logical Operators
+
+function parseBinaryExpression() {
+ var expr, token, prec, stack, right, operator, left, i;
+
+ left = parseUnaryExpression();
+
+ token = lookahead;
+ prec = binaryPrecedence(token);
+ if (prec === 0) {
+ return left;
+ }
+ token.prec = prec;
+ lex();
+
+ right = parseUnaryExpression();
+
+ stack = [left, token, right];
+
+ while ((prec = binaryPrecedence(lookahead)) > 0) {
+
+ // Reduce: make a binary expression from the three topmost entries.
+ while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
+ right = stack.pop();
+ operator = stack.pop().value;
+ left = stack.pop();
+ expr = delegate.createBinaryExpression(operator, left, right);
+ stack.push(expr);
+ }
+
+ // Shift.
+ token = lex();
+ token.prec = prec;
+ stack.push(token);
+ expr = parseUnaryExpression();
+ stack.push(expr);
+ }
+
+ // Final reduce to clean-up the stack.
+ i = stack.length - 1;
+ expr = stack[i];
+ while (i > 1) {
+ expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
+ i -= 2;
+ }
+
+ return expr;
+}
+
+
+// 11.12 Conditional Operator
+
+function parseConditionalExpression() {
+ var expr, consequent, alternate;
+
+ expr = parseBinaryExpression();
+
+ if (match('?')) {
+ lex();
+ consequent = parseConditionalExpression();
+ expect(':');
+ alternate = parseConditionalExpression();
+
+ expr = delegate.createConditionalExpression(expr, consequent, alternate);
+ }
+
+ return expr;
+}
+
+// Simplification since we do not support AssignmentExpression.
+var parseExpression = parseConditionalExpression;
+
+// Polymer Syntax extensions
+
+// Filter ::
+// Identifier
+// Identifier "(" ")"
+// Identifier "(" FilterArguments ")"
+
+function parseFilter() {
+ var identifier, args;
+
+ identifier = lex();
+
+ if (identifier.type !== Token.Identifier) {
+ throwUnexpected(identifier);
+ }
+
+ args = match('(') ? parseArguments() : [];
+
+ return delegate.createFilter(identifier.value, args);
+}
+
+// Filters ::
+// "|" Filter
+// Filters "|" Filter
+
+function parseFilters() {
+ while (match('|')) {
+ lex();
+ parseFilter();
+ }
+}
+
+// TopLevel ::
+// LabelledExpressions
+// AsExpression
+// InExpression
+// FilterExpression
+
+// AsExpression ::
+// FilterExpression as Identifier
+
+// InExpression ::
+// Identifier, Identifier in FilterExpression
+// Identifier in FilterExpression
+
+// FilterExpression ::
+// Expression
+// Expression Filters
+
+function parseTopLevel() {
+ skipWhitespace();
+ peek();
+
+ var expr = parseExpression();
+ if (expr) {
+ if (lookahead.value === ',' || lookahead.value == 'in' &&
+ expr.type === Syntax.Identifier) {
+ parseInExpression(expr);
+ } else {
+ parseFilters();
+ if (lookahead.value === 'as') {
+ parseAsExpression(expr);
+ } else {
+ delegate.createTopLevel(expr);
+ }
+ }
+ }
+
+ if (lookahead.type !== Token.EOF) {
+ throwUnexpected(lookahead);
+ }
+}
+
+function parseAsExpression(expr) {
+ lex(); // as
+ var identifier = lex().value;
+ delegate.createAsExpression(expr, identifier);
+}
+
+function parseInExpression(identifier) {
+ var indexName;
+ if (lookahead.value === ',') {
+ lex();
+ if (lookahead.type !== Token.Identifier)
+ throwUnexpected(lookahead);
+ indexName = lex().value;
+ }
+
+ lex(); // in
+ var expr = parseExpression();
+ parseFilters();
+ delegate.createInExpression(identifier.name, indexName, expr);
+}
+
+function parse(code, inDelegate) {
+ delegate = inDelegate;
+ source = code;
+ index = 0;
+ length = source.length;
+ lookahead = null;
+ state = {
+ labelSet: {}
+ };
+
+ return parseTopLevel();
+}
+
+module.exports = {
+ parse: parse
+};
+
+</script>
« sky/examples/city-list/city-list.sky ('K') | « sky/framework/sky-element/sky-element.sky ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698