mirror of https://github.com/morpheus65535/bazarr
3210 lines
105 KiB
Python
3210 lines
105 KiB
Python
# JUST FOR NOW, later I will write my own - much faster and better.
|
|
|
|
# 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.
|
|
|
|
# -*- coding: latin-1 -*-
|
|
from __future__ import print_function
|
|
import re
|
|
|
|
|
|
def typeof(t):
|
|
if t is None: return 'undefined'
|
|
elif isinstance(t, bool): return 'boolean'
|
|
elif isinstance(t, str): return 'string'
|
|
elif isinstance(t, int) or isinstance(t, float): return 'number'
|
|
elif hasattr(t, '__call__'): return 'function'
|
|
else: return 'object'
|
|
|
|
|
|
def list_indexOf(l, v):
|
|
try:
|
|
return l.index(v)
|
|
except:
|
|
return -1
|
|
|
|
|
|
parseFloat = float
|
|
parseInt = int
|
|
|
|
|
|
class jsdict(object):
|
|
def __init__(self, d):
|
|
self.__dict__.update(d)
|
|
|
|
def __getitem__(self, name):
|
|
if name in self.__dict__:
|
|
return self.__dict__[name]
|
|
else:
|
|
return None
|
|
|
|
def __setitem__(self, name, value):
|
|
self.__dict__[name] = value
|
|
return value
|
|
|
|
def __getattr__(self, name):
|
|
try:
|
|
return getattr(self, name)
|
|
except:
|
|
return None
|
|
|
|
def __setattr__(self, name, value):
|
|
self[name] = value
|
|
return value
|
|
|
|
def __contains__(self, name):
|
|
return name in self.__dict__
|
|
|
|
def __repr__(self):
|
|
return str(self.__dict__)
|
|
|
|
|
|
class RegExp(object):
|
|
def __init__(self, pattern, flags=''):
|
|
self.flags = flags
|
|
pyflags = 0 | re.M if 'm' in flags else 0 | re.I if 'i' in flags else 0
|
|
self.source = pattern
|
|
self.pattern = re.compile(pattern, pyflags)
|
|
|
|
def test(self, s):
|
|
return self.pattern.search(s) is not None
|
|
|
|
|
|
console = jsdict({"log": print})
|
|
|
|
|
|
def __temp__42(object=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.WithStatement,
|
|
"object": object,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__41(test=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.WhileStatement,
|
|
"test": test,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__40(id=None, init=None):
|
|
return jsdict({
|
|
"type": Syntax.VariableDeclarator,
|
|
"id": id,
|
|
"init": init,
|
|
})
|
|
|
|
|
|
def __temp__39(declarations=None, kind=None):
|
|
return jsdict({
|
|
"type": Syntax.VariableDeclaration,
|
|
"declarations": declarations,
|
|
"kind": kind,
|
|
})
|
|
|
|
|
|
def __temp__38(operator=None, argument=None):
|
|
if (operator == "++") or (operator == "--"):
|
|
return jsdict({
|
|
"type": Syntax.UpdateExpression,
|
|
"operator": operator,
|
|
"argument": argument,
|
|
"prefix": True,
|
|
})
|
|
return jsdict({
|
|
"type": Syntax.UnaryExpression,
|
|
"operator": operator,
|
|
"argument": argument,
|
|
"prefix": True,
|
|
})
|
|
|
|
|
|
def __temp__37(block=None, guardedHandlers=None, handlers=None,
|
|
finalizer=None):
|
|
return jsdict({
|
|
"type": Syntax.TryStatement,
|
|
"block": block,
|
|
"guardedHandlers": guardedHandlers,
|
|
"handlers": handlers,
|
|
"finalizer": finalizer,
|
|
})
|
|
|
|
|
|
def __temp__36(argument=None):
|
|
return jsdict({
|
|
"type": Syntax.ThrowStatement,
|
|
"argument": argument,
|
|
})
|
|
|
|
|
|
def __temp__35():
|
|
return jsdict({
|
|
"type": Syntax.ThisExpression,
|
|
})
|
|
|
|
|
|
def __temp__34(discriminant=None, cases=None):
|
|
return jsdict({
|
|
"type": Syntax.SwitchStatement,
|
|
"discriminant": discriminant,
|
|
"cases": cases,
|
|
})
|
|
|
|
|
|
def __temp__33(test=None, consequent=None):
|
|
return jsdict({
|
|
"type": Syntax.SwitchCase,
|
|
"test": test,
|
|
"consequent": consequent,
|
|
})
|
|
|
|
|
|
def __temp__32(expressions=None):
|
|
return jsdict({
|
|
"type": Syntax.SequenceExpression,
|
|
"expressions": expressions,
|
|
})
|
|
|
|
|
|
def __temp__31(argument=None):
|
|
return jsdict({
|
|
"type": Syntax.ReturnStatement,
|
|
"argument": argument,
|
|
})
|
|
|
|
|
|
def __temp__30(kind=None, key=None, value=None):
|
|
return jsdict({
|
|
"type": Syntax.Property,
|
|
"key": key,
|
|
"value": value,
|
|
"kind": kind,
|
|
})
|
|
|
|
|
|
def __temp__29(body=None):
|
|
return jsdict({
|
|
"type": Syntax.Program,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__28(operator=None, argument=None):
|
|
return jsdict({
|
|
"type": Syntax.UpdateExpression,
|
|
"operator": operator,
|
|
"argument": argument,
|
|
"prefix": False,
|
|
})
|
|
|
|
|
|
def __temp__27(properties=None):
|
|
return jsdict({
|
|
"type": Syntax.ObjectExpression,
|
|
"properties": properties,
|
|
})
|
|
|
|
|
|
def __temp__26(callee=None, args=None):
|
|
return jsdict({
|
|
"type": Syntax.NewExpression,
|
|
"callee": callee,
|
|
"arguments": args,
|
|
})
|
|
|
|
|
|
def __temp__25(accessor=None, object=None, property=None):
|
|
return jsdict({
|
|
"type": Syntax.MemberExpression,
|
|
"computed": accessor == "[",
|
|
"object": object,
|
|
"property": property,
|
|
})
|
|
|
|
|
|
def __temp__24(token=None):
|
|
return jsdict({
|
|
"type": Syntax.Literal,
|
|
"value": token.value,
|
|
"raw": source[token.range[0]:token.range[1]],
|
|
})
|
|
|
|
|
|
def __temp__23(label=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.LabeledStatement,
|
|
"label": label,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__22(test=None, consequent=None, alternate=None):
|
|
return jsdict({
|
|
"type": Syntax.IfStatement,
|
|
"test": test,
|
|
"consequent": consequent,
|
|
"alternate": alternate,
|
|
})
|
|
|
|
|
|
def __temp__21(name=None):
|
|
return jsdict({
|
|
"type": Syntax.Identifier,
|
|
"name": name,
|
|
})
|
|
|
|
|
|
def __temp__20(id=None, params=None, defaults=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.FunctionExpression,
|
|
"id": id,
|
|
"params": params,
|
|
"defaults": defaults,
|
|
"body": body,
|
|
"rest": None,
|
|
"generator": False,
|
|
"expression": False,
|
|
})
|
|
|
|
|
|
def __temp__19(id=None, params=None, defaults=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.FunctionDeclaration,
|
|
"id": id,
|
|
"params": params,
|
|
"defaults": defaults,
|
|
"body": body,
|
|
"rest": None,
|
|
"generator": False,
|
|
"expression": False,
|
|
})
|
|
|
|
|
|
def __temp__18(left=None, right=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.ForInStatement,
|
|
"left": left,
|
|
"right": right,
|
|
"body": body,
|
|
"each": False,
|
|
})
|
|
|
|
|
|
def __temp__17(init=None, test=None, update=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.ForStatement,
|
|
"init": init,
|
|
"test": test,
|
|
"update": update,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__16(expression=None):
|
|
return jsdict({
|
|
"type": Syntax.ExpressionStatement,
|
|
"expression": expression,
|
|
})
|
|
|
|
|
|
def __temp__15():
|
|
return jsdict({
|
|
"type": Syntax.EmptyStatement,
|
|
})
|
|
|
|
|
|
def __temp__14(body=None, test=None):
|
|
return jsdict({
|
|
"type": Syntax.DoWhileStatement,
|
|
"body": body,
|
|
"test": test,
|
|
})
|
|
|
|
|
|
def __temp__13():
|
|
return jsdict({
|
|
"type": Syntax.DebuggerStatement,
|
|
})
|
|
|
|
|
|
def __temp__12(label=None):
|
|
return jsdict({
|
|
"type": Syntax.ContinueStatement,
|
|
"label": label,
|
|
})
|
|
|
|
|
|
def __temp__11(test=None, consequent=None, alternate=None):
|
|
return jsdict({
|
|
"type": Syntax.ConditionalExpression,
|
|
"test": test,
|
|
"consequent": consequent,
|
|
"alternate": alternate,
|
|
})
|
|
|
|
|
|
def __temp__10(param=None, body=None):
|
|
return jsdict({
|
|
"type": Syntax.CatchClause,
|
|
"param": param,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__9(callee=None, args=None):
|
|
return jsdict({
|
|
"type": Syntax.CallExpression,
|
|
"callee": callee,
|
|
"arguments": args,
|
|
})
|
|
|
|
|
|
def __temp__8(label=None):
|
|
return jsdict({
|
|
"type": Syntax.BreakStatement,
|
|
"label": label,
|
|
})
|
|
|
|
|
|
def __temp__7(body=None):
|
|
return jsdict({
|
|
"type": Syntax.BlockStatement,
|
|
"body": body,
|
|
})
|
|
|
|
|
|
def __temp__6(operator=None, left=None, right=None):
|
|
type = (Syntax.LogicalExpression if (operator == "||") or
|
|
(operator == "&&") else Syntax.BinaryExpression)
|
|
return jsdict({
|
|
"type": type,
|
|
"operator": operator,
|
|
"left": left,
|
|
"right": right,
|
|
})
|
|
|
|
|
|
def __temp__5(operator=None, left=None, right=None):
|
|
return jsdict({
|
|
"type": Syntax.AssignmentExpression,
|
|
"operator": operator,
|
|
"left": left,
|
|
"right": right,
|
|
})
|
|
|
|
|
|
def __temp__4(elements=None):
|
|
return jsdict({
|
|
"type": Syntax.ArrayExpression,
|
|
"elements": elements,
|
|
})
|
|
|
|
|
|
def __temp__3(node=None):
|
|
if extra.source:
|
|
node.loc.source = extra.source
|
|
return node
|
|
|
|
|
|
def __temp__2(node=None):
|
|
if node.range or node.loc:
|
|
if extra.loc:
|
|
state.markerStack.pop()
|
|
state.markerStack.pop()
|
|
if extra.range:
|
|
state.markerStack.pop()
|
|
else:
|
|
SyntaxTreeDelegate.markEnd(node)
|
|
return node
|
|
|
|
|
|
def __temp__1(node=None):
|
|
if extra.range:
|
|
node.range = [state.markerStack.pop(), index]
|
|
if extra.loc:
|
|
node.loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": state.markerStack.pop(),
|
|
"column": state.markerStack.pop(),
|
|
}),
|
|
"end":
|
|
jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
}),
|
|
})
|
|
SyntaxTreeDelegate.postProcess(node)
|
|
return node
|
|
|
|
|
|
def __temp__0():
|
|
if extra.loc:
|
|
state.markerStack.append(index - lineStart)
|
|
state.markerStack.append(lineNumber)
|
|
if extra.range:
|
|
state.markerStack.append(index)
|
|
|
|
|
|
Token = None
|
|
TokenName = None
|
|
FnExprTokens = None
|
|
Syntax = None
|
|
PropertyKind = None
|
|
Messages = None
|
|
Regex = None
|
|
SyntaxTreeDelegate = None
|
|
source = None
|
|
strict = None
|
|
index = None
|
|
lineNumber = None
|
|
lineStart = None
|
|
length = None
|
|
delegate = None
|
|
lookahead = None
|
|
state = None
|
|
extra = None
|
|
Token = jsdict({
|
|
"BooleanLiteral": 1,
|
|
"EOF": 2,
|
|
"Identifier": 3,
|
|
"Keyword": 4,
|
|
"NullLiteral": 5,
|
|
"NumericLiteral": 6,
|
|
"Punctuator": 7,
|
|
"StringLiteral": 8,
|
|
"RegularExpression": 9,
|
|
})
|
|
TokenName = jsdict({})
|
|
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"
|
|
TokenName[Token.RegularExpression] = "RegularExpression"
|
|
FnExprTokens = [
|
|
"(", "{", "[", "in", "typeof", "instanceof", "new", "return", "case",
|
|
"delete", "throw", "void", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=",
|
|
">>>=", "&=", "|=", "^=", ",", "+", "-", "*", "/", "%", "++", "--", "<<",
|
|
">>", ">>>", "&", "|", "^", "!", "~", "&&", "||", "?", ":", "===", "==",
|
|
">=", "<=", "<", ">", "!=", "!=="
|
|
]
|
|
Syntax = jsdict({
|
|
"AssignmentExpression": "AssignmentExpression",
|
|
"ArrayExpression": "ArrayExpression",
|
|
"BlockStatement": "BlockStatement",
|
|
"BinaryExpression": "BinaryExpression",
|
|
"BreakStatement": "BreakStatement",
|
|
"CallExpression": "CallExpression",
|
|
"CatchClause": "CatchClause",
|
|
"ConditionalExpression": "ConditionalExpression",
|
|
"ContinueStatement": "ContinueStatement",
|
|
"DoWhileStatement": "DoWhileStatement",
|
|
"DebuggerStatement": "DebuggerStatement",
|
|
"EmptyStatement": "EmptyStatement",
|
|
"ExpressionStatement": "ExpressionStatement",
|
|
"ForStatement": "ForStatement",
|
|
"ForInStatement": "ForInStatement",
|
|
"FunctionDeclaration": "FunctionDeclaration",
|
|
"FunctionExpression": "FunctionExpression",
|
|
"Identifier": "Identifier",
|
|
"IfStatement": "IfStatement",
|
|
"Literal": "Literal",
|
|
"LabeledStatement": "LabeledStatement",
|
|
"LogicalExpression": "LogicalExpression",
|
|
"MemberExpression": "MemberExpression",
|
|
"NewExpression": "NewExpression",
|
|
"ObjectExpression": "ObjectExpression",
|
|
"Program": "Program",
|
|
"Property": "Property",
|
|
"ReturnStatement": "ReturnStatement",
|
|
"SequenceExpression": "SequenceExpression",
|
|
"SwitchStatement": "SwitchStatement",
|
|
"SwitchCase": "SwitchCase",
|
|
"ThisExpression": "ThisExpression",
|
|
"ThrowStatement": "ThrowStatement",
|
|
"TryStatement": "TryStatement",
|
|
"UnaryExpression": "UnaryExpression",
|
|
"UpdateExpression": "UpdateExpression",
|
|
"VariableDeclaration": "VariableDeclaration",
|
|
"VariableDeclarator": "VariableDeclarator",
|
|
"WhileStatement": "WhileStatement",
|
|
"WithStatement": "WithStatement",
|
|
})
|
|
PropertyKind = jsdict({
|
|
"Data": 1,
|
|
"Get": 2,
|
|
"Set": 4,
|
|
})
|
|
Messages = jsdict({
|
|
"UnexpectedToken":
|
|
"Unexpected token %0",
|
|
"UnexpectedNumber":
|
|
"Unexpected number",
|
|
"UnexpectedString":
|
|
"Unexpected string",
|
|
"UnexpectedIdentifier":
|
|
"Unexpected identifier",
|
|
"UnexpectedReserved":
|
|
"Unexpected reserved word",
|
|
"UnexpectedEOS":
|
|
"Unexpected end of input",
|
|
"NewlineAfterThrow":
|
|
"Illegal newline after throw",
|
|
"InvalidRegExp":
|
|
"Invalid regular expression",
|
|
"UnterminatedRegExp":
|
|
"Invalid regular expression: missing /",
|
|
"InvalidLHSInAssignment":
|
|
"Invalid left-hand side in assignment",
|
|
"InvalidLHSInForIn":
|
|
"Invalid left-hand side in for-in",
|
|
"MultipleDefaultsInSwitch":
|
|
"More than one default clause in switch statement",
|
|
"NoCatchOrFinally":
|
|
"Missing catch or finally after try",
|
|
"UnknownLabel":
|
|
"Undefined label '%0'",
|
|
"Redeclaration":
|
|
"%0 '%1' has already been declared",
|
|
"IllegalContinue":
|
|
"Illegal continue statement",
|
|
"IllegalBreak":
|
|
"Illegal break statement",
|
|
"IllegalReturn":
|
|
"Illegal return statement",
|
|
"StrictModeWith":
|
|
"Strict mode code may not include a with statement",
|
|
"StrictCatchVariable":
|
|
"Catch variable may not be eval or arguments in strict mode",
|
|
"StrictVarName":
|
|
"Variable name may not be eval or arguments in strict mode",
|
|
"StrictParamName":
|
|
"Parameter name eval or arguments is not allowed in strict mode",
|
|
"StrictParamDupe":
|
|
"Strict mode function may not have duplicate parameter names",
|
|
"StrictFunctionName":
|
|
"Function name may not be eval or arguments in strict mode",
|
|
"StrictOctalLiteral":
|
|
"Octal literals are not allowed in strict mode.",
|
|
"StrictDelete":
|
|
"Delete of an unqualified identifier in strict mode.",
|
|
"StrictDuplicateProperty":
|
|
"Duplicate data property in object literal not allowed in strict mode",
|
|
"AccessorDataProperty":
|
|
"Object literal may not have data and accessor property with the same name",
|
|
"AccessorGetSet":
|
|
"Object literal may not have multiple get/set accessors with the same name",
|
|
"StrictLHSAssignment":
|
|
"Assignment to eval or arguments is not allowed in strict mode",
|
|
"StrictLHSPostfix":
|
|
"Postfix increment/decrement may not have eval or arguments operand in strict mode",
|
|
"StrictLHSPrefix":
|
|
"Prefix increment/decrement may not have eval or arguments operand in strict mode",
|
|
"StrictReservedWord":
|
|
"Use of future reserved word in strict mode",
|
|
})
|
|
Regex = jsdict({
|
|
"NonAsciiIdentifierStart":
|
|
RegExp(
|
|
u"[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]"
|
|
),
|
|
"NonAsciiIdentifierPart":
|
|
RegExp(
|
|
u"[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]"
|
|
),
|
|
})
|
|
|
|
|
|
def assert__py__(condition=None, message=None):
|
|
if not condition:
|
|
raise RuntimeError("ASSERT: " + message)
|
|
|
|
|
|
def isDecimalDigit(ch=None):
|
|
return (ch >= 48) and (ch <= 57)
|
|
|
|
|
|
def isHexDigit(ch=None):
|
|
return "0123456789abcdefABCDEF".find(ch) >= 0
|
|
|
|
|
|
def isOctalDigit(ch=None):
|
|
return "01234567".find(ch) >= 0
|
|
|
|
|
|
def isWhiteSpace(ch=None):
|
|
return (
|
|
((((ch == 32) or (ch == 9)) or (ch == 11)) or
|
|
(ch == 12)) or (ch == 160)
|
|
) or ((ch >= 5760) and (
|
|
u"\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\ufeff"
|
|
.find(unichr(ch)) > 0))
|
|
|
|
|
|
def isLineTerminator(ch=None):
|
|
return (((ch == 10) or (ch == 13)) or (ch == 8232)) or (ch == 8233)
|
|
|
|
|
|
def isIdentifierStart(ch=None):
|
|
return (((((ch == 36) or (ch == 95)) or ((ch >= 65) and (ch <= 90))) or
|
|
((ch >= 97) and (ch <= 122))) or
|
|
(ch == 92)) or ((ch >= 128)
|
|
and Regex.NonAsciiIdentifierStart.test(unichr(ch)))
|
|
|
|
|
|
def isIdentifierPart(ch=None):
|
|
return ((((((ch == 36) or (ch == 95)) or ((ch >= 65) and (ch <= 90))) or
|
|
((ch >= 97) and (ch <= 122))) or ((ch >= 48) and (ch <= 57))) or
|
|
(ch == 92)) or ((ch >= 128)
|
|
and Regex.NonAsciiIdentifierPart.test(unichr(ch)))
|
|
|
|
|
|
def isFutureReservedWord(id=None):
|
|
while 1:
|
|
if (id == "super") or ((id == "import") or ((id == "extends") or
|
|
((id == "export") or
|
|
((id == "enum") or
|
|
(id == "class"))))):
|
|
return True
|
|
else:
|
|
return False
|
|
break
|
|
|
|
|
|
def isStrictModeReservedWord(id=None):
|
|
while 1:
|
|
if (id == "let") or ((id == "yield") or
|
|
((id == "static") or
|
|
((id == "public") or
|
|
((id == "protected") or
|
|
((id == "private") or
|
|
((id == "package") or
|
|
((id == "interface") or
|
|
(id == "implements")))))))):
|
|
return True
|
|
else:
|
|
return False
|
|
break
|
|
|
|
|
|
def isRestrictedWord(id=None):
|
|
return (id == "eval") or (id == "arguments")
|
|
|
|
|
|
def isKeyword(id=None):
|
|
if strict and isStrictModeReservedWord(id):
|
|
return True
|
|
while 1:
|
|
if len(id) == 2:
|
|
return ((id == "if") or (id == "in")) or (id == "do")
|
|
elif len(id) == 3:
|
|
return ((((id == "var") or (id == "for")) or (id == "new")) or
|
|
(id == "try")) or (id == "let")
|
|
elif len(id) == 4:
|
|
return (((((id == "this") or (id == "else")) or (id == "case")) or
|
|
(id == "void")) or (id == "with")) or (id == "enum")
|
|
elif len(id) == 5:
|
|
return (((((((id == "while") or (id == "break")) or
|
|
(id == "catch")) or (id == "throw")) or
|
|
(id == "const")) or (id == "yield")) or
|
|
(id == "class")) or (id == "super")
|
|
elif len(id) == 6:
|
|
return (((((id == "return") or (id == "typeof")) or
|
|
(id == "delete")) or (id == "switch")) or
|
|
(id == "export")) or (id == "import")
|
|
elif len(id) == 7:
|
|
return ((id == "default") or
|
|
(id == "finally")) or (id == "extends")
|
|
elif len(id) == 8:
|
|
return ((id == "function") or
|
|
(id == "continue")) or (id == "debugger")
|
|
elif len(id) == 10:
|
|
return id == "instanceof"
|
|
else:
|
|
return False
|
|
break
|
|
|
|
|
|
def addComment(type=None, value=None, start=None, end=None, loc=None):
|
|
comment = None
|
|
assert__py__(('undefined'
|
|
if not 'start' in locals() else typeof(start)) == "number",
|
|
"Comment must have valid position")
|
|
if state.lastCommentStart >= start:
|
|
return
|
|
state.lastCommentStart = start
|
|
comment = jsdict({
|
|
"type": type,
|
|
"value": value,
|
|
})
|
|
if extra.range:
|
|
comment.range = [start, end]
|
|
if extra.loc:
|
|
comment.loc = loc
|
|
extra.comments.append(comment)
|
|
|
|
|
|
def skipSingleLineComment():
|
|
global index, lineNumber, lineStart
|
|
start = None
|
|
loc = None
|
|
ch = None
|
|
comment = None
|
|
start = index - 2
|
|
loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": lineNumber,
|
|
"column": (index - lineStart) - 2,
|
|
}),
|
|
})
|
|
while index < length:
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
index += 1
|
|
index
|
|
if isLineTerminator(ch):
|
|
if extra.comments:
|
|
comment = source[(start + 2):(index - 1)]
|
|
loc.end = jsdict({
|
|
"line": lineNumber,
|
|
"column": (index - lineStart) - 1,
|
|
})
|
|
addComment("Line", comment, start, index - 1, loc)
|
|
if (ch == 13) and (
|
|
(ord(source[index]) if index < len(source) else None) == 10):
|
|
index += 1
|
|
index
|
|
lineNumber += 1
|
|
lineNumber
|
|
lineStart = index
|
|
return
|
|
if extra.comments:
|
|
comment = source[(start + 2):index]
|
|
loc.end = jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
})
|
|
addComment("Line", comment, start, index, loc)
|
|
|
|
|
|
def skipMultiLineComment():
|
|
global index, lineNumber, lineStart
|
|
start = None
|
|
loc = None
|
|
ch = None
|
|
comment = None
|
|
if extra.comments:
|
|
start = index - 2
|
|
loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": lineNumber,
|
|
"column": (index - lineStart) - 2,
|
|
}),
|
|
})
|
|
while index < length:
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
if isLineTerminator(ch):
|
|
if (ch == 13) and ((ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None) == 10):
|
|
index += 1
|
|
index
|
|
lineNumber += 1
|
|
lineNumber
|
|
index += 1
|
|
index
|
|
lineStart = index
|
|
if index >= length:
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
elif ch == 42:
|
|
if (ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None) == 47:
|
|
index += 1
|
|
index
|
|
index += 1
|
|
index
|
|
if extra.comments:
|
|
comment = source[(start + 2):(index - 2)]
|
|
loc.end = jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
})
|
|
addComment("Block", comment, start, index, loc)
|
|
return
|
|
index += 1
|
|
index
|
|
else:
|
|
index += 1
|
|
index
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
|
|
|
|
def skipComment():
|
|
global index, lineNumber, lineStart
|
|
ch = None
|
|
while index < length:
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
if isWhiteSpace(ch):
|
|
index += 1
|
|
index
|
|
elif isLineTerminator(ch):
|
|
index += 1
|
|
index
|
|
if (ch == 13) and (
|
|
(ord(source[index]) if index < len(source) else None) == 10):
|
|
index += 1
|
|
index
|
|
lineNumber += 1
|
|
lineNumber
|
|
lineStart = index
|
|
elif ch == 47:
|
|
ch = (ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None)
|
|
if ch == 47:
|
|
index += 1
|
|
index
|
|
index += 1
|
|
index
|
|
skipSingleLineComment()
|
|
elif ch == 42:
|
|
index += 1
|
|
index
|
|
index += 1
|
|
index
|
|
skipMultiLineComment()
|
|
else:
|
|
break
|
|
else:
|
|
break
|
|
|
|
|
|
def scanHexEscape(prefix=None):
|
|
global len__py__, index
|
|
i = None
|
|
len__py__ = None
|
|
ch = None
|
|
code = 0
|
|
len__py__ = (4 if prefix == "u" else 2)
|
|
i = 0
|
|
while 1:
|
|
if not (i < len__py__):
|
|
break
|
|
if (index < length) and isHexDigit(source[index]):
|
|
index += 1
|
|
ch = source[index - 1]
|
|
code = (code * 16) + "0123456789abcdef".find(ch.lower())
|
|
else:
|
|
return ""
|
|
i += 1
|
|
return unichr(code)
|
|
|
|
|
|
def getEscapedIdentifier():
|
|
global index
|
|
ch = None
|
|
id = None
|
|
index += 1
|
|
index += 1
|
|
ch = (ord(source[index - 1]) if index - 1 < len(source) else None)
|
|
id = unichr(ch)
|
|
if ch == 92:
|
|
if (ord(source[index]) if index < len(source) else None) != 117:
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
index += 1
|
|
index
|
|
ch = scanHexEscape("u")
|
|
if ((not ch) or (ch == "\\")) or (not isIdentifierStart(
|
|
(ord(ch[0]) if 0 < len(ch) else None))):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
id = ch
|
|
while index < length:
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
if not isIdentifierPart(ch):
|
|
break
|
|
index += 1
|
|
index
|
|
id += unichr(ch)
|
|
if ch == 92:
|
|
id = id[0:(0 + (len(id) - 1))]
|
|
if (ord(source[index]) if index < len(source) else None) != 117:
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
index += 1
|
|
index
|
|
ch = scanHexEscape("u")
|
|
if ((not ch) or (ch == "\\")) or (not isIdentifierPart(
|
|
(ord(ch[0]) if 0 < len(ch) else None))):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
id += ch
|
|
return id
|
|
|
|
|
|
def getIdentifier():
|
|
global index
|
|
start = None
|
|
ch = None
|
|
index += 1
|
|
start = index - 1
|
|
while index < length:
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
if ch == 92:
|
|
index = start
|
|
return getEscapedIdentifier()
|
|
if isIdentifierPart(ch):
|
|
index += 1
|
|
index
|
|
else:
|
|
break
|
|
return source[start:index]
|
|
|
|
|
|
def scanIdentifier():
|
|
start = None
|
|
id = None
|
|
type = None
|
|
start = index
|
|
id = (getEscapedIdentifier() if
|
|
(ord(source[index]) if index < len(source) else None) == 92 else
|
|
getIdentifier())
|
|
if len(id) == 1:
|
|
type = Token.Identifier
|
|
elif isKeyword(id):
|
|
type = Token.Keyword
|
|
elif id == "null":
|
|
type = Token.NullLiteral
|
|
elif (id == "true") or (id == "false"):
|
|
type = Token.BooleanLiteral
|
|
else:
|
|
type = Token.Identifier
|
|
return jsdict({
|
|
"type": type,
|
|
"value": id,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def scanPunctuator():
|
|
global index
|
|
start = index
|
|
code = (ord(source[index]) if index < len(source) else None)
|
|
code2 = None
|
|
ch1 = source[index]
|
|
ch2 = None
|
|
ch3 = None
|
|
ch4 = None
|
|
while 1:
|
|
if (code == 126) or ((code == 63) or ((code == 58) or
|
|
((code == 93) or
|
|
((code == 91) or
|
|
((code == 125) or
|
|
((code == 123) or
|
|
((code == 44) or
|
|
((code == 59) or
|
|
((code == 41) or
|
|
((code == 40) or
|
|
(code == 46))))))))))):
|
|
index += 1
|
|
index
|
|
if extra.tokenize:
|
|
if code == 40:
|
|
extra.openParenToken = len(extra.tokens)
|
|
elif code == 123:
|
|
extra.openCurlyToken = len(extra.tokens)
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": unichr(code),
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
else:
|
|
code2 = (ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None)
|
|
if code2 == 61:
|
|
while 1:
|
|
if (code == 124) or ((code == 94) or
|
|
((code == 62) or
|
|
((code == 60) or
|
|
((code == 47) or
|
|
((code == 45) or
|
|
((code == 43) or
|
|
((code == 42) or
|
|
((code == 38) or
|
|
(code == 37))))))))):
|
|
index += 2
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": unichr(code) + unichr(code2),
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
elif (code == 61) or (code == 33):
|
|
index += 2
|
|
if (ord(source[index])
|
|
if index < len(source) else None) == 61:
|
|
index += 1
|
|
index
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": source[start:index],
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
else:
|
|
break
|
|
break
|
|
break
|
|
break
|
|
ch2 = source[index + 1] if index + 1 < len(source) else None
|
|
ch3 = source[index + 2] if index + 2 < len(source) else None
|
|
ch4 = source[index + 3] if index + 3 < len(source) else None
|
|
if ((ch1 == ">") and (ch2 == ">")) and (ch3 == ">"):
|
|
if ch4 == "=":
|
|
index += 4
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": ">>>=",
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
if ((ch1 == ">") and (ch2 == ">")) and (ch3 == ">"):
|
|
index += 3
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": ">>>",
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
if ((ch1 == "<") and (ch2 == "<")) and (ch3 == "="):
|
|
index += 3
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": "<<=",
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
if ((ch1 == ">") and (ch2 == ">")) and (ch3 == "="):
|
|
index += 3
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": ">>=",
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
if (ch1 == ch2) and ("+-<>&|".find(ch1) >= 0):
|
|
index += 2
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": ch1 + ch2,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
if "<>=!+-*%&|^/".find(ch1) >= 0:
|
|
index += 1
|
|
index
|
|
return jsdict({
|
|
"type": Token.Punctuator,
|
|
"value": ch1,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
|
|
|
|
def scanHexLiteral(start=None):
|
|
global index
|
|
number = ""
|
|
while index < length:
|
|
if not isHexDigit(source[index]):
|
|
break
|
|
index += 1
|
|
number += source[index - 1]
|
|
if len(number) == 0:
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
if isIdentifierStart(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
return jsdict({
|
|
"type": Token.NumericLiteral,
|
|
"value": parseInt("0x" + number, 16),
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def scanOctalLiteral(start=None):
|
|
global index
|
|
index += 1
|
|
number = "0" + source[index - 1]
|
|
while index < length:
|
|
if not isOctalDigit(source[index]):
|
|
break
|
|
index += 1
|
|
number += source[index - 1]
|
|
if isIdentifierStart(
|
|
(ord(source[index])
|
|
if index < len(source) else None)) or isDecimalDigit(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
return jsdict({
|
|
"type": Token.NumericLiteral,
|
|
"value": parseInt(number, 8),
|
|
"octal": True,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def scanNumericLiteral():
|
|
global index
|
|
number = None
|
|
start = None
|
|
ch = None
|
|
ch = source[index]
|
|
assert__py__(
|
|
isDecimalDigit((ord(ch[0]) if 0 < len(ch) else None)) or (ch == "."),
|
|
"Numeric literal must start with a decimal digit or a decimal point")
|
|
start = index
|
|
number = ""
|
|
if ch != ".":
|
|
index += 1
|
|
number = source[index - 1]
|
|
ch = source[index] if index < len(source) else None
|
|
if number == "0":
|
|
if (ch == "x") or (ch == "X"):
|
|
index += 1
|
|
index
|
|
return scanHexLiteral(start)
|
|
if isOctalDigit(ch):
|
|
return scanOctalLiteral(start)
|
|
if ch and isDecimalDigit((ord(ch[0]) if 0 < len(ch) else None)):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
while isDecimalDigit(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
index += 1
|
|
number += source[index - 1]
|
|
ch = source[index] if index < len(source) else None
|
|
if ch == ".":
|
|
index += 1
|
|
number += source[index - 1]
|
|
while isDecimalDigit(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
index += 1
|
|
number += source[index - 1]
|
|
ch = source[index]
|
|
if (ch == "e") or (ch == "E"):
|
|
index += 1
|
|
number += source[index - 1]
|
|
ch = source[index]
|
|
if (ch == "+") or (ch == "-"):
|
|
index += 1
|
|
number += source[index - 1]
|
|
if isDecimalDigit(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
while isDecimalDigit(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
index += 1
|
|
number += source[index - 1]
|
|
else:
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
if isIdentifierStart(
|
|
(ord(source[index]) if index < len(source) else None)):
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
return jsdict({
|
|
"type": Token.NumericLiteral,
|
|
"value": parseFloat(number),
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def scanStringLiteral():
|
|
global index, lineNumber
|
|
str = ""
|
|
quote = None
|
|
start = None
|
|
ch = None
|
|
code = None
|
|
unescaped = None
|
|
restore = None
|
|
octal = False
|
|
quote = source[index]
|
|
assert__py__((quote == "'") or (quote == "\""),
|
|
"String literal must starts with a quote")
|
|
start = index
|
|
index += 1
|
|
index
|
|
while index < length:
|
|
index += 1
|
|
ch = source[index - 1]
|
|
if ch == quote:
|
|
quote = ""
|
|
break
|
|
elif ch == "\\":
|
|
index += 1
|
|
ch = source[index - 1]
|
|
if (not ch) or (not isLineTerminator(
|
|
(ord(ch[0]) if 0 < len(ch) else None))):
|
|
while 1:
|
|
if ch == "n":
|
|
str += u"\x0a"
|
|
break
|
|
elif ch == "r":
|
|
str += u"\x0d"
|
|
break
|
|
elif ch == "t":
|
|
str += u"\x09"
|
|
break
|
|
elif (ch == "x") or (ch == "u"):
|
|
restore = index
|
|
unescaped = scanHexEscape(ch)
|
|
if unescaped:
|
|
str += unescaped
|
|
else:
|
|
index = restore
|
|
str += ch
|
|
break
|
|
elif ch == "b":
|
|
str += u"\x08"
|
|
break
|
|
elif ch == "f":
|
|
str += u"\x0c"
|
|
break
|
|
elif ch == "v":
|
|
str += u"\x0b"
|
|
break
|
|
else:
|
|
if isOctalDigit(ch):
|
|
code = "01234567".find(ch)
|
|
if code != 0:
|
|
octal = True
|
|
if (index < length) and isOctalDigit(
|
|
source[index]):
|
|
octal = True
|
|
index += 1
|
|
code = (code * 8) + "01234567".find(
|
|
source[index - 1])
|
|
if (("0123".find(ch) >= 0) and
|
|
(index < length)) and isOctalDigit(
|
|
source[index]):
|
|
index += 1
|
|
code = (code * 8) + "01234567".find(
|
|
source[index - 1])
|
|
str += unichr(code)
|
|
else:
|
|
str += ch
|
|
break
|
|
break
|
|
else:
|
|
lineNumber += 1
|
|
lineNumber
|
|
if (ch == u"\x0d") and (source[index] == u"\x0a"):
|
|
index += 1
|
|
index
|
|
elif isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
|
|
break
|
|
else:
|
|
str += ch
|
|
if quote != "":
|
|
throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
|
|
return jsdict({
|
|
"type": Token.StringLiteral,
|
|
"value": str,
|
|
"octal": octal,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def scanRegExp():
|
|
global lookahead, index
|
|
str = None
|
|
ch = None
|
|
start = None
|
|
pattern = None
|
|
flags = None
|
|
value = None
|
|
classMarker = False
|
|
restore = None
|
|
terminated = False
|
|
lookahead = None
|
|
skipComment()
|
|
start = index
|
|
ch = source[index]
|
|
assert__py__(ch == "/",
|
|
"Regular expression literal must start with a slash")
|
|
index += 1
|
|
str = source[index - 1]
|
|
while index < length:
|
|
index += 1
|
|
ch = source[index - 1]
|
|
str += ch
|
|
if classMarker:
|
|
if ch == "]":
|
|
classMarker = False
|
|
else:
|
|
if ch == "\\":
|
|
index += 1
|
|
ch = source[index - 1]
|
|
if isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
|
|
throwError(jsdict({}), Messages.UnterminatedRegExp)
|
|
str += ch
|
|
elif ch == "/":
|
|
terminated = True
|
|
break
|
|
elif ch == "[":
|
|
classMarker = True
|
|
elif isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
|
|
throwError(jsdict({}), Messages.UnterminatedRegExp)
|
|
if not terminated:
|
|
throwError(jsdict({}), Messages.UnterminatedRegExp)
|
|
pattern = str[1:(1 + (len(str) - 2))]
|
|
flags = ""
|
|
while index < length:
|
|
ch = source[index]
|
|
if not isIdentifierPart((ord(ch[0]) if 0 < len(ch) else None)):
|
|
break
|
|
index += 1
|
|
index
|
|
if (ch == "\\") and (index < length):
|
|
ch = source[index]
|
|
if ch == "u":
|
|
index += 1
|
|
index
|
|
restore = index
|
|
ch = scanHexEscape("u")
|
|
if ch:
|
|
flags += ch
|
|
str += "\\u"
|
|
while 1:
|
|
if not (restore < index):
|
|
break
|
|
str += source[restore]
|
|
restore += 1
|
|
else:
|
|
index = restore
|
|
flags += "u"
|
|
str += "\\u"
|
|
else:
|
|
str += "\\"
|
|
else:
|
|
flags += ch
|
|
str += ch
|
|
try:
|
|
value = RegExp(pattern, flags)
|
|
except Exception as e:
|
|
throwError(jsdict({}), Messages.InvalidRegExp)
|
|
peek()
|
|
if extra.tokenize:
|
|
return jsdict({
|
|
"type": Token.RegularExpression,
|
|
"value": value,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [start, index],
|
|
})
|
|
return jsdict({
|
|
"literal": str,
|
|
"value": value,
|
|
"range": [start, index],
|
|
})
|
|
|
|
|
|
def isIdentifierName(token=None):
|
|
return (((token.type == Token.Identifier) or
|
|
(token.type == Token.Keyword)) or
|
|
(token.type == Token.BooleanLiteral)) or (
|
|
token.type == Token.NullLiteral)
|
|
|
|
|
|
def advanceSlash():
|
|
prevToken = None
|
|
checkToken = None
|
|
prevToken = extra.tokens[len(extra.tokens) - 1]
|
|
if not prevToken:
|
|
return scanRegExp()
|
|
if prevToken.type == "Punctuator":
|
|
if prevToken.value == ")":
|
|
checkToken = extra.tokens[extra.openParenToken - 1]
|
|
if (checkToken and (checkToken.type == "Keyword")) and (
|
|
(((checkToken.value == "if") or
|
|
(checkToken.value == "while")) or
|
|
(checkToken.value == "for")) or (checkToken.value == "with")):
|
|
return scanRegExp()
|
|
return scanPunctuator()
|
|
if prevToken.value == "}":
|
|
if extra.tokens[extra.openCurlyToken - 3] and (
|
|
extra.tokens[extra.openCurlyToken - 3].type == "Keyword"):
|
|
checkToken = extra.tokens[extra.openCurlyToken - 4]
|
|
if not checkToken:
|
|
return scanPunctuator()
|
|
elif extra.tokens[extra.openCurlyToken - 4] and (
|
|
extra.tokens[extra.openCurlyToken - 4].type == "Keyword"):
|
|
checkToken = extra.tokens[extra.openCurlyToken - 5]
|
|
if not checkToken:
|
|
return scanRegExp()
|
|
else:
|
|
return scanPunctuator()
|
|
if FnExprTokens.indexOf(checkToken.value) >= 0:
|
|
return scanPunctuator()
|
|
return scanRegExp()
|
|
return scanRegExp()
|
|
if prevToken.type == "Keyword":
|
|
return scanRegExp()
|
|
return scanPunctuator()
|
|
|
|
|
|
def advance():
|
|
ch = None
|
|
skipComment()
|
|
if index >= length:
|
|
return jsdict({
|
|
"type": Token.EOF,
|
|
"lineNumber": lineNumber,
|
|
"lineStart": lineStart,
|
|
"range": [index, index],
|
|
})
|
|
ch = (ord(source[index]) if index < len(source) else None)
|
|
if ((ch == 40) or (ch == 41)) or (ch == 58):
|
|
return scanPunctuator()
|
|
if (ch == 39) or (ch == 34):
|
|
return scanStringLiteral()
|
|
if isIdentifierStart(ch):
|
|
return scanIdentifier()
|
|
if ch == 46:
|
|
if isDecimalDigit((ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None)):
|
|
return scanNumericLiteral()
|
|
return scanPunctuator()
|
|
if isDecimalDigit(ch):
|
|
return scanNumericLiteral()
|
|
if extra.tokenize and (ch == 47):
|
|
return advanceSlash()
|
|
return scanPunctuator()
|
|
|
|
|
|
def lex():
|
|
global index, lineNumber, lineStart, lookahead
|
|
token = None
|
|
token = lookahead
|
|
index = token.range[1]
|
|
lineNumber = token.lineNumber
|
|
lineStart = token.lineStart
|
|
lookahead = advance()
|
|
index = token.range[1]
|
|
lineNumber = token.lineNumber
|
|
lineStart = token.lineStart
|
|
return token
|
|
|
|
|
|
def peek():
|
|
global lookahead, index, lineNumber, lineStart
|
|
pos = None
|
|
line = None
|
|
start = None
|
|
pos = index
|
|
line = lineNumber
|
|
start = lineStart
|
|
lookahead = advance()
|
|
index = pos
|
|
lineNumber = line
|
|
lineStart = start
|
|
|
|
|
|
SyntaxTreeDelegate = jsdict({
|
|
"name": "SyntaxTree",
|
|
"markStart": __temp__0,
|
|
"markEnd": __temp__1,
|
|
"markEndIf": __temp__2,
|
|
"postProcess": __temp__3,
|
|
"createArrayExpression": __temp__4,
|
|
"createAssignmentExpression": __temp__5,
|
|
"createBinaryExpression": __temp__6,
|
|
"createBlockStatement": __temp__7,
|
|
"createBreakStatement": __temp__8,
|
|
"createCallExpression": __temp__9,
|
|
"createCatchClause": __temp__10,
|
|
"createConditionalExpression": __temp__11,
|
|
"createContinueStatement": __temp__12,
|
|
"createDebuggerStatement": __temp__13,
|
|
"createDoWhileStatement": __temp__14,
|
|
"createEmptyStatement": __temp__15,
|
|
"createExpressionStatement": __temp__16,
|
|
"createForStatement": __temp__17,
|
|
"createForInStatement": __temp__18,
|
|
"createFunctionDeclaration": __temp__19,
|
|
"createFunctionExpression": __temp__20,
|
|
"createIdentifier": __temp__21,
|
|
"createIfStatement": __temp__22,
|
|
"createLabeledStatement": __temp__23,
|
|
"createLiteral": __temp__24,
|
|
"createMemberExpression": __temp__25,
|
|
"createNewExpression": __temp__26,
|
|
"createObjectExpression": __temp__27,
|
|
"createPostfixExpression": __temp__28,
|
|
"createProgram": __temp__29,
|
|
"createProperty": __temp__30,
|
|
"createReturnStatement": __temp__31,
|
|
"createSequenceExpression": __temp__32,
|
|
"createSwitchCase": __temp__33,
|
|
"createSwitchStatement": __temp__34,
|
|
"createThisExpression": __temp__35,
|
|
"createThrowStatement": __temp__36,
|
|
"createTryStatement": __temp__37,
|
|
"createUnaryExpression": __temp__38,
|
|
"createVariableDeclaration": __temp__39,
|
|
"createVariableDeclarator": __temp__40,
|
|
"createWhileStatement": __temp__41,
|
|
"createWithStatement": __temp__42,
|
|
})
|
|
|
|
|
|
def peekLineTerminator():
|
|
global index, lineNumber, lineStart
|
|
pos = None
|
|
line = None
|
|
start = None
|
|
found = None
|
|
pos = index
|
|
line = lineNumber
|
|
start = lineStart
|
|
skipComment()
|
|
found = lineNumber != line
|
|
index = pos
|
|
lineNumber = line
|
|
lineStart = start
|
|
return found
|
|
|
|
|
|
def throwError(token=None, messageFormat=None, a=None):
|
|
def __temp__43(whole=None, index=None):
|
|
assert__py__(index < len(args), "Message reference must be in range")
|
|
return args[index]
|
|
|
|
error = None
|
|
args = Array.prototype.slice.call(arguments, 2)
|
|
msg = messageFormat.replace(RegExp(r'%(\d)'), __temp__43)
|
|
if ('undefined' if not ('lineNumber' in token) else typeof(
|
|
token.lineNumber)) == "number":
|
|
error = RuntimeError((("Line " + token.lineNumber) + ": ") + msg)
|
|
error.index = token.range[0]
|
|
error.lineNumber = token.lineNumber
|
|
error.column = (token.range[0] - lineStart) + 1
|
|
else:
|
|
error = RuntimeError((("Line " + lineNumber) + ": ") + msg)
|
|
error.index = index
|
|
error.lineNumber = lineNumber
|
|
error.column = (index - lineStart) + 1
|
|
error.description = msg
|
|
raise error
|
|
|
|
|
|
def throwErrorTolerant():
|
|
try:
|
|
throwError.apply(None, arguments)
|
|
except Exception as e:
|
|
if extra.errors:
|
|
extra.errors.append(e)
|
|
else:
|
|
raise
|
|
|
|
|
|
def throwUnexpected(token=None):
|
|
if token.type == Token.EOF:
|
|
throwError(token, Messages.UnexpectedEOS)
|
|
if token.type == Token.NumericLiteral:
|
|
throwError(token, Messages.UnexpectedNumber)
|
|
if token.type == Token.StringLiteral:
|
|
throwError(token, Messages.UnexpectedString)
|
|
if token.type == Token.Identifier:
|
|
throwError(token, Messages.UnexpectedIdentifier)
|
|
if token.type == Token.Keyword:
|
|
if isFutureReservedWord(token.value):
|
|
throwError(token, Messages.UnexpectedReserved)
|
|
elif strict and isStrictModeReservedWord(token.value):
|
|
throwErrorTolerant(token, Messages.StrictReservedWord)
|
|
return
|
|
throwError(token, Messages.UnexpectedToken, token.value)
|
|
throwError(token, Messages.UnexpectedToken, token.value)
|
|
|
|
|
|
def expect(value=None):
|
|
token = lex()
|
|
if (token.type != Token.Punctuator) or (token.value != value):
|
|
throwUnexpected(token)
|
|
|
|
|
|
def expectKeyword(keyword=None):
|
|
token = lex()
|
|
if (token.type != Token.Keyword) or (token.value != keyword):
|
|
throwUnexpected(token)
|
|
|
|
|
|
def match(value=None):
|
|
return (lookahead.type == Token.Punctuator) and (lookahead.value == value)
|
|
|
|
|
|
def matchKeyword(keyword=None):
|
|
return (lookahead.type == Token.Keyword) and (lookahead.value == keyword)
|
|
|
|
|
|
def matchAssign():
|
|
op = None
|
|
if lookahead.type != Token.Punctuator:
|
|
return False
|
|
op = lookahead.value
|
|
return (((((((((((op == "=") or (op == "*=")) or (op == "/=")) or
|
|
(op == "%=")) or (op == "+=")) or (op == "-=")) or
|
|
(op == "<<=")) or (op == ">>=")) or (op == ">>>=")) or
|
|
(op == "&=")) or (op == "^=")) or (op == "|=")
|
|
|
|
|
|
def consumeSemicolon():
|
|
line = None
|
|
if (ord(source[index]) if index < len(source) else None) == 59:
|
|
lex()
|
|
return
|
|
line = lineNumber
|
|
skipComment()
|
|
if lineNumber != line:
|
|
return
|
|
if match(";"):
|
|
lex()
|
|
return
|
|
if (lookahead.type != Token.EOF) and (not match("}")):
|
|
throwUnexpected(lookahead)
|
|
|
|
|
|
def isLeftHandSide(expr=None):
|
|
return (expr.type == Syntax.Identifier) or (
|
|
expr.type == Syntax.MemberExpression)
|
|
|
|
|
|
def parseArrayInitialiser():
|
|
elements = []
|
|
expect("[")
|
|
while not match("]"):
|
|
if match(","):
|
|
lex()
|
|
elements.append(None)
|
|
else:
|
|
elements.append(parseAssignmentExpression())
|
|
if not match("]"):
|
|
expect(",")
|
|
expect("]")
|
|
return delegate.createArrayExpression(elements)
|
|
|
|
|
|
def parsePropertyFunction(param=None, first=None):
|
|
global strict
|
|
previousStrict = None
|
|
body = None
|
|
previousStrict = strict
|
|
skipComment()
|
|
delegate.markStart()
|
|
body = parseFunctionSourceElements()
|
|
if (first and strict) and isRestrictedWord(param[0].name):
|
|
throwErrorTolerant(first, Messages.StrictParamName)
|
|
strict = previousStrict
|
|
return delegate.markEnd(
|
|
delegate.createFunctionExpression(None, param, [], body))
|
|
|
|
|
|
def parseObjectPropertyKey():
|
|
token = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
token = lex()
|
|
if (token.type == Token.StringLiteral) or (
|
|
token.type == Token.NumericLiteral):
|
|
if strict and token.octal:
|
|
throwErrorTolerant(token, Messages.StrictOctalLiteral)
|
|
return delegate.markEnd(delegate.createLiteral(token))
|
|
return delegate.markEnd(delegate.createIdentifier(token.value))
|
|
|
|
|
|
def parseObjectProperty():
|
|
token = None
|
|
key = None
|
|
id = None
|
|
value = None
|
|
param = None
|
|
token = lookahead
|
|
skipComment()
|
|
delegate.markStart()
|
|
if token.type == Token.Identifier:
|
|
id = parseObjectPropertyKey()
|
|
if (token.value == "get") and (not match(":")):
|
|
key = parseObjectPropertyKey()
|
|
expect("(")
|
|
expect(")")
|
|
value = parsePropertyFunction([])
|
|
return delegate.markEnd(delegate.createProperty("get", key, value))
|
|
if (token.value == "set") and (not match(":")):
|
|
key = parseObjectPropertyKey()
|
|
expect("(")
|
|
token = lookahead
|
|
if token.type != Token.Identifier:
|
|
expect(")")
|
|
throwErrorTolerant(token, Messages.UnexpectedToken,
|
|
token.value)
|
|
value = parsePropertyFunction([])
|
|
else:
|
|
param = [parseVariableIdentifier()]
|
|
expect(")")
|
|
value = parsePropertyFunction(param, token)
|
|
return delegate.markEnd(delegate.createProperty("set", key, value))
|
|
expect(":")
|
|
value = parseAssignmentExpression()
|
|
return delegate.markEnd(delegate.createProperty("init", id, value))
|
|
if (token.type == Token.EOF) or (token.type == Token.Punctuator):
|
|
throwUnexpected(token)
|
|
else:
|
|
key = parseObjectPropertyKey()
|
|
expect(":")
|
|
value = parseAssignmentExpression()
|
|
return delegate.markEnd(delegate.createProperty("init", key, value))
|
|
|
|
|
|
def parseObjectInitialiser():
|
|
properties = []
|
|
property = None
|
|
name = None
|
|
key = None
|
|
kind = None
|
|
map = jsdict({})
|
|
toString = str
|
|
expect("{")
|
|
while not match("}"):
|
|
property = parseObjectProperty()
|
|
if property.key.type == Syntax.Identifier:
|
|
name = property.key.name
|
|
else:
|
|
name = toString(property.key.value)
|
|
kind = (PropertyKind.Data if property.kind == "init" else (
|
|
PropertyKind.Get if property.kind == "get" else PropertyKind.Set))
|
|
key = "$" + name
|
|
if key in map:
|
|
if map[key] == PropertyKind.Data:
|
|
if strict and (kind == PropertyKind.Data):
|
|
throwErrorTolerant(
|
|
jsdict({}), Messages.StrictDuplicateProperty)
|
|
elif kind != PropertyKind.Data:
|
|
throwErrorTolerant(
|
|
jsdict({}), Messages.AccessorDataProperty)
|
|
else:
|
|
if kind == PropertyKind.Data:
|
|
throwErrorTolerant(
|
|
jsdict({}), Messages.AccessorDataProperty)
|
|
elif map[key] & kind:
|
|
throwErrorTolerant(jsdict({}), Messages.AccessorGetSet)
|
|
map[key] |= kind
|
|
else:
|
|
map[key] = kind
|
|
properties.append(property)
|
|
if not match("}"):
|
|
expect(",")
|
|
expect("}")
|
|
return delegate.createObjectExpression(properties)
|
|
|
|
|
|
def parseGroupExpression():
|
|
expr = None
|
|
expect("(")
|
|
expr = parseExpression()
|
|
expect(")")
|
|
return expr
|
|
|
|
|
|
def parsePrimaryExpression():
|
|
type = None
|
|
token = None
|
|
expr = None
|
|
if match("("):
|
|
return parseGroupExpression()
|
|
type = lookahead.type
|
|
delegate.markStart()
|
|
if type == Token.Identifier:
|
|
expr = delegate.createIdentifier(lex().value)
|
|
elif (type == Token.StringLiteral) or (type == Token.NumericLiteral):
|
|
if strict and lookahead.octal:
|
|
throwErrorTolerant(lookahead, Messages.StrictOctalLiteral)
|
|
expr = delegate.createLiteral(lex())
|
|
elif type == Token.Keyword:
|
|
if matchKeyword("this"):
|
|
lex()
|
|
expr = delegate.createThisExpression()
|
|
elif matchKeyword("function"):
|
|
expr = parseFunctionExpression()
|
|
elif type == Token.BooleanLiteral:
|
|
token = lex()
|
|
token.value = token.value == "true"
|
|
expr = delegate.createLiteral(token)
|
|
elif type == Token.NullLiteral:
|
|
token = lex()
|
|
token.value = None
|
|
expr = delegate.createLiteral(token)
|
|
elif match("["):
|
|
expr = parseArrayInitialiser()
|
|
elif match("{"):
|
|
expr = parseObjectInitialiser()
|
|
elif match("/") or match("/="):
|
|
expr = delegate.createLiteral(scanRegExp())
|
|
if expr:
|
|
return delegate.markEnd(expr)
|
|
throwUnexpected(lex())
|
|
|
|
|
|
def parseArguments():
|
|
args = []
|
|
expect("(")
|
|
if not match(")"):
|
|
while index < length:
|
|
args.append(parseAssignmentExpression())
|
|
if match(")"):
|
|
break
|
|
expect(",")
|
|
expect(")")
|
|
return args
|
|
|
|
|
|
def parseNonComputedProperty():
|
|
token = None
|
|
delegate.markStart()
|
|
token = lex()
|
|
if not isIdentifierName(token):
|
|
throwUnexpected(token)
|
|
return delegate.markEnd(delegate.createIdentifier(token.value))
|
|
|
|
|
|
def parseNonComputedMember():
|
|
expect(".")
|
|
return parseNonComputedProperty()
|
|
|
|
|
|
def parseComputedMember():
|
|
expr = None
|
|
expect("[")
|
|
expr = parseExpression()
|
|
expect("]")
|
|
return expr
|
|
|
|
|
|
def parseNewExpression():
|
|
callee = None
|
|
args = None
|
|
delegate.markStart()
|
|
expectKeyword("new")
|
|
callee = parseLeftHandSideExpression()
|
|
args = (parseArguments() if match("(") else [])
|
|
return delegate.markEnd(delegate.createNewExpression(callee, args))
|
|
|
|
|
|
def parseLeftHandSideExpressionAllowCall():
|
|
marker = None
|
|
expr = None
|
|
args = None
|
|
property = None
|
|
marker = createLocationMarker()
|
|
expr = (parseNewExpression()
|
|
if matchKeyword("new") else parsePrimaryExpression())
|
|
while (match(".") or match("[")) or match("("):
|
|
if match("("):
|
|
args = parseArguments()
|
|
expr = delegate.createCallExpression(expr, args)
|
|
elif match("["):
|
|
property = parseComputedMember()
|
|
expr = delegate.createMemberExpression("[", expr, property)
|
|
else:
|
|
property = parseNonComputedMember()
|
|
expr = delegate.createMemberExpression(".", expr, property)
|
|
if marker:
|
|
marker.end()
|
|
marker.apply(expr)
|
|
return expr
|
|
|
|
|
|
def parseLeftHandSideExpression():
|
|
marker = None
|
|
expr = None
|
|
property = None
|
|
marker = createLocationMarker()
|
|
expr = (parseNewExpression()
|
|
if matchKeyword("new") else parsePrimaryExpression())
|
|
while match(".") or match("["):
|
|
if match("["):
|
|
property = parseComputedMember()
|
|
expr = delegate.createMemberExpression("[", expr, property)
|
|
else:
|
|
property = parseNonComputedMember()
|
|
expr = delegate.createMemberExpression(".", expr, property)
|
|
if marker:
|
|
marker.end()
|
|
marker.apply(expr)
|
|
return expr
|
|
|
|
|
|
def parsePostfixExpression():
|
|
expr = None
|
|
token = None
|
|
delegate.markStart()
|
|
expr = parseLeftHandSideExpressionAllowCall()
|
|
if lookahead.type == Token.Punctuator:
|
|
if (match("++") or match("--")) and (not peekLineTerminator()):
|
|
if (strict and
|
|
(expr.type == Syntax.Identifier)) and isRestrictedWord(
|
|
expr.name):
|
|
throwErrorTolerant(jsdict({}), Messages.StrictLHSPostfix)
|
|
if not isLeftHandSide(expr):
|
|
throwError(jsdict({}), Messages.InvalidLHSInAssignment)
|
|
token = lex()
|
|
expr = delegate.createPostfixExpression(token.value, expr)
|
|
return delegate.markEndIf(expr)
|
|
|
|
|
|
def parseUnaryExpression():
|
|
token = None
|
|
expr = None
|
|
delegate.markStart()
|
|
if (lookahead.type != Token.Punctuator) and (lookahead.type !=
|
|
Token.Keyword):
|
|
expr = parsePostfixExpression()
|
|
elif match("++") or match("--"):
|
|
token = lex()
|
|
expr = parseUnaryExpression()
|
|
if (strict and
|
|
(expr.type == Syntax.Identifier)) and isRestrictedWord(expr.name):
|
|
throwErrorTolerant(jsdict({}), Messages.StrictLHSPrefix)
|
|
if not isLeftHandSide(expr):
|
|
throwError(jsdict({}), Messages.InvalidLHSInAssignment)
|
|
expr = delegate.createUnaryExpression(token.value, expr)
|
|
elif ((match("+") or match("-")) or match("~")) or match("!"):
|
|
token = lex()
|
|
expr = parseUnaryExpression()
|
|
expr = delegate.createUnaryExpression(token.value, expr)
|
|
elif (matchKeyword("delete")
|
|
or matchKeyword("void")) or matchKeyword("typeof"):
|
|
token = lex()
|
|
expr = parseUnaryExpression()
|
|
expr = delegate.createUnaryExpression(token.value, expr)
|
|
if (strict and (expr.operator == "delete")) and (
|
|
expr.argument.type == Syntax.Identifier):
|
|
throwErrorTolerant(jsdict({}), Messages.StrictDelete)
|
|
else:
|
|
expr = parsePostfixExpression()
|
|
return delegate.markEndIf(expr)
|
|
|
|
|
|
def binaryPrecedence(token=None, allowIn=None):
|
|
prec = 0
|
|
if (token.type != Token.Punctuator) and (token.type != Token.Keyword):
|
|
return 0
|
|
while 1:
|
|
if token.value == "||":
|
|
prec = 1
|
|
break
|
|
elif token.value == "&&":
|
|
prec = 2
|
|
break
|
|
elif token.value == "|":
|
|
prec = 3
|
|
break
|
|
elif token.value == "^":
|
|
prec = 4
|
|
break
|
|
elif token.value == "&":
|
|
prec = 5
|
|
break
|
|
elif (token.value == "!==") or ((token.value == "===") or
|
|
((token.value == "!=") or
|
|
(token.value == "=="))):
|
|
prec = 6
|
|
break
|
|
elif (token.value == "instanceof") or ((token.value == ">=") or
|
|
((token.value == "<=") or
|
|
((token.value == ">") or
|
|
(token.value == "<")))):
|
|
prec = 7
|
|
break
|
|
elif token.value == "in":
|
|
prec = (7 if allowIn else 0)
|
|
break
|
|
elif (token.value == ">>>") or ((token.value == ">>") or
|
|
(token.value == "<<")):
|
|
prec = 8
|
|
break
|
|
elif (token.value == "-") or (token.value == "+"):
|
|
prec = 9
|
|
break
|
|
elif (token.value == "%") or ((token.value == "/") or
|
|
(token.value == "*")):
|
|
prec = 11
|
|
break
|
|
else:
|
|
break
|
|
break
|
|
return prec
|
|
|
|
|
|
def parseBinaryExpression():
|
|
marker = None
|
|
markers = None
|
|
expr = None
|
|
token = None
|
|
prec = None
|
|
previousAllowIn = None
|
|
stack = None
|
|
right = None
|
|
operator = None
|
|
left = None
|
|
i = None
|
|
previousAllowIn = state.allowIn
|
|
state.allowIn = True
|
|
marker = createLocationMarker()
|
|
left = parseUnaryExpression()
|
|
token = lookahead
|
|
prec = binaryPrecedence(token, previousAllowIn)
|
|
if prec == 0:
|
|
return left
|
|
token.prec = prec
|
|
lex()
|
|
markers = [marker, createLocationMarker()]
|
|
right = parseUnaryExpression()
|
|
stack = [left, token, right]
|
|
prec = binaryPrecedence(lookahead, previousAllowIn)
|
|
while prec > 0:
|
|
while (len(stack) > 2) and (prec <= stack[len(stack) - 2].prec):
|
|
right = stack.pop()
|
|
operator = stack.pop().value
|
|
left = stack.pop()
|
|
expr = delegate.createBinaryExpression(operator, left, right)
|
|
markers.pop()
|
|
marker = markers.pop()
|
|
if marker:
|
|
marker.end()
|
|
marker.apply(expr)
|
|
stack.append(expr)
|
|
markers.append(marker)
|
|
token = lex()
|
|
token.prec = prec
|
|
stack.append(token)
|
|
markers.append(createLocationMarker())
|
|
expr = parseUnaryExpression()
|
|
stack.append(expr)
|
|
prec = binaryPrecedence(lookahead, previousAllowIn)
|
|
state.allowIn = previousAllowIn
|
|
i = len(stack) - 1
|
|
expr = stack[i]
|
|
markers.pop()
|
|
while i > 1:
|
|
expr = delegate.createBinaryExpression(stack[i - 1].value,
|
|
stack[i - 2], expr)
|
|
i -= 2
|
|
marker = markers.pop()
|
|
if marker:
|
|
marker.end()
|
|
marker.apply(expr)
|
|
return expr
|
|
|
|
|
|
def parseConditionalExpression():
|
|
expr = None
|
|
previousAllowIn = None
|
|
consequent = None
|
|
alternate = None
|
|
delegate.markStart()
|
|
expr = parseBinaryExpression()
|
|
if match("?"):
|
|
lex()
|
|
previousAllowIn = state.allowIn
|
|
state.allowIn = True
|
|
consequent = parseAssignmentExpression()
|
|
state.allowIn = previousAllowIn
|
|
expect(":")
|
|
alternate = parseAssignmentExpression()
|
|
expr = delegate.markEnd(
|
|
delegate.createConditionalExpression(expr, consequent, alternate))
|
|
else:
|
|
delegate.markEnd(jsdict({}))
|
|
return expr
|
|
|
|
|
|
def parseAssignmentExpression():
|
|
token = None
|
|
left = None
|
|
right = None
|
|
node = None
|
|
token = lookahead
|
|
delegate.markStart()
|
|
left = parseConditionalExpression()
|
|
node = left
|
|
if matchAssign():
|
|
if not isLeftHandSide(left):
|
|
throwError(jsdict({}), Messages.InvalidLHSInAssignment)
|
|
if (strict and
|
|
(left.type == Syntax.Identifier)) and isRestrictedWord(left.name):
|
|
throwErrorTolerant(token, Messages.StrictLHSAssignment)
|
|
token = lex()
|
|
right = parseAssignmentExpression()
|
|
node = delegate.createAssignmentExpression(token.value, left, right)
|
|
return delegate.markEndIf(node)
|
|
|
|
|
|
def parseExpression():
|
|
expr = None
|
|
delegate.markStart()
|
|
expr = parseAssignmentExpression()
|
|
if match(","):
|
|
expr = delegate.createSequenceExpression([expr])
|
|
while index < length:
|
|
if not match(","):
|
|
break
|
|
lex()
|
|
expr.expressions.append(parseAssignmentExpression())
|
|
return delegate.markEndIf(expr)
|
|
|
|
|
|
def parseStatementList():
|
|
list__py__ = []
|
|
statement = None
|
|
while index < length:
|
|
if match("}"):
|
|
break
|
|
statement = parseSourceElement()
|
|
if ('undefined' if not 'statement' in locals() else
|
|
typeof(statement)) == "undefined":
|
|
break
|
|
list__py__.append(statement)
|
|
return list__py__
|
|
|
|
|
|
def parseBlock():
|
|
block = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
expect("{")
|
|
block = parseStatementList()
|
|
expect("}")
|
|
return delegate.markEnd(delegate.createBlockStatement(block))
|
|
|
|
|
|
def parseVariableIdentifier():
|
|
token = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
token = lex()
|
|
if token.type != Token.Identifier:
|
|
throwUnexpected(token)
|
|
return delegate.markEnd(delegate.createIdentifier(token.value))
|
|
|
|
|
|
def parseVariableDeclaration(kind=None):
|
|
init = None
|
|
id = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
id = parseVariableIdentifier()
|
|
if strict and isRestrictedWord(id.name):
|
|
throwErrorTolerant(jsdict({}), Messages.StrictVarName)
|
|
if kind == "const":
|
|
expect("=")
|
|
init = parseAssignmentExpression()
|
|
elif match("="):
|
|
lex()
|
|
init = parseAssignmentExpression()
|
|
return delegate.markEnd(delegate.createVariableDeclarator(id, init))
|
|
|
|
|
|
def parseVariableDeclarationList(kind=None):
|
|
list__py__ = []
|
|
while 1:
|
|
list__py__.append(parseVariableDeclaration(kind))
|
|
if not match(","):
|
|
break
|
|
lex()
|
|
if not (index < length):
|
|
break
|
|
return list__py__
|
|
|
|
|
|
def parseVariableStatement():
|
|
declarations = None
|
|
expectKeyword("var")
|
|
declarations = parseVariableDeclarationList()
|
|
consumeSemicolon()
|
|
return delegate.createVariableDeclaration(declarations, "var")
|
|
|
|
|
|
def parseConstLetDeclaration(kind=None):
|
|
declarations = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
expectKeyword(kind)
|
|
declarations = parseVariableDeclarationList(kind)
|
|
consumeSemicolon()
|
|
return delegate.markEnd(
|
|
delegate.createVariableDeclaration(declarations, kind))
|
|
|
|
|
|
def parseEmptyStatement():
|
|
expect(";")
|
|
return delegate.createEmptyStatement()
|
|
|
|
|
|
def parseExpressionStatement():
|
|
expr = parseExpression()
|
|
consumeSemicolon()
|
|
return delegate.createExpressionStatement(expr)
|
|
|
|
|
|
def parseIfStatement():
|
|
test = None
|
|
consequent = None
|
|
alternate = None
|
|
expectKeyword("if")
|
|
expect("(")
|
|
test = parseExpression()
|
|
expect(")")
|
|
consequent = parseStatement()
|
|
if matchKeyword("else"):
|
|
lex()
|
|
alternate = parseStatement()
|
|
else:
|
|
alternate = None
|
|
return delegate.createIfStatement(test, consequent, alternate)
|
|
|
|
|
|
def parseDoWhileStatement():
|
|
body = None
|
|
test = None
|
|
oldInIteration = None
|
|
expectKeyword("do")
|
|
oldInIteration = state.inIteration
|
|
state.inIteration = True
|
|
body = parseStatement()
|
|
state.inIteration = oldInIteration
|
|
expectKeyword("while")
|
|
expect("(")
|
|
test = parseExpression()
|
|
expect(")")
|
|
if match(";"):
|
|
lex()
|
|
return delegate.createDoWhileStatement(body, test)
|
|
|
|
|
|
def parseWhileStatement():
|
|
test = None
|
|
body = None
|
|
oldInIteration = None
|
|
expectKeyword("while")
|
|
expect("(")
|
|
test = parseExpression()
|
|
expect(")")
|
|
oldInIteration = state.inIteration
|
|
state.inIteration = True
|
|
body = parseStatement()
|
|
state.inIteration = oldInIteration
|
|
return delegate.createWhileStatement(test, body)
|
|
|
|
|
|
def parseForVariableDeclaration():
|
|
token = None
|
|
declarations = None
|
|
delegate.markStart()
|
|
token = lex()
|
|
declarations = parseVariableDeclarationList()
|
|
return delegate.markEnd(
|
|
delegate.createVariableDeclaration(declarations, token.value))
|
|
|
|
|
|
def parseForStatement():
|
|
init = None
|
|
test = None
|
|
update = None
|
|
left = None
|
|
right = None
|
|
body = None
|
|
oldInIteration = None
|
|
update = None
|
|
test = update
|
|
init = test
|
|
expectKeyword("for")
|
|
expect("(")
|
|
if match(";"):
|
|
lex()
|
|
else:
|
|
if matchKeyword("var") or matchKeyword("let"):
|
|
state.allowIn = False
|
|
init = parseForVariableDeclaration()
|
|
state.allowIn = True
|
|
if (len(init.declarations) == 1) and matchKeyword("in"):
|
|
lex()
|
|
left = init
|
|
right = parseExpression()
|
|
init = None
|
|
else:
|
|
state.allowIn = False
|
|
init = parseExpression()
|
|
state.allowIn = True
|
|
if matchKeyword("in"):
|
|
if not isLeftHandSide(init):
|
|
throwError(jsdict({}), Messages.InvalidLHSInForIn)
|
|
lex()
|
|
left = init
|
|
right = parseExpression()
|
|
init = None
|
|
if ('undefined'
|
|
if not 'left' in locals() else typeof(left)) == "undefined":
|
|
expect(";")
|
|
if ('undefined'
|
|
if not 'left' in locals() else typeof(left)) == "undefined":
|
|
if not match(";"):
|
|
test = parseExpression()
|
|
expect(";")
|
|
if not match(")"):
|
|
update = parseExpression()
|
|
expect(")")
|
|
oldInIteration = state.inIteration
|
|
state.inIteration = True
|
|
body = parseStatement()
|
|
state.inIteration = oldInIteration
|
|
return (delegate.createForStatement(init, test, update, body) if (
|
|
'undefined' if not 'left' in locals() else typeof(left)) == "undefined"
|
|
else delegate.createForInStatement(left, right, body))
|
|
|
|
|
|
def parseContinueStatement():
|
|
label = None
|
|
key = None
|
|
expectKeyword("continue")
|
|
if (ord(source[index]) if index < len(source) else None) == 59:
|
|
lex()
|
|
if not state.inIteration:
|
|
throwError(jsdict({}), Messages.IllegalContinue)
|
|
return delegate.createContinueStatement(None)
|
|
if peekLineTerminator():
|
|
if not state.inIteration:
|
|
throwError(jsdict({}), Messages.IllegalContinue)
|
|
return delegate.createContinueStatement(None)
|
|
if lookahead.type == Token.Identifier:
|
|
label = parseVariableIdentifier()
|
|
key = "$" + label.name
|
|
if not (key in state.labelSet):
|
|
throwError(jsdict({}), Messages.UnknownLabel, label.name)
|
|
consumeSemicolon()
|
|
if (label == None) and (not state.inIteration):
|
|
throwError(jsdict({}), Messages.IllegalContinue)
|
|
return delegate.createContinueStatement(label)
|
|
|
|
|
|
def parseBreakStatement():
|
|
label = None
|
|
key = None
|
|
expectKeyword("break")
|
|
if (ord(source[index]) if index < len(source) else None) == 59:
|
|
lex()
|
|
if not (state.inIteration or state.inSwitch):
|
|
throwError(jsdict({}), Messages.IllegalBreak)
|
|
return delegate.createBreakStatement(None)
|
|
if peekLineTerminator():
|
|
if not (state.inIteration or state.inSwitch):
|
|
throwError(jsdict({}), Messages.IllegalBreak)
|
|
return delegate.createBreakStatement(None)
|
|
if lookahead.type == Token.Identifier:
|
|
label = parseVariableIdentifier()
|
|
key = "$" + label.name
|
|
if not (key in state.labelSet):
|
|
throwError(jsdict({}), Messages.UnknownLabel, label.name)
|
|
consumeSemicolon()
|
|
if (label == None) and (not (state.inIteration or state.inSwitch)):
|
|
throwError(jsdict({}), Messages.IllegalBreak)
|
|
return delegate.createBreakStatement(label)
|
|
|
|
|
|
def parseReturnStatement():
|
|
argument = None
|
|
expectKeyword("return")
|
|
if not state.inFunctionBody:
|
|
throwErrorTolerant(jsdict({}), Messages.IllegalReturn)
|
|
if (ord(source[index]) if index < len(source) else None) == 32:
|
|
if isIdentifierStart((ord(source[index + 1]) if
|
|
(index + 1) < len(source) else None)):
|
|
argument = parseExpression()
|
|
consumeSemicolon()
|
|
return delegate.createReturnStatement(argument)
|
|
if peekLineTerminator():
|
|
return delegate.createReturnStatement(None)
|
|
if not match(";"):
|
|
if (not match("}")) and (lookahead.type != Token.EOF):
|
|
argument = parseExpression()
|
|
consumeSemicolon()
|
|
return delegate.createReturnStatement(argument)
|
|
|
|
|
|
def parseWithStatement():
|
|
object = None
|
|
body = None
|
|
if strict:
|
|
throwErrorTolerant(jsdict({}), Messages.StrictModeWith)
|
|
expectKeyword("with")
|
|
expect("(")
|
|
object = parseExpression()
|
|
expect(")")
|
|
body = parseStatement()
|
|
return delegate.createWithStatement(object, body)
|
|
|
|
|
|
def parseSwitchCase():
|
|
test = None
|
|
consequent = []
|
|
statement = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
if matchKeyword("default"):
|
|
lex()
|
|
test = None
|
|
else:
|
|
expectKeyword("case")
|
|
test = parseExpression()
|
|
expect(":")
|
|
while index < length:
|
|
if (match("}") or matchKeyword("default")) or matchKeyword("case"):
|
|
break
|
|
statement = parseStatement()
|
|
consequent.append(statement)
|
|
return delegate.markEnd(delegate.createSwitchCase(test, consequent))
|
|
|
|
|
|
def parseSwitchStatement():
|
|
discriminant = None
|
|
cases = None
|
|
clause = None
|
|
oldInSwitch = None
|
|
defaultFound = None
|
|
expectKeyword("switch")
|
|
expect("(")
|
|
discriminant = parseExpression()
|
|
expect(")")
|
|
expect("{")
|
|
if match("}"):
|
|
lex()
|
|
return delegate.createSwitchStatement(discriminant)
|
|
cases = []
|
|
oldInSwitch = state.inSwitch
|
|
state.inSwitch = True
|
|
defaultFound = False
|
|
while index < length:
|
|
if match("}"):
|
|
break
|
|
clause = parseSwitchCase()
|
|
if clause.test == None:
|
|
if defaultFound:
|
|
throwError(jsdict({}), Messages.MultipleDefaultsInSwitch)
|
|
defaultFound = True
|
|
cases.append(clause)
|
|
state.inSwitch = oldInSwitch
|
|
expect("}")
|
|
return delegate.createSwitchStatement(discriminant, cases)
|
|
|
|
|
|
def parseThrowStatement():
|
|
argument = None
|
|
expectKeyword("throw")
|
|
if peekLineTerminator():
|
|
throwError(jsdict({}), Messages.NewlineAfterThrow)
|
|
argument = parseExpression()
|
|
consumeSemicolon()
|
|
return delegate.createThrowStatement(argument)
|
|
|
|
|
|
def parseCatchClause():
|
|
param = None
|
|
body = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
expectKeyword("catch")
|
|
expect("(")
|
|
if match(")"):
|
|
throwUnexpected(lookahead)
|
|
param = parseVariableIdentifier()
|
|
if strict and isRestrictedWord(param.name):
|
|
throwErrorTolerant(jsdict({}), Messages.StrictCatchVariable)
|
|
expect(")")
|
|
body = parseBlock()
|
|
return delegate.markEnd(delegate.createCatchClause(param, body))
|
|
|
|
|
|
def parseTryStatement():
|
|
block = None
|
|
handlers = []
|
|
finalizer = None
|
|
expectKeyword("try")
|
|
block = parseBlock()
|
|
if matchKeyword("catch"):
|
|
handlers.append(parseCatchClause())
|
|
if matchKeyword("finally"):
|
|
lex()
|
|
finalizer = parseBlock()
|
|
if (len(handlers) == 0) and (not finalizer):
|
|
throwError(jsdict({}), Messages.NoCatchOrFinally)
|
|
return delegate.createTryStatement(block, [], handlers, finalizer)
|
|
|
|
|
|
def parseDebuggerStatement():
|
|
expectKeyword("debugger")
|
|
consumeSemicolon()
|
|
return delegate.createDebuggerStatement()
|
|
|
|
|
|
def parseStatement():
|
|
type = lookahead.type
|
|
expr = None
|
|
labeledBody = None
|
|
key = None
|
|
if type == Token.EOF:
|
|
throwUnexpected(lookahead)
|
|
skipComment()
|
|
delegate.markStart()
|
|
if type == Token.Punctuator:
|
|
while 1:
|
|
if lookahead.value == ";":
|
|
return delegate.markEnd(parseEmptyStatement())
|
|
elif lookahead.value == "{":
|
|
return delegate.markEnd(parseBlock())
|
|
elif lookahead.value == "(":
|
|
return delegate.markEnd(parseExpressionStatement())
|
|
else:
|
|
break
|
|
break
|
|
if type == Token.Keyword:
|
|
while 1:
|
|
if lookahead.value == "break":
|
|
return delegate.markEnd(parseBreakStatement())
|
|
elif lookahead.value == "continue":
|
|
return delegate.markEnd(parseContinueStatement())
|
|
elif lookahead.value == "debugger":
|
|
return delegate.markEnd(parseDebuggerStatement())
|
|
elif lookahead.value == "do":
|
|
return delegate.markEnd(parseDoWhileStatement())
|
|
elif lookahead.value == "for":
|
|
return delegate.markEnd(parseForStatement())
|
|
elif lookahead.value == "function":
|
|
return delegate.markEnd(parseFunctionDeclaration())
|
|
elif lookahead.value == "if":
|
|
return delegate.markEnd(parseIfStatement())
|
|
elif lookahead.value == "return":
|
|
return delegate.markEnd(parseReturnStatement())
|
|
elif lookahead.value == "switch":
|
|
return delegate.markEnd(parseSwitchStatement())
|
|
elif lookahead.value == "throw":
|
|
return delegate.markEnd(parseThrowStatement())
|
|
elif lookahead.value == "try":
|
|
return delegate.markEnd(parseTryStatement())
|
|
elif lookahead.value == "var":
|
|
return delegate.markEnd(parseVariableStatement())
|
|
elif lookahead.value == "while":
|
|
return delegate.markEnd(parseWhileStatement())
|
|
elif lookahead.value == "with":
|
|
return delegate.markEnd(parseWithStatement())
|
|
else:
|
|
break
|
|
break
|
|
expr = parseExpression()
|
|
if (expr.type == Syntax.Identifier) and match(":"):
|
|
lex()
|
|
key = "$" + expr.name
|
|
if key in state.labelSet:
|
|
throwError(jsdict({}), Messages.Redeclaration, "Label", expr.name)
|
|
state.labelSet[key] = True
|
|
labeledBody = parseStatement()
|
|
del state.labelSet[key]
|
|
return delegate.markEnd(
|
|
delegate.createLabeledStatement(expr, labeledBody))
|
|
consumeSemicolon()
|
|
return delegate.markEnd(delegate.createExpressionStatement(expr))
|
|
|
|
|
|
def parseFunctionSourceElements():
|
|
global strict
|
|
sourceElement = None
|
|
sourceElements = []
|
|
token = None
|
|
directive = None
|
|
firstRestricted = None
|
|
oldLabelSet = None
|
|
oldInIteration = None
|
|
oldInSwitch = None
|
|
oldInFunctionBody = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
expect("{")
|
|
while index < length:
|
|
if lookahead.type != Token.StringLiteral:
|
|
break
|
|
token = lookahead
|
|
sourceElement = parseSourceElement()
|
|
sourceElements.append(sourceElement)
|
|
if sourceElement.expression.type != Syntax.Literal:
|
|
break
|
|
directive = source[(token.range[0] + 1):(token.range[1] - 1)]
|
|
if directive == "use strict":
|
|
strict = True
|
|
if firstRestricted:
|
|
throwErrorTolerant(firstRestricted,
|
|
Messages.StrictOctalLiteral)
|
|
else:
|
|
if (not firstRestricted) and token.octal:
|
|
firstRestricted = token
|
|
oldLabelSet = state.labelSet
|
|
oldInIteration = state.inIteration
|
|
oldInSwitch = state.inSwitch
|
|
oldInFunctionBody = state.inFunctionBody
|
|
state.labelSet = jsdict({})
|
|
state.inIteration = False
|
|
state.inSwitch = False
|
|
state.inFunctionBody = True
|
|
while index < length:
|
|
if match("}"):
|
|
break
|
|
sourceElement = parseSourceElement()
|
|
if ('undefined' if not 'sourceElement' in locals() else
|
|
typeof(sourceElement)) == "undefined":
|
|
break
|
|
sourceElements.append(sourceElement)
|
|
expect("}")
|
|
state.labelSet = oldLabelSet
|
|
state.inIteration = oldInIteration
|
|
state.inSwitch = oldInSwitch
|
|
state.inFunctionBody = oldInFunctionBody
|
|
return delegate.markEnd(delegate.createBlockStatement(sourceElements))
|
|
|
|
|
|
def parseParams(firstRestricted=None):
|
|
param = None
|
|
params = []
|
|
token = None
|
|
stricted = None
|
|
paramSet = None
|
|
key = None
|
|
message = None
|
|
expect("(")
|
|
if not match(")"):
|
|
paramSet = jsdict({})
|
|
while index < length:
|
|
token = lookahead
|
|
param = parseVariableIdentifier()
|
|
key = "$" + token.value
|
|
if strict:
|
|
if isRestrictedWord(token.value):
|
|
stricted = token
|
|
message = Messages.StrictParamName
|
|
if key in paramSet:
|
|
stricted = token
|
|
message = Messages.StrictParamDupe
|
|
elif not firstRestricted:
|
|
if isRestrictedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictParamName
|
|
elif isStrictModeReservedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictReservedWord
|
|
elif key in paramSet:
|
|
firstRestricted = token
|
|
message = Messages.StrictParamDupe
|
|
params.append(param)
|
|
paramSet[key] = True
|
|
if match(")"):
|
|
break
|
|
expect(",")
|
|
expect(")")
|
|
return jsdict({
|
|
"params": params,
|
|
"stricted": stricted,
|
|
"firstRestricted": firstRestricted,
|
|
"message": message,
|
|
})
|
|
|
|
|
|
def parseFunctionDeclaration():
|
|
global strict
|
|
id = None
|
|
params = []
|
|
body = None
|
|
token = None
|
|
stricted = None
|
|
tmp = None
|
|
firstRestricted = None
|
|
message = None
|
|
previousStrict = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
expectKeyword("function")
|
|
token = lookahead
|
|
id = parseVariableIdentifier()
|
|
if strict:
|
|
if isRestrictedWord(token.value):
|
|
throwErrorTolerant(token, Messages.StrictFunctionName)
|
|
else:
|
|
if isRestrictedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictFunctionName
|
|
elif isStrictModeReservedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictReservedWord
|
|
tmp = parseParams(firstRestricted)
|
|
params = tmp.params
|
|
stricted = tmp.stricted
|
|
firstRestricted = tmp.firstRestricted
|
|
if tmp.message:
|
|
message = tmp.message
|
|
previousStrict = strict
|
|
body = parseFunctionSourceElements()
|
|
if strict and firstRestricted:
|
|
throwError(firstRestricted, message)
|
|
if strict and stricted:
|
|
throwErrorTolerant(stricted, message)
|
|
strict = previousStrict
|
|
return delegate.markEnd(
|
|
delegate.createFunctionDeclaration(id, params, [], body))
|
|
|
|
|
|
def parseFunctionExpression():
|
|
global strict
|
|
token = None
|
|
id = None
|
|
stricted = None
|
|
firstRestricted = None
|
|
message = None
|
|
tmp = None
|
|
params = []
|
|
body = None
|
|
previousStrict = None
|
|
delegate.markStart()
|
|
expectKeyword("function")
|
|
if not match("("):
|
|
token = lookahead
|
|
id = parseVariableIdentifier()
|
|
if strict:
|
|
if isRestrictedWord(token.value):
|
|
throwErrorTolerant(token, Messages.StrictFunctionName)
|
|
else:
|
|
if isRestrictedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictFunctionName
|
|
elif isStrictModeReservedWord(token.value):
|
|
firstRestricted = token
|
|
message = Messages.StrictReservedWord
|
|
tmp = parseParams(firstRestricted)
|
|
params = tmp.params
|
|
stricted = tmp.stricted
|
|
firstRestricted = tmp.firstRestricted
|
|
if tmp.message:
|
|
message = tmp.message
|
|
previousStrict = strict
|
|
body = parseFunctionSourceElements()
|
|
if strict and firstRestricted:
|
|
throwError(firstRestricted, message)
|
|
if strict and stricted:
|
|
throwErrorTolerant(stricted, message)
|
|
strict = previousStrict
|
|
return delegate.markEnd(
|
|
delegate.createFunctionExpression(id, params, [], body))
|
|
|
|
|
|
def parseSourceElement():
|
|
if lookahead.type == Token.Keyword:
|
|
while 1:
|
|
if (lookahead.value == "let") or (lookahead.value == "const"):
|
|
return parseConstLetDeclaration(lookahead.value)
|
|
elif lookahead.value == "function":
|
|
return parseFunctionDeclaration()
|
|
else:
|
|
return parseStatement()
|
|
break
|
|
if lookahead.type != Token.EOF:
|
|
return parseStatement()
|
|
|
|
|
|
def parseSourceElements():
|
|
global strict
|
|
sourceElement = None
|
|
sourceElements = []
|
|
token = None
|
|
directive = None
|
|
firstRestricted = None
|
|
while index < length:
|
|
token = lookahead
|
|
if token.type != Token.StringLiteral:
|
|
break
|
|
sourceElement = parseSourceElement()
|
|
sourceElements.append(sourceElement)
|
|
if sourceElement.expression.type != Syntax.Literal:
|
|
break
|
|
directive = source[(token.range[0] + 1):(token.range[1] - 1)]
|
|
if directive == "use strict":
|
|
strict = True
|
|
if firstRestricted:
|
|
throwErrorTolerant(firstRestricted,
|
|
Messages.StrictOctalLiteral)
|
|
else:
|
|
if (not firstRestricted) and token.octal:
|
|
firstRestricted = token
|
|
while index < length:
|
|
sourceElement = parseSourceElement()
|
|
if ('undefined' if not 'sourceElement' in locals() else
|
|
typeof(sourceElement)) == "undefined":
|
|
break
|
|
sourceElements.append(sourceElement)
|
|
return sourceElements
|
|
|
|
|
|
def parseProgram():
|
|
global strict
|
|
body = None
|
|
skipComment()
|
|
delegate.markStart()
|
|
strict = False
|
|
peek()
|
|
body = parseSourceElements()
|
|
return delegate.markEnd(delegate.createProgram(body))
|
|
|
|
|
|
def collectToken():
|
|
start = None
|
|
loc = None
|
|
token = None
|
|
range = None
|
|
value = None
|
|
skipComment()
|
|
start = index
|
|
loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
}),
|
|
})
|
|
token = extra.advance()
|
|
loc.end = jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
})
|
|
if token.type != Token.EOF:
|
|
range = [token.range[0], token.range[1]]
|
|
value = source[token.range[0]:token.range[1]]
|
|
extra.tokens.append(
|
|
jsdict({
|
|
"type": TokenName[token.type],
|
|
"value": value,
|
|
"range": range,
|
|
"loc": loc,
|
|
}))
|
|
return token
|
|
|
|
|
|
def collectRegex():
|
|
pos = None
|
|
loc = None
|
|
regex = None
|
|
token = None
|
|
skipComment()
|
|
pos = index
|
|
loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
}),
|
|
})
|
|
regex = extra.scanRegExp()
|
|
loc.end = jsdict({
|
|
"line": lineNumber,
|
|
"column": index - lineStart,
|
|
})
|
|
if not extra.tokenize:
|
|
if len(extra.tokens) > 0:
|
|
token = extra.tokens[len(extra.tokens) - 1]
|
|
if (token.range[0] == pos) and (token.type == "Punctuator"):
|
|
if (token.value == "/") or (token.value == "/="):
|
|
extra.tokens.pop()
|
|
extra.tokens.append(
|
|
jsdict({
|
|
"type": "RegularExpression",
|
|
"value": regex.literal,
|
|
"range": [pos, index],
|
|
"loc": loc,
|
|
}))
|
|
return regex
|
|
|
|
|
|
def filterTokenLocation():
|
|
i = None
|
|
entry = None
|
|
token = None
|
|
tokens = []
|
|
i = 0
|
|
while 1:
|
|
if not (i < len(extra.tokens)):
|
|
break
|
|
entry = extra.tokens[i]
|
|
token = jsdict({
|
|
"type": entry.type,
|
|
"value": entry.value,
|
|
})
|
|
if extra.range:
|
|
token.range = entry.range
|
|
if extra.loc:
|
|
token.loc = entry.loc
|
|
tokens.append(token)
|
|
i += 1
|
|
extra.tokens = tokens
|
|
|
|
|
|
class LocationMarker(object):
|
|
def __init__(self=None):
|
|
self.marker = [index, lineNumber, index - lineStart, 0, 0, 0]
|
|
|
|
def end(self=None):
|
|
self.marker[3] = index
|
|
self.marker[4] = lineNumber
|
|
self.marker[5] = index - lineStart
|
|
|
|
def apply(self=None, node=None):
|
|
if extra.range:
|
|
node.range = [self.marker[0], self.marker[3]]
|
|
if extra.loc:
|
|
node.loc = jsdict({
|
|
"start":
|
|
jsdict({
|
|
"line": self.marker[1],
|
|
"column": self.marker[2],
|
|
}),
|
|
"end":
|
|
jsdict({
|
|
"line": self.marker[4],
|
|
"column": self.marker[5],
|
|
}),
|
|
})
|
|
node = delegate.postProcess(node)
|
|
|
|
|
|
def createLocationMarker():
|
|
if (not extra.loc) and (not extra.range):
|
|
return None
|
|
skipComment()
|
|
return LocationMarker()
|
|
|
|
|
|
def patch():
|
|
global advance, scanRegExp
|
|
if ('undefined' if not ('tokens' in extra) else typeof(
|
|
extra.tokens)) != "undefined":
|
|
extra.advance = advance
|
|
extra.scanRegExp = scanRegExp
|
|
advance = collectToken
|
|
scanRegExp = collectRegex
|
|
|
|
|
|
def unpatch():
|
|
global advance, scanRegExp
|
|
if ('undefined' if not ('scanRegExp' in extra) else typeof(
|
|
extra.scanRegExp)) == "function":
|
|
advance = extra.advance
|
|
scanRegExp = extra.scanRegExp
|
|
|
|
|
|
def tokenize(code, **options):
|
|
global delegate, source, index, lineNumber, lineStart, length, lookahead, state, extra
|
|
options = jsdict(options)
|
|
toString = None
|
|
token = None
|
|
tokens = None
|
|
toString = str
|
|
if (('undefined' if not 'code' in locals() else typeof(code)) !=
|
|
"string") and (not isinstance(code, str)):
|
|
code = toString(code)
|
|
delegate = SyntaxTreeDelegate
|
|
source = code
|
|
index = 0
|
|
lineNumber = (1 if len(source) > 0 else 0)
|
|
lineStart = 0
|
|
length = len(source)
|
|
lookahead = None
|
|
state = jsdict({
|
|
"allowIn": True,
|
|
"labelSet": jsdict({}),
|
|
"inFunctionBody": False,
|
|
"inIteration": False,
|
|
"inSwitch": False,
|
|
"lastCommentStart": -1,
|
|
})
|
|
extra = jsdict({})
|
|
options = options or jsdict({})
|
|
options.tokens = True
|
|
extra.tokens = []
|
|
extra.tokenize = True
|
|
extra.openParenToken = -1
|
|
extra.openCurlyToken = -1
|
|
extra.range = (('undefined' if not ('range' in options) else typeof(
|
|
options.range)) == "boolean") and options.range
|
|
extra.loc = (('undefined' if not ('loc' in options) else typeof(
|
|
options.loc)) == "boolean") and options.loc
|
|
if (('undefined' if not ('comment' in options) else typeof(
|
|
options.comment)) == "boolean") and options.comment:
|
|
extra.comments = []
|
|
if (('undefined' if not ('tolerant' in options) else typeof(
|
|
options.tolerant)) == "boolean") and options.tolerant:
|
|
extra.errors = []
|
|
if length > 0:
|
|
if (typeof(source[0])) == "undefined":
|
|
if isinstance(code, str):
|
|
source = code.valueOf()
|
|
patch()
|
|
try:
|
|
peek()
|
|
if lookahead.type == Token.EOF:
|
|
return extra.tokens
|
|
token = lex()
|
|
while lookahead.type != Token.EOF:
|
|
try:
|
|
token = lex()
|
|
except Exception as lexError:
|
|
token = lookahead
|
|
if extra.errors:
|
|
extra.errors.append(lexError)
|
|
break
|
|
else:
|
|
raise
|
|
filterTokenLocation()
|
|
tokens = extra.tokens
|
|
if ('undefined' if not ('comments' in extra) else typeof(
|
|
extra.comments)) != "undefined":
|
|
tokens.comments = extra.comments
|
|
if ('undefined' if not ('errors' in extra) else typeof(
|
|
extra.errors)) != "undefined":
|
|
tokens.errors = extra.errors
|
|
except Exception as e:
|
|
raise
|
|
finally:
|
|
unpatch()
|
|
extra = jsdict({})
|
|
return tokens
|
|
|
|
|
|
def parse(code, **options):
|
|
global delegate, source, index, lineNumber, lineStart, length, lookahead, state, extra
|
|
options = jsdict(options)
|
|
program = None
|
|
toString = None
|
|
toString = str
|
|
if (('undefined' if not 'code' in locals() else typeof(code)) !=
|
|
"string") and (not isinstance(code, str)):
|
|
code = toString(code)
|
|
delegate = SyntaxTreeDelegate
|
|
source = code
|
|
index = 0
|
|
lineNumber = (1 if len(source) > 0 else 0)
|
|
lineStart = 0
|
|
length = len(source)
|
|
lookahead = None
|
|
state = jsdict({
|
|
"allowIn": True,
|
|
"labelSet": jsdict({}),
|
|
"inFunctionBody": False,
|
|
"inIteration": False,
|
|
"inSwitch": False,
|
|
"lastCommentStart": -1,
|
|
"markerStack": [],
|
|
})
|
|
extra = jsdict({})
|
|
if ('undefined'
|
|
if not 'options' in locals() else typeof(options)) != "undefined":
|
|
extra.range = (('undefined' if not ('range' in options) else typeof(
|
|
options.range)) == "boolean") and options.range
|
|
extra.loc = (('undefined' if not ('loc' in options) else typeof(
|
|
options.loc)) == "boolean") and options.loc
|
|
if (extra.loc and
|
|
(options.source != None)) and (options.source != undefined):
|
|
extra.source = toString(options.source)
|
|
if (('undefined' if not ('tokens' in options) else typeof(
|
|
options.tokens)) == "boolean") and options.tokens:
|
|
extra.tokens = []
|
|
if (('undefined' if not ('comment' in options) else typeof(
|
|
options.comment)) == "boolean") and options.comment:
|
|
extra.comments = []
|
|
if (('undefined' if not ('tolerant' in options) else typeof(
|
|
options.tolerant)) == "boolean") and options.tolerant:
|
|
extra.errors = []
|
|
if length > 0:
|
|
if (typeof(source[0])) == "undefined":
|
|
if isinstance(code, str):
|
|
source = code.valueOf()
|
|
patch()
|
|
try:
|
|
program = parseProgram()
|
|
if ('undefined' if not ('comments' in extra) else typeof(
|
|
extra.comments)) != "undefined":
|
|
program.comments = extra.comments
|
|
if ('undefined' if not ('tokens' in extra) else typeof(
|
|
extra.tokens)) != "undefined":
|
|
filterTokenLocation()
|
|
program.tokens = extra.tokens
|
|
if ('undefined' if not ('errors' in extra) else typeof(
|
|
extra.errors)) != "undefined":
|
|
program.errors = extra.errors
|
|
except Exception as e:
|
|
raise
|
|
finally:
|
|
unpatch()
|
|
extra = jsdict({})
|
|
return program
|
|
|
|
|
|
parse('var = 490 \n a=4;')
|