1# JUST FOR NOW, later I will write my own - much faster and better.
2
3#  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
4#  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
5#  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
6#  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
7#  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
8#  Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
9#  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
10#  Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
11#  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
12#
13#  Redistribution and use in source and binary forms, with or without
14#  modification, are permitted provided that the following conditions are met:
15#
16#    * Redistributions of source code must retain the above copyright
17#      notice, this list of conditions and the following disclaimer.
18#    * Redistributions in binary form must reproduce the above copyright
19#      notice, this list of conditions and the following disclaimer in the
20#      documentation and/or other materials provided with the distribution.
21#
22#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25#  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
26#  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27#  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28#  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29#  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31#  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33# -*- coding: latin-1 -*-
34from __future__ import print_function
35import re
36
37
38def typeof(t):
39    if t is None: return 'undefined'
40    elif isinstance(t, bool): return 'boolean'
41    elif isinstance(t, str): return 'string'
42    elif isinstance(t, int) or isinstance(t, float): return 'number'
43    elif hasattr(t, '__call__'): return 'function'
44    else: return 'object'
45
46
47def list_indexOf(l, v):
48    try:
49        return l.index(v)
50    except:
51        return -1
52
53
54parseFloat = float
55parseInt = int
56
57
58class jsdict(object):
59    def __init__(self, d):
60        self.__dict__.update(d)
61
62    def __getitem__(self, name):
63        if name in self.__dict__:
64            return self.__dict__[name]
65        else:
66            return None
67
68    def __setitem__(self, name, value):
69        self.__dict__[name] = value
70        return value
71
72    def __getattr__(self, name):
73        try:
74            return getattr(self, name)
75        except:
76            return None
77
78    def __setattr__(self, name, value):
79        self[name] = value
80        return value
81
82    def __contains__(self, name):
83        return name in self.__dict__
84
85    def __repr__(self):
86        return str(self.__dict__)
87
88
89class RegExp(object):
90    def __init__(self, pattern, flags=''):
91        self.flags = flags
92        pyflags = 0 | re.M if 'm' in flags else 0 | re.I if 'i' in flags else 0
93        self.source = pattern
94        self.pattern = re.compile(pattern, pyflags)
95
96    def test(self, s):
97        return self.pattern.search(s) is not None
98
99
100console = jsdict({"log": print})
101
102
103def __temp__42(object=None, body=None):
104    return jsdict({
105        "type": Syntax.WithStatement,
106        "object": object,
107        "body": body,
108    })
109
110
111def __temp__41(test=None, body=None):
112    return jsdict({
113        "type": Syntax.WhileStatement,
114        "test": test,
115        "body": body,
116    })
117
118
119def __temp__40(id=None, init=None):
120    return jsdict({
121        "type": Syntax.VariableDeclarator,
122        "id": id,
123        "init": init,
124    })
125
126
127def __temp__39(declarations=None, kind=None):
128    return jsdict({
129        "type": Syntax.VariableDeclaration,
130        "declarations": declarations,
131        "kind": kind,
132    })
133
134
135def __temp__38(operator=None, argument=None):
136    if (operator == "++") or (operator == "--"):
137        return jsdict({
138            "type": Syntax.UpdateExpression,
139            "operator": operator,
140            "argument": argument,
141            "prefix": True,
142        })
143    return jsdict({
144        "type": Syntax.UnaryExpression,
145        "operator": operator,
146        "argument": argument,
147        "prefix": True,
148    })
149
150
151def __temp__37(block=None, guardedHandlers=None, handlers=None,
152               finalizer=None):
153    return jsdict({
154        "type": Syntax.TryStatement,
155        "block": block,
156        "guardedHandlers": guardedHandlers,
157        "handlers": handlers,
158        "finalizer": finalizer,
159    })
160
161
162def __temp__36(argument=None):
163    return jsdict({
164        "type": Syntax.ThrowStatement,
165        "argument": argument,
166    })
167
168
169def __temp__35():
170    return jsdict({
171        "type": Syntax.ThisExpression,
172    })
173
174
175def __temp__34(discriminant=None, cases=None):
176    return jsdict({
177        "type": Syntax.SwitchStatement,
178        "discriminant": discriminant,
179        "cases": cases,
180    })
181
182
183def __temp__33(test=None, consequent=None):
184    return jsdict({
185        "type": Syntax.SwitchCase,
186        "test": test,
187        "consequent": consequent,
188    })
189
190
191def __temp__32(expressions=None):
192    return jsdict({
193        "type": Syntax.SequenceExpression,
194        "expressions": expressions,
195    })
196
197
198def __temp__31(argument=None):
199    return jsdict({
200        "type": Syntax.ReturnStatement,
201        "argument": argument,
202    })
203
204
205def __temp__30(kind=None, key=None, value=None):
206    return jsdict({
207        "type": Syntax.Property,
208        "key": key,
209        "value": value,
210        "kind": kind,
211    })
212
213
214def __temp__29(body=None):
215    return jsdict({
216        "type": Syntax.Program,
217        "body": body,
218    })
219
220
221def __temp__28(operator=None, argument=None):
222    return jsdict({
223        "type": Syntax.UpdateExpression,
224        "operator": operator,
225        "argument": argument,
226        "prefix": False,
227    })
228
229
230def __temp__27(properties=None):
231    return jsdict({
232        "type": Syntax.ObjectExpression,
233        "properties": properties,
234    })
235
236
237def __temp__26(callee=None, args=None):
238    return jsdict({
239        "type": Syntax.NewExpression,
240        "callee": callee,
241        "arguments": args,
242    })
243
244
245def __temp__25(accessor=None, object=None, property=None):
246    return jsdict({
247        "type": Syntax.MemberExpression,
248        "computed": accessor == "[",
249        "object": object,
250        "property": property,
251    })
252
253
254def __temp__24(token=None):
255    return jsdict({
256        "type": Syntax.Literal,
257        "value": token.value,
258        "raw": source[token.range[0]:token.range[1]],
259    })
260
261
262def __temp__23(label=None, body=None):
263    return jsdict({
264        "type": Syntax.LabeledStatement,
265        "label": label,
266        "body": body,
267    })
268
269
270def __temp__22(test=None, consequent=None, alternate=None):
271    return jsdict({
272        "type": Syntax.IfStatement,
273        "test": test,
274        "consequent": consequent,
275        "alternate": alternate,
276    })
277
278
279def __temp__21(name=None):
280    return jsdict({
281        "type": Syntax.Identifier,
282        "name": name,
283    })
284
285
286def __temp__20(id=None, params=None, defaults=None, body=None):
287    return jsdict({
288        "type": Syntax.FunctionExpression,
289        "id": id,
290        "params": params,
291        "defaults": defaults,
292        "body": body,
293        "rest": None,
294        "generator": False,
295        "expression": False,
296    })
297
298
299def __temp__19(id=None, params=None, defaults=None, body=None):
300    return jsdict({
301        "type": Syntax.FunctionDeclaration,
302        "id": id,
303        "params": params,
304        "defaults": defaults,
305        "body": body,
306        "rest": None,
307        "generator": False,
308        "expression": False,
309    })
310
311
312def __temp__18(left=None, right=None, body=None):
313    return jsdict({
314        "type": Syntax.ForInStatement,
315        "left": left,
316        "right": right,
317        "body": body,
318        "each": False,
319    })
320
321
322def __temp__17(init=None, test=None, update=None, body=None):
323    return jsdict({
324        "type": Syntax.ForStatement,
325        "init": init,
326        "test": test,
327        "update": update,
328        "body": body,
329    })
330
331
332def __temp__16(expression=None):
333    return jsdict({
334        "type": Syntax.ExpressionStatement,
335        "expression": expression,
336    })
337
338
339def __temp__15():
340    return jsdict({
341        "type": Syntax.EmptyStatement,
342    })
343
344
345def __temp__14(body=None, test=None):
346    return jsdict({
347        "type": Syntax.DoWhileStatement,
348        "body": body,
349        "test": test,
350    })
351
352
353def __temp__13():
354    return jsdict({
355        "type": Syntax.DebuggerStatement,
356    })
357
358
359def __temp__12(label=None):
360    return jsdict({
361        "type": Syntax.ContinueStatement,
362        "label": label,
363    })
364
365
366def __temp__11(test=None, consequent=None, alternate=None):
367    return jsdict({
368        "type": Syntax.ConditionalExpression,
369        "test": test,
370        "consequent": consequent,
371        "alternate": alternate,
372    })
373
374
375def __temp__10(param=None, body=None):
376    return jsdict({
377        "type": Syntax.CatchClause,
378        "param": param,
379        "body": body,
380    })
381
382
383def __temp__9(callee=None, args=None):
384    return jsdict({
385        "type": Syntax.CallExpression,
386        "callee": callee,
387        "arguments": args,
388    })
389
390
391def __temp__8(label=None):
392    return jsdict({
393        "type": Syntax.BreakStatement,
394        "label": label,
395    })
396
397
398def __temp__7(body=None):
399    return jsdict({
400        "type": Syntax.BlockStatement,
401        "body": body,
402    })
403
404
405def __temp__6(operator=None, left=None, right=None):
406    type = (Syntax.LogicalExpression if (operator == "||") or
407            (operator == "&&") else Syntax.BinaryExpression)
408    return jsdict({
409        "type": type,
410        "operator": operator,
411        "left": left,
412        "right": right,
413    })
414
415
416def __temp__5(operator=None, left=None, right=None):
417    return jsdict({
418        "type": Syntax.AssignmentExpression,
419        "operator": operator,
420        "left": left,
421        "right": right,
422    })
423
424
425def __temp__4(elements=None):
426    return jsdict({
427        "type": Syntax.ArrayExpression,
428        "elements": elements,
429    })
430
431
432def __temp__3(node=None):
433    if extra.source:
434        node.loc.source = extra.source
435    return node
436
437
438def __temp__2(node=None):
439    if node.range or node.loc:
440        if extra.loc:
441            state.markerStack.pop()
442            state.markerStack.pop()
443        if extra.range:
444            state.markerStack.pop()
445    else:
446        SyntaxTreeDelegate.markEnd(node)
447    return node
448
449
450def __temp__1(node=None):
451    if extra.range:
452        node.range = [state.markerStack.pop(), index]
453    if extra.loc:
454        node.loc = jsdict({
455            "start":
456            jsdict({
457                "line": state.markerStack.pop(),
458                "column": state.markerStack.pop(),
459            }),
460            "end":
461            jsdict({
462                "line": lineNumber,
463                "column": index - lineStart,
464            }),
465        })
466        SyntaxTreeDelegate.postProcess(node)
467    return node
468
469
470def __temp__0():
471    if extra.loc:
472        state.markerStack.append(index - lineStart)
473        state.markerStack.append(lineNumber)
474    if extra.range:
475        state.markerStack.append(index)
476
477
478Token = None
479TokenName = None
480FnExprTokens = None
481Syntax = None
482PropertyKind = None
483Messages = None
484Regex = None
485SyntaxTreeDelegate = None
486source = None
487strict = None
488index = None
489lineNumber = None
490lineStart = None
491length = None
492delegate = None
493lookahead = None
494state = None
495extra = None
496Token = jsdict({
497    "BooleanLiteral": 1,
498    "EOF": 2,
499    "Identifier": 3,
500    "Keyword": 4,
501    "NullLiteral": 5,
502    "NumericLiteral": 6,
503    "Punctuator": 7,
504    "StringLiteral": 8,
505    "RegularExpression": 9,
506})
507TokenName = jsdict({})
508TokenName[Token.BooleanLiteral] = "Boolean"
509TokenName[Token.EOF] = "<end>"
510TokenName[Token.Identifier] = "Identifier"
511TokenName[Token.Keyword] = "Keyword"
512TokenName[Token.NullLiteral] = "Null"
513TokenName[Token.NumericLiteral] = "Numeric"
514TokenName[Token.Punctuator] = "Punctuator"
515TokenName[Token.StringLiteral] = "String"
516TokenName[Token.RegularExpression] = "RegularExpression"
517FnExprTokens = [
518    "(", "{", "[", "in", "typeof", "instanceof", "new", "return", "case",
519    "delete", "throw", "void", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=",
520    ">>>=", "&=", "|=", "^=", ",", "+", "-", "*", "/", "%", "++", "--", "<<",
521    ">>", ">>>", "&", "|", "^", "!", "~", "&&", "||", "?", ":", "===", "==",
522    ">=", "<=", "<", ">", "!=", "!=="
523]
524Syntax = jsdict({
525    "AssignmentExpression": "AssignmentExpression",
526    "ArrayExpression": "ArrayExpression",
527    "BlockStatement": "BlockStatement",
528    "BinaryExpression": "BinaryExpression",
529    "BreakStatement": "BreakStatement",
530    "CallExpression": "CallExpression",
531    "CatchClause": "CatchClause",
532    "ConditionalExpression": "ConditionalExpression",
533    "ContinueStatement": "ContinueStatement",
534    "DoWhileStatement": "DoWhileStatement",
535    "DebuggerStatement": "DebuggerStatement",
536    "EmptyStatement": "EmptyStatement",
537    "ExpressionStatement": "ExpressionStatement",
538    "ForStatement": "ForStatement",
539    "ForInStatement": "ForInStatement",
540    "FunctionDeclaration": "FunctionDeclaration",
541    "FunctionExpression": "FunctionExpression",
542    "Identifier": "Identifier",
543    "IfStatement": "IfStatement",
544    "Literal": "Literal",
545    "LabeledStatement": "LabeledStatement",
546    "LogicalExpression": "LogicalExpression",
547    "MemberExpression": "MemberExpression",
548    "NewExpression": "NewExpression",
549    "ObjectExpression": "ObjectExpression",
550    "Program": "Program",
551    "Property": "Property",
552    "ReturnStatement": "ReturnStatement",
553    "SequenceExpression": "SequenceExpression",
554    "SwitchStatement": "SwitchStatement",
555    "SwitchCase": "SwitchCase",
556    "ThisExpression": "ThisExpression",
557    "ThrowStatement": "ThrowStatement",
558    "TryStatement": "TryStatement",
559    "UnaryExpression": "UnaryExpression",
560    "UpdateExpression": "UpdateExpression",
561    "VariableDeclaration": "VariableDeclaration",
562    "VariableDeclarator": "VariableDeclarator",
563    "WhileStatement": "WhileStatement",
564    "WithStatement": "WithStatement",
565})
566PropertyKind = jsdict({
567    "Data": 1,
568    "Get": 2,
569    "Set": 4,
570})
571Messages = jsdict({
572    "UnexpectedToken":
573    "Unexpected token %0",
574    "UnexpectedNumber":
575    "Unexpected number",
576    "UnexpectedString":
577    "Unexpected string",
578    "UnexpectedIdentifier":
579    "Unexpected identifier",
580    "UnexpectedReserved":
581    "Unexpected reserved word",
582    "UnexpectedEOS":
583    "Unexpected end of input",
584    "NewlineAfterThrow":
585    "Illegal newline after throw",
586    "InvalidRegExp":
587    "Invalid regular expression",
588    "UnterminatedRegExp":
589    "Invalid regular expression: missing /",
590    "InvalidLHSInAssignment":
591    "Invalid left-hand side in assignment",
592    "InvalidLHSInForIn":
593    "Invalid left-hand side in for-in",
594    "MultipleDefaultsInSwitch":
595    "More than one default clause in switch statement",
596    "NoCatchOrFinally":
597    "Missing catch or finally after try",
598    "UnknownLabel":
599    "Undefined label '%0'",
600    "Redeclaration":
601    "%0 '%1' has already been declared",
602    "IllegalContinue":
603    "Illegal continue statement",
604    "IllegalBreak":
605    "Illegal break statement",
606    "IllegalReturn":
607    "Illegal return statement",
608    "StrictModeWith":
609    "Strict mode code may not include a with statement",
610    "StrictCatchVariable":
611    "Catch variable may not be eval or arguments in strict mode",
612    "StrictVarName":
613    "Variable name may not be eval or arguments in strict mode",
614    "StrictParamName":
615    "Parameter name eval or arguments is not allowed in strict mode",
616    "StrictParamDupe":
617    "Strict mode function may not have duplicate parameter names",
618    "StrictFunctionName":
619    "Function name may not be eval or arguments in strict mode",
620    "StrictOctalLiteral":
621    "Octal literals are not allowed in strict mode.",
622    "StrictDelete":
623    "Delete of an unqualified identifier in strict mode.",
624    "StrictDuplicateProperty":
625    "Duplicate data property in object literal not allowed in strict mode",
626    "AccessorDataProperty":
627    "Object literal may not have data and accessor property with the same name",
628    "AccessorGetSet":
629    "Object literal may not have multiple get/set accessors with the same name",
630    "StrictLHSAssignment":
631    "Assignment to eval or arguments is not allowed in strict mode",
632    "StrictLHSPostfix":
633    "Postfix increment/decrement may not have eval or arguments operand in strict mode",
634    "StrictLHSPrefix":
635    "Prefix increment/decrement may not have eval or arguments operand in strict mode",
636    "StrictReservedWord":
637    "Use of future reserved word in strict mode",
638})
639Regex = jsdict({
640    "NonAsciiIdentifierStart":
641    RegExp(
642        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]"
643    ),
644    "NonAsciiIdentifierPart":
645    RegExp(
646        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]"
647    ),
648})
649
650
651def assert__py__(condition=None, message=None):
652    if not condition:
653        raise RuntimeError("ASSERT: " + message)
654
655
656def isDecimalDigit(ch=None):
657    return (ch >= 48) and (ch <= 57)
658
659
660def isHexDigit(ch=None):
661    return "0123456789abcdefABCDEF".find(ch) >= 0
662
663
664def isOctalDigit(ch=None):
665    return "01234567".find(ch) >= 0
666
667
668def isWhiteSpace(ch=None):
669    return (
670        ((((ch == 32) or (ch == 9)) or (ch == 11)) or
671         (ch == 12)) or (ch == 160)
672    ) or ((ch >= 5760) and (
673        u"\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\ufeff"
674        .find(unichr(ch)) > 0))
675
676
677def isLineTerminator(ch=None):
678    return (((ch == 10) or (ch == 13)) or (ch == 8232)) or (ch == 8233)
679
680
681def isIdentifierStart(ch=None):
682    return (((((ch == 36) or (ch == 95)) or ((ch >= 65) and (ch <= 90))) or
683             ((ch >= 97) and (ch <= 122))) or
684            (ch == 92)) or ((ch >= 128)
685                            and Regex.NonAsciiIdentifierStart.test(unichr(ch)))
686
687
688def isIdentifierPart(ch=None):
689    return ((((((ch == 36) or (ch == 95)) or ((ch >= 65) and (ch <= 90))) or
690              ((ch >= 97) and (ch <= 122))) or ((ch >= 48) and (ch <= 57))) or
691            (ch == 92)) or ((ch >= 128)
692                            and Regex.NonAsciiIdentifierPart.test(unichr(ch)))
693
694
695def isFutureReservedWord(id=None):
696    while 1:
697        if (id == "super") or ((id == "import") or ((id == "extends") or
698                                                    ((id == "export") or
699                                                     ((id == "enum") or
700                                                      (id == "class"))))):
701            return True
702        else:
703            return False
704        break
705
706
707def isStrictModeReservedWord(id=None):
708    while 1:
709        if (id == "let") or ((id == "yield") or
710                             ((id == "static") or
711                              ((id == "public") or
712                               ((id == "protected") or
713                                ((id == "private") or
714                                 ((id == "package") or
715                                  ((id == "interface") or
716                                   (id == "implements")))))))):
717            return True
718        else:
719            return False
720        break
721
722
723def isRestrictedWord(id=None):
724    return (id == "eval") or (id == "arguments")
725
726
727def isKeyword(id=None):
728    if strict and isStrictModeReservedWord(id):
729        return True
730    while 1:
731        if len(id) == 2:
732            return ((id == "if") or (id == "in")) or (id == "do")
733        elif len(id) == 3:
734            return ((((id == "var") or (id == "for")) or (id == "new")) or
735                    (id == "try")) or (id == "let")
736        elif len(id) == 4:
737            return (((((id == "this") or (id == "else")) or (id == "case")) or
738                     (id == "void")) or (id == "with")) or (id == "enum")
739        elif len(id) == 5:
740            return (((((((id == "while") or (id == "break")) or
741                        (id == "catch")) or (id == "throw")) or
742                      (id == "const")) or (id == "yield")) or
743                    (id == "class")) or (id == "super")
744        elif len(id) == 6:
745            return (((((id == "return") or (id == "typeof")) or
746                      (id == "delete")) or (id == "switch")) or
747                    (id == "export")) or (id == "import")
748        elif len(id) == 7:
749            return ((id == "default") or
750                    (id == "finally")) or (id == "extends")
751        elif len(id) == 8:
752            return ((id == "function") or
753                    (id == "continue")) or (id == "debugger")
754        elif len(id) == 10:
755            return id == "instanceof"
756        else:
757            return False
758        break
759
760
761def addComment(type=None, value=None, start=None, end=None, loc=None):
762    comment = None
763    assert__py__(('undefined'
764                  if not 'start' in locals() else typeof(start)) == "number",
765                 "Comment must have valid position")
766    if state.lastCommentStart >= start:
767        return
768    state.lastCommentStart = start
769    comment = jsdict({
770        "type": type,
771        "value": value,
772    })
773    if extra.range:
774        comment.range = [start, end]
775    if extra.loc:
776        comment.loc = loc
777    extra.comments.append(comment)
778
779
780def skipSingleLineComment():
781    global index, lineNumber, lineStart
782    start = None
783    loc = None
784    ch = None
785    comment = None
786    start = index - 2
787    loc = jsdict({
788        "start":
789        jsdict({
790            "line": lineNumber,
791            "column": (index - lineStart) - 2,
792        }),
793    })
794    while index < length:
795        ch = (ord(source[index]) if index < len(source) else None)
796        index += 1
797        index
798        if isLineTerminator(ch):
799            if extra.comments:
800                comment = source[(start + 2):(index - 1)]
801                loc.end = jsdict({
802                    "line": lineNumber,
803                    "column": (index - lineStart) - 1,
804                })
805                addComment("Line", comment, start, index - 1, loc)
806            if (ch == 13) and (
807                (ord(source[index]) if index < len(source) else None) == 10):
808                index += 1
809                index
810            lineNumber += 1
811            lineNumber
812            lineStart = index
813            return
814    if extra.comments:
815        comment = source[(start + 2):index]
816        loc.end = jsdict({
817            "line": lineNumber,
818            "column": index - lineStart,
819        })
820        addComment("Line", comment, start, index, loc)
821
822
823def skipMultiLineComment():
824    global index, lineNumber, lineStart
825    start = None
826    loc = None
827    ch = None
828    comment = None
829    if extra.comments:
830        start = index - 2
831        loc = jsdict({
832            "start":
833            jsdict({
834                "line": lineNumber,
835                "column": (index - lineStart) - 2,
836            }),
837        })
838    while index < length:
839        ch = (ord(source[index]) if index < len(source) else None)
840        if isLineTerminator(ch):
841            if (ch == 13) and ((ord(source[index + 1]) if
842                                (index + 1) < len(source) else None) == 10):
843                index += 1
844                index
845            lineNumber += 1
846            lineNumber
847            index += 1
848            index
849            lineStart = index
850            if index >= length:
851                throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
852        elif ch == 42:
853            if (ord(source[index + 1]) if
854                (index + 1) < len(source) else None) == 47:
855                index += 1
856                index
857                index += 1
858                index
859                if extra.comments:
860                    comment = source[(start + 2):(index - 2)]
861                    loc.end = jsdict({
862                        "line": lineNumber,
863                        "column": index - lineStart,
864                    })
865                    addComment("Block", comment, start, index, loc)
866                return
867            index += 1
868            index
869        else:
870            index += 1
871            index
872    throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
873
874
875def skipComment():
876    global index, lineNumber, lineStart
877    ch = None
878    while index < length:
879        ch = (ord(source[index]) if index < len(source) else None)
880        if isWhiteSpace(ch):
881            index += 1
882            index
883        elif isLineTerminator(ch):
884            index += 1
885            index
886            if (ch == 13) and (
887                (ord(source[index]) if index < len(source) else None) == 10):
888                index += 1
889                index
890            lineNumber += 1
891            lineNumber
892            lineStart = index
893        elif ch == 47:
894            ch = (ord(source[index + 1]) if
895                  (index + 1) < len(source) else None)
896            if ch == 47:
897                index += 1
898                index
899                index += 1
900                index
901                skipSingleLineComment()
902            elif ch == 42:
903                index += 1
904                index
905                index += 1
906                index
907                skipMultiLineComment()
908            else:
909                break
910        else:
911            break
912
913
914def scanHexEscape(prefix=None):
915    global len__py__, index
916    i = None
917    len__py__ = None
918    ch = None
919    code = 0
920    len__py__ = (4 if prefix == "u" else 2)
921    i = 0
922    while 1:
923        if not (i < len__py__):
924            break
925        if (index < length) and isHexDigit(source[index]):
926            index += 1
927            ch = source[index - 1]
928            code = (code * 16) + "0123456789abcdef".find(ch.lower())
929        else:
930            return ""
931        i += 1
932    return unichr(code)
933
934
935def getEscapedIdentifier():
936    global index
937    ch = None
938    id = None
939    index += 1
940    index += 1
941    ch = (ord(source[index - 1]) if index - 1 < len(source) else None)
942    id = unichr(ch)
943    if ch == 92:
944        if (ord(source[index]) if index < len(source) else None) != 117:
945            throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
946        index += 1
947        index
948        ch = scanHexEscape("u")
949        if ((not ch) or (ch == "\\")) or (not isIdentifierStart(
950            (ord(ch[0]) if 0 < len(ch) else None))):
951            throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
952        id = ch
953    while index < length:
954        ch = (ord(source[index]) if index < len(source) else None)
955        if not isIdentifierPart(ch):
956            break
957        index += 1
958        index
959        id += unichr(ch)
960        if ch == 92:
961            id = id[0:(0 + (len(id) - 1))]
962            if (ord(source[index]) if index < len(source) else None) != 117:
963                throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
964            index += 1
965            index
966            ch = scanHexEscape("u")
967            if ((not ch) or (ch == "\\")) or (not isIdentifierPart(
968                (ord(ch[0]) if 0 < len(ch) else None))):
969                throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
970            id += ch
971    return id
972
973
974def getIdentifier():
975    global index
976    start = None
977    ch = None
978    index += 1
979    start = index - 1
980    while index < length:
981        ch = (ord(source[index]) if index < len(source) else None)
982        if ch == 92:
983            index = start
984            return getEscapedIdentifier()
985        if isIdentifierPart(ch):
986            index += 1
987            index
988        else:
989            break
990    return source[start:index]
991
992
993def scanIdentifier():
994    start = None
995    id = None
996    type = None
997    start = index
998    id = (getEscapedIdentifier() if
999          (ord(source[index]) if index < len(source) else None) == 92 else
1000          getIdentifier())
1001    if len(id) == 1:
1002        type = Token.Identifier
1003    elif isKeyword(id):
1004        type = Token.Keyword
1005    elif id == "null":
1006        type = Token.NullLiteral
1007    elif (id == "true") or (id == "false"):
1008        type = Token.BooleanLiteral
1009    else:
1010        type = Token.Identifier
1011    return jsdict({
1012        "type": type,
1013        "value": id,
1014        "lineNumber": lineNumber,
1015        "lineStart": lineStart,
1016        "range": [start, index],
1017    })
1018
1019
1020def scanPunctuator():
1021    global index
1022    start = index
1023    code = (ord(source[index]) if index < len(source) else None)
1024    code2 = None
1025    ch1 = source[index]
1026    ch2 = None
1027    ch3 = None
1028    ch4 = None
1029    while 1:
1030        if (code == 126) or ((code == 63) or ((code == 58) or
1031                                              ((code == 93) or
1032                                               ((code == 91) or
1033                                                ((code == 125) or
1034                                                 ((code == 123) or
1035                                                  ((code == 44) or
1036                                                   ((code == 59) or
1037                                                    ((code == 41) or
1038                                                     ((code == 40) or
1039                                                      (code == 46))))))))))):
1040            index += 1
1041            index
1042            if extra.tokenize:
1043                if code == 40:
1044                    extra.openParenToken = len(extra.tokens)
1045                elif code == 123:
1046                    extra.openCurlyToken = len(extra.tokens)
1047            return jsdict({
1048                "type": Token.Punctuator,
1049                "value": unichr(code),
1050                "lineNumber": lineNumber,
1051                "lineStart": lineStart,
1052                "range": [start, index],
1053            })
1054        else:
1055            code2 = (ord(source[index + 1]) if
1056                     (index + 1) < len(source) else None)
1057            if code2 == 61:
1058                while 1:
1059                    if (code == 124) or ((code == 94) or
1060                                         ((code == 62) or
1061                                          ((code == 60) or
1062                                           ((code == 47) or
1063                                            ((code == 45) or
1064                                             ((code == 43) or
1065                                              ((code == 42) or
1066                                               ((code == 38) or
1067                                                (code == 37))))))))):
1068                        index += 2
1069                        return jsdict({
1070                            "type": Token.Punctuator,
1071                            "value": unichr(code) + unichr(code2),
1072                            "lineNumber": lineNumber,
1073                            "lineStart": lineStart,
1074                            "range": [start, index],
1075                        })
1076                    elif (code == 61) or (code == 33):
1077                        index += 2
1078                        if (ord(source[index])
1079                                if index < len(source) else None) == 61:
1080                            index += 1
1081                            index
1082                        return jsdict({
1083                            "type": Token.Punctuator,
1084                            "value": source[start:index],
1085                            "lineNumber": lineNumber,
1086                            "lineStart": lineStart,
1087                            "range": [start, index],
1088                        })
1089                    else:
1090                        break
1091                    break
1092            break
1093        break
1094    ch2 = source[index + 1] if index + 1 < len(source) else None
1095    ch3 = source[index + 2] if index + 2 < len(source) else None
1096    ch4 = source[index + 3] if index + 3 < len(source) else None
1097    if ((ch1 == ">") and (ch2 == ">")) and (ch3 == ">"):
1098        if ch4 == "=":
1099            index += 4
1100            return jsdict({
1101                "type": Token.Punctuator,
1102                "value": ">>>=",
1103                "lineNumber": lineNumber,
1104                "lineStart": lineStart,
1105                "range": [start, index],
1106            })
1107    if ((ch1 == ">") and (ch2 == ">")) and (ch3 == ">"):
1108        index += 3
1109        return jsdict({
1110            "type": Token.Punctuator,
1111            "value": ">>>",
1112            "lineNumber": lineNumber,
1113            "lineStart": lineStart,
1114            "range": [start, index],
1115        })
1116    if ((ch1 == "<") and (ch2 == "<")) and (ch3 == "="):
1117        index += 3
1118        return jsdict({
1119            "type": Token.Punctuator,
1120            "value": "<<=",
1121            "lineNumber": lineNumber,
1122            "lineStart": lineStart,
1123            "range": [start, index],
1124        })
1125    if ((ch1 == ">") and (ch2 == ">")) and (ch3 == "="):
1126        index += 3
1127        return jsdict({
1128            "type": Token.Punctuator,
1129            "value": ">>=",
1130            "lineNumber": lineNumber,
1131            "lineStart": lineStart,
1132            "range": [start, index],
1133        })
1134    if (ch1 == ch2) and ("+-<>&|".find(ch1) >= 0):
1135        index += 2
1136        return jsdict({
1137            "type": Token.Punctuator,
1138            "value": ch1 + ch2,
1139            "lineNumber": lineNumber,
1140            "lineStart": lineStart,
1141            "range": [start, index],
1142        })
1143    if "<>=!+-*%&|^/".find(ch1) >= 0:
1144        index += 1
1145        index
1146        return jsdict({
1147            "type": Token.Punctuator,
1148            "value": ch1,
1149            "lineNumber": lineNumber,
1150            "lineStart": lineStart,
1151            "range": [start, index],
1152        })
1153    throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1154
1155
1156def scanHexLiteral(start=None):
1157    global index
1158    number = ""
1159    while index < length:
1160        if not isHexDigit(source[index]):
1161            break
1162        index += 1
1163        number += source[index - 1]
1164    if len(number) == 0:
1165        throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1166    if isIdentifierStart(
1167        (ord(source[index]) if index < len(source) else None)):
1168        throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1169    return jsdict({
1170        "type": Token.NumericLiteral,
1171        "value": parseInt("0x" + number, 16),
1172        "lineNumber": lineNumber,
1173        "lineStart": lineStart,
1174        "range": [start, index],
1175    })
1176
1177
1178def scanOctalLiteral(start=None):
1179    global index
1180    index += 1
1181    number = "0" + source[index - 1]
1182    while index < length:
1183        if not isOctalDigit(source[index]):
1184            break
1185        index += 1
1186        number += source[index - 1]
1187    if isIdentifierStart(
1188        (ord(source[index])
1189         if index < len(source) else None)) or isDecimalDigit(
1190             (ord(source[index]) if index < len(source) else None)):
1191        throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1192    return jsdict({
1193        "type": Token.NumericLiteral,
1194        "value": parseInt(number, 8),
1195        "octal": True,
1196        "lineNumber": lineNumber,
1197        "lineStart": lineStart,
1198        "range": [start, index],
1199    })
1200
1201
1202def scanNumericLiteral():
1203    global index
1204    number = None
1205    start = None
1206    ch = None
1207    ch = source[index]
1208    assert__py__(
1209        isDecimalDigit((ord(ch[0]) if 0 < len(ch) else None)) or (ch == "."),
1210        "Numeric literal must start with a decimal digit or a decimal point")
1211    start = index
1212    number = ""
1213    if ch != ".":
1214        index += 1
1215        number = source[index - 1]
1216        ch = source[index] if index < len(source) else None
1217        if number == "0":
1218            if (ch == "x") or (ch == "X"):
1219                index += 1
1220                index
1221                return scanHexLiteral(start)
1222            if isOctalDigit(ch):
1223                return scanOctalLiteral(start)
1224            if ch and isDecimalDigit((ord(ch[0]) if 0 < len(ch) else None)):
1225                throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1226        while isDecimalDigit(
1227            (ord(source[index]) if index < len(source) else None)):
1228            index += 1
1229            number += source[index - 1]
1230        ch = source[index] if index < len(source) else None
1231    if ch == ".":
1232        index += 1
1233        number += source[index - 1]
1234        while isDecimalDigit(
1235            (ord(source[index]) if index < len(source) else None)):
1236            index += 1
1237            number += source[index - 1]
1238        ch = source[index]
1239    if (ch == "e") or (ch == "E"):
1240        index += 1
1241        number += source[index - 1]
1242        ch = source[index]
1243        if (ch == "+") or (ch == "-"):
1244            index += 1
1245            number += source[index - 1]
1246        if isDecimalDigit(
1247            (ord(source[index]) if index < len(source) else None)):
1248            while isDecimalDigit(
1249                (ord(source[index]) if index < len(source) else None)):
1250                index += 1
1251                number += source[index - 1]
1252        else:
1253            throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1254    if isIdentifierStart(
1255        (ord(source[index]) if index < len(source) else None)):
1256        throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1257    return jsdict({
1258        "type": Token.NumericLiteral,
1259        "value": parseFloat(number),
1260        "lineNumber": lineNumber,
1261        "lineStart": lineStart,
1262        "range": [start, index],
1263    })
1264
1265
1266def scanStringLiteral():
1267    global index, lineNumber
1268    str = ""
1269    quote = None
1270    start = None
1271    ch = None
1272    code = None
1273    unescaped = None
1274    restore = None
1275    octal = False
1276    quote = source[index]
1277    assert__py__((quote == "'") or (quote == "\""),
1278                 "String literal must starts with a quote")
1279    start = index
1280    index += 1
1281    index
1282    while index < length:
1283        index += 1
1284        ch = source[index - 1]
1285        if ch == quote:
1286            quote = ""
1287            break
1288        elif ch == "\\":
1289            index += 1
1290            ch = source[index - 1]
1291            if (not ch) or (not isLineTerminator(
1292                (ord(ch[0]) if 0 < len(ch) else None))):
1293                while 1:
1294                    if ch == "n":
1295                        str += u"\x0a"
1296                        break
1297                    elif ch == "r":
1298                        str += u"\x0d"
1299                        break
1300                    elif ch == "t":
1301                        str += u"\x09"
1302                        break
1303                    elif (ch == "x") or (ch == "u"):
1304                        restore = index
1305                        unescaped = scanHexEscape(ch)
1306                        if unescaped:
1307                            str += unescaped
1308                        else:
1309                            index = restore
1310                            str += ch
1311                        break
1312                    elif ch == "b":
1313                        str += u"\x08"
1314                        break
1315                    elif ch == "f":
1316                        str += u"\x0c"
1317                        break
1318                    elif ch == "v":
1319                        str += u"\x0b"
1320                        break
1321                    else:
1322                        if isOctalDigit(ch):
1323                            code = "01234567".find(ch)
1324                            if code != 0:
1325                                octal = True
1326                            if (index < length) and isOctalDigit(
1327                                    source[index]):
1328                                octal = True
1329                                index += 1
1330                                code = (code * 8) + "01234567".find(
1331                                    source[index - 1])
1332                                if (("0123".find(ch) >= 0) and
1333                                    (index < length)) and isOctalDigit(
1334                                        source[index]):
1335                                    index += 1
1336                                    code = (code * 8) + "01234567".find(
1337                                        source[index - 1])
1338                            str += unichr(code)
1339                        else:
1340                            str += ch
1341                        break
1342                    break
1343            else:
1344                lineNumber += 1
1345                lineNumber
1346                if (ch == u"\x0d") and (source[index] == u"\x0a"):
1347                    index += 1
1348                    index
1349        elif isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
1350            break
1351        else:
1352            str += ch
1353    if quote != "":
1354        throwError(jsdict({}), Messages.UnexpectedToken, "ILLEGAL")
1355    return jsdict({
1356        "type": Token.StringLiteral,
1357        "value": str,
1358        "octal": octal,
1359        "lineNumber": lineNumber,
1360        "lineStart": lineStart,
1361        "range": [start, index],
1362    })
1363
1364
1365def scanRegExp():
1366    global lookahead, index
1367    str = None
1368    ch = None
1369    start = None
1370    pattern = None
1371    flags = None
1372    value = None
1373    classMarker = False
1374    restore = None
1375    terminated = False
1376    lookahead = None
1377    skipComment()
1378    start = index
1379    ch = source[index]
1380    assert__py__(ch == "/",
1381                 "Regular expression literal must start with a slash")
1382    index += 1
1383    str = source[index - 1]
1384    while index < length:
1385        index += 1
1386        ch = source[index - 1]
1387        str += ch
1388        if classMarker:
1389            if ch == "]":
1390                classMarker = False
1391        else:
1392            if ch == "\\":
1393                index += 1
1394                ch = source[index - 1]
1395                if isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
1396                    throwError(jsdict({}), Messages.UnterminatedRegExp)
1397                str += ch
1398            elif ch == "/":
1399                terminated = True
1400                break
1401            elif ch == "[":
1402                classMarker = True
1403            elif isLineTerminator((ord(ch[0]) if 0 < len(ch) else None)):
1404                throwError(jsdict({}), Messages.UnterminatedRegExp)
1405    if not terminated:
1406        throwError(jsdict({}), Messages.UnterminatedRegExp)
1407    pattern = str[1:(1 + (len(str) - 2))]
1408    flags = ""
1409    while index < length:
1410        ch = source[index]
1411        if not isIdentifierPart((ord(ch[0]) if 0 < len(ch) else None)):
1412            break
1413        index += 1
1414        index
1415        if (ch == "\\") and (index < length):
1416            ch = source[index]
1417            if ch == "u":
1418                index += 1
1419                index
1420                restore = index
1421                ch = scanHexEscape("u")
1422                if ch:
1423                    flags += ch
1424                    str += "\\u"
1425                    while 1:
1426                        if not (restore < index):
1427                            break
1428                        str += source[restore]
1429                        restore += 1
1430                else:
1431                    index = restore
1432                    flags += "u"
1433                    str += "\\u"
1434            else:
1435                str += "\\"
1436        else:
1437            flags += ch
1438            str += ch
1439    try:
1440        value = RegExp(pattern, flags)
1441    except Exception as e:
1442        throwError(jsdict({}), Messages.InvalidRegExp)
1443    peek()
1444    if extra.tokenize:
1445        return jsdict({
1446            "type": Token.RegularExpression,
1447            "value": value,
1448            "lineNumber": lineNumber,
1449            "lineStart": lineStart,
1450            "range": [start, index],
1451        })
1452    return jsdict({
1453        "literal": str,
1454        "value": value,
1455        "range": [start, index],
1456    })
1457
1458
1459def isIdentifierName(token=None):
1460    return (((token.type == Token.Identifier) or
1461             (token.type == Token.Keyword)) or
1462            (token.type == Token.BooleanLiteral)) or (
1463                token.type == Token.NullLiteral)
1464
1465
1466def advanceSlash():
1467    prevToken = None
1468    checkToken = None
1469    prevToken = extra.tokens[len(extra.tokens) - 1]
1470    if not prevToken:
1471        return scanRegExp()
1472    if prevToken.type == "Punctuator":
1473        if prevToken.value == ")":
1474            checkToken = extra.tokens[extra.openParenToken - 1]
1475            if (checkToken and (checkToken.type == "Keyword")) and (
1476                (((checkToken.value == "if") or
1477                  (checkToken.value == "while")) or
1478                 (checkToken.value == "for")) or (checkToken.value == "with")):
1479                return scanRegExp()
1480            return scanPunctuator()
1481        if prevToken.value == "}":
1482            if extra.tokens[extra.openCurlyToken - 3] and (
1483                    extra.tokens[extra.openCurlyToken - 3].type == "Keyword"):
1484                checkToken = extra.tokens[extra.openCurlyToken - 4]
1485                if not checkToken:
1486                    return scanPunctuator()
1487            elif extra.tokens[extra.openCurlyToken - 4] and (
1488                    extra.tokens[extra.openCurlyToken - 4].type == "Keyword"):
1489                checkToken = extra.tokens[extra.openCurlyToken - 5]
1490                if not checkToken:
1491                    return scanRegExp()
1492            else:
1493                return scanPunctuator()
1494            if FnExprTokens.indexOf(checkToken.value) >= 0:
1495                return scanPunctuator()
1496            return scanRegExp()
1497        return scanRegExp()
1498    if prevToken.type == "Keyword":
1499        return scanRegExp()
1500    return scanPunctuator()
1501
1502
1503def advance():
1504    ch = None
1505    skipComment()
1506    if index >= length:
1507        return jsdict({
1508            "type": Token.EOF,
1509            "lineNumber": lineNumber,
1510            "lineStart": lineStart,
1511            "range": [index, index],
1512        })
1513    ch = (ord(source[index]) if index < len(source) else None)
1514    if ((ch == 40) or (ch == 41)) or (ch == 58):
1515        return scanPunctuator()
1516    if (ch == 39) or (ch == 34):
1517        return scanStringLiteral()
1518    if isIdentifierStart(ch):
1519        return scanIdentifier()
1520    if ch == 46:
1521        if isDecimalDigit((ord(source[index + 1]) if
1522                           (index + 1) < len(source) else None)):
1523            return scanNumericLiteral()
1524        return scanPunctuator()
1525    if isDecimalDigit(ch):
1526        return scanNumericLiteral()
1527    if extra.tokenize and (ch == 47):
1528        return advanceSlash()
1529    return scanPunctuator()
1530
1531
1532def lex():
1533    global index, lineNumber, lineStart, lookahead
1534    token = None
1535    token = lookahead
1536    index = token.range[1]
1537    lineNumber = token.lineNumber
1538    lineStart = token.lineStart
1539    lookahead = advance()
1540    index = token.range[1]
1541    lineNumber = token.lineNumber
1542    lineStart = token.lineStart
1543    return token
1544
1545
1546def peek():
1547    global lookahead, index, lineNumber, lineStart
1548    pos = None
1549    line = None
1550    start = None
1551    pos = index
1552    line = lineNumber
1553    start = lineStart
1554    lookahead = advance()
1555    index = pos
1556    lineNumber = line
1557    lineStart = start
1558
1559
1560SyntaxTreeDelegate = jsdict({
1561    "name": "SyntaxTree",
1562    "markStart": __temp__0,
1563    "markEnd": __temp__1,
1564    "markEndIf": __temp__2,
1565    "postProcess": __temp__3,
1566    "createArrayExpression": __temp__4,
1567    "createAssignmentExpression": __temp__5,
1568    "createBinaryExpression": __temp__6,
1569    "createBlockStatement": __temp__7,
1570    "createBreakStatement": __temp__8,
1571    "createCallExpression": __temp__9,
1572    "createCatchClause": __temp__10,
1573    "createConditionalExpression": __temp__11,
1574    "createContinueStatement": __temp__12,
1575    "createDebuggerStatement": __temp__13,
1576    "createDoWhileStatement": __temp__14,
1577    "createEmptyStatement": __temp__15,
1578    "createExpressionStatement": __temp__16,
1579    "createForStatement": __temp__17,
1580    "createForInStatement": __temp__18,
1581    "createFunctionDeclaration": __temp__19,
1582    "createFunctionExpression": __temp__20,
1583    "createIdentifier": __temp__21,
1584    "createIfStatement": __temp__22,
1585    "createLabeledStatement": __temp__23,
1586    "createLiteral": __temp__24,
1587    "createMemberExpression": __temp__25,
1588    "createNewExpression": __temp__26,
1589    "createObjectExpression": __temp__27,
1590    "createPostfixExpression": __temp__28,
1591    "createProgram": __temp__29,
1592    "createProperty": __temp__30,
1593    "createReturnStatement": __temp__31,
1594    "createSequenceExpression": __temp__32,
1595    "createSwitchCase": __temp__33,
1596    "createSwitchStatement": __temp__34,
1597    "createThisExpression": __temp__35,
1598    "createThrowStatement": __temp__36,
1599    "createTryStatement": __temp__37,
1600    "createUnaryExpression": __temp__38,
1601    "createVariableDeclaration": __temp__39,
1602    "createVariableDeclarator": __temp__40,
1603    "createWhileStatement": __temp__41,
1604    "createWithStatement": __temp__42,
1605})
1606
1607
1608def peekLineTerminator():
1609    global index, lineNumber, lineStart
1610    pos = None
1611    line = None
1612    start = None
1613    found = None
1614    pos = index
1615    line = lineNumber
1616    start = lineStart
1617    skipComment()
1618    found = lineNumber != line
1619    index = pos
1620    lineNumber = line
1621    lineStart = start
1622    return found
1623
1624
1625def throwError(token=None, messageFormat=None, a=None):
1626    def __temp__43(whole=None, index=None):
1627        assert__py__(index < len(args), "Message reference must be in range")
1628        return args[index]
1629
1630    error = None
1631    args = Array.prototype.slice.call(arguments, 2)
1632    msg = messageFormat.replace(RegExp(r'%(\d)'), __temp__43)
1633    if ('undefined' if not ('lineNumber' in token) else typeof(
1634            token.lineNumber)) == "number":
1635        error = RuntimeError((("Line " + token.lineNumber) + ": ") + msg)
1636        error.index = token.range[0]
1637        error.lineNumber = token.lineNumber
1638        error.column = (token.range[0] - lineStart) + 1
1639    else:
1640        error = RuntimeError((("Line " + lineNumber) + ": ") + msg)
1641        error.index = index
1642        error.lineNumber = lineNumber
1643        error.column = (index - lineStart) + 1
1644    error.description = msg
1645    raise error
1646
1647
1648def throwErrorTolerant():
1649    try:
1650        throwError.apply(None, arguments)
1651    except Exception as e:
1652        if extra.errors:
1653            extra.errors.append(e)
1654        else:
1655            raise
1656
1657
1658def throwUnexpected(token=None):
1659    if token.type == Token.EOF:
1660        throwError(token, Messages.UnexpectedEOS)
1661    if token.type == Token.NumericLiteral:
1662        throwError(token, Messages.UnexpectedNumber)
1663    if token.type == Token.StringLiteral:
1664        throwError(token, Messages.UnexpectedString)
1665    if token.type == Token.Identifier:
1666        throwError(token, Messages.UnexpectedIdentifier)
1667    if token.type == Token.Keyword:
1668        if isFutureReservedWord(token.value):
1669            throwError(token, Messages.UnexpectedReserved)
1670        elif strict and isStrictModeReservedWord(token.value):
1671            throwErrorTolerant(token, Messages.StrictReservedWord)
1672            return
1673        throwError(token, Messages.UnexpectedToken, token.value)
1674    throwError(token, Messages.UnexpectedToken, token.value)
1675
1676
1677def expect(value=None):
1678    token = lex()
1679    if (token.type != Token.Punctuator) or (token.value != value):
1680        throwUnexpected(token)
1681
1682
1683def expectKeyword(keyword=None):
1684    token = lex()
1685    if (token.type != Token.Keyword) or (token.value != keyword):
1686        throwUnexpected(token)
1687
1688
1689def match(value=None):
1690    return (lookahead.type == Token.Punctuator) and (lookahead.value == value)
1691
1692
1693def matchKeyword(keyword=None):
1694    return (lookahead.type == Token.Keyword) and (lookahead.value == keyword)
1695
1696
1697def matchAssign():
1698    op = None
1699    if lookahead.type != Token.Punctuator:
1700        return False
1701    op = lookahead.value
1702    return (((((((((((op == "=") or (op == "*=")) or (op == "/=")) or
1703                   (op == "%=")) or (op == "+=")) or (op == "-=")) or
1704                (op == "<<=")) or (op == ">>=")) or (op == ">>>=")) or
1705             (op == "&=")) or (op == "^=")) or (op == "|=")
1706
1707
1708def consumeSemicolon():
1709    line = None
1710    if (ord(source[index]) if index < len(source) else None) == 59:
1711        lex()
1712        return
1713    line = lineNumber
1714    skipComment()
1715    if lineNumber != line:
1716        return
1717    if match(";"):
1718        lex()
1719        return
1720    if (lookahead.type != Token.EOF) and (not match("}")):
1721        throwUnexpected(lookahead)
1722
1723
1724def isLeftHandSide(expr=None):
1725    return (expr.type == Syntax.Identifier) or (
1726        expr.type == Syntax.MemberExpression)
1727
1728
1729def parseArrayInitialiser():
1730    elements = []
1731    expect("[")
1732    while not match("]"):
1733        if match(","):
1734            lex()
1735            elements.append(None)
1736        else:
1737            elements.append(parseAssignmentExpression())
1738            if not match("]"):
1739                expect(",")
1740    expect("]")
1741    return delegate.createArrayExpression(elements)
1742
1743
1744def parsePropertyFunction(param=None, first=None):
1745    global strict
1746    previousStrict = None
1747    body = None
1748    previousStrict = strict
1749    skipComment()
1750    delegate.markStart()
1751    body = parseFunctionSourceElements()
1752    if (first and strict) and isRestrictedWord(param[0].name):
1753        throwErrorTolerant(first, Messages.StrictParamName)
1754    strict = previousStrict
1755    return delegate.markEnd(
1756        delegate.createFunctionExpression(None, param, [], body))
1757
1758
1759def parseObjectPropertyKey():
1760    token = None
1761    skipComment()
1762    delegate.markStart()
1763    token = lex()
1764    if (token.type == Token.StringLiteral) or (
1765            token.type == Token.NumericLiteral):
1766        if strict and token.octal:
1767            throwErrorTolerant(token, Messages.StrictOctalLiteral)
1768        return delegate.markEnd(delegate.createLiteral(token))
1769    return delegate.markEnd(delegate.createIdentifier(token.value))
1770
1771
1772def parseObjectProperty():
1773    token = None
1774    key = None
1775    id = None
1776    value = None
1777    param = None
1778    token = lookahead
1779    skipComment()
1780    delegate.markStart()
1781    if token.type == Token.Identifier:
1782        id = parseObjectPropertyKey()
1783        if (token.value == "get") and (not match(":")):
1784            key = parseObjectPropertyKey()
1785            expect("(")
1786            expect(")")
1787            value = parsePropertyFunction([])
1788            return delegate.markEnd(delegate.createProperty("get", key, value))
1789        if (token.value == "set") and (not match(":")):
1790            key = parseObjectPropertyKey()
1791            expect("(")
1792            token = lookahead
1793            if token.type != Token.Identifier:
1794                expect(")")
1795                throwErrorTolerant(token, Messages.UnexpectedToken,
1796                                   token.value)
1797                value = parsePropertyFunction([])
1798            else:
1799                param = [parseVariableIdentifier()]
1800                expect(")")
1801                value = parsePropertyFunction(param, token)
1802            return delegate.markEnd(delegate.createProperty("set", key, value))
1803        expect(":")
1804        value = parseAssignmentExpression()
1805        return delegate.markEnd(delegate.createProperty("init", id, value))
1806    if (token.type == Token.EOF) or (token.type == Token.Punctuator):
1807        throwUnexpected(token)
1808    else:
1809        key = parseObjectPropertyKey()
1810        expect(":")
1811        value = parseAssignmentExpression()
1812        return delegate.markEnd(delegate.createProperty("init", key, value))
1813
1814
1815def parseObjectInitialiser():
1816    properties = []
1817    property = None
1818    name = None
1819    key = None
1820    kind = None
1821    map = jsdict({})
1822    toString = str
1823    expect("{")
1824    while not match("}"):
1825        property = parseObjectProperty()
1826        if property.key.type == Syntax.Identifier:
1827            name = property.key.name
1828        else:
1829            name = toString(property.key.value)
1830        kind = (PropertyKind.Data if property.kind == "init" else (
1831            PropertyKind.Get if property.kind == "get" else PropertyKind.Set))
1832        key = "$" + name
1833        if key in map:
1834            if map[key] == PropertyKind.Data:
1835                if strict and (kind == PropertyKind.Data):
1836                    throwErrorTolerant(
1837                        jsdict({}), Messages.StrictDuplicateProperty)
1838                elif kind != PropertyKind.Data:
1839                    throwErrorTolerant(
1840                        jsdict({}), Messages.AccessorDataProperty)
1841            else:
1842                if kind == PropertyKind.Data:
1843                    throwErrorTolerant(
1844                        jsdict({}), Messages.AccessorDataProperty)
1845                elif map[key] & kind:
1846                    throwErrorTolerant(jsdict({}), Messages.AccessorGetSet)
1847            map[key] |= kind
1848        else:
1849            map[key] = kind
1850        properties.append(property)
1851        if not match("}"):
1852            expect(",")
1853    expect("}")
1854    return delegate.createObjectExpression(properties)
1855
1856
1857def parseGroupExpression():
1858    expr = None
1859    expect("(")
1860    expr = parseExpression()
1861    expect(")")
1862    return expr
1863
1864
1865def parsePrimaryExpression():
1866    type = None
1867    token = None
1868    expr = None
1869    if match("("):
1870        return parseGroupExpression()
1871    type = lookahead.type
1872    delegate.markStart()
1873    if type == Token.Identifier:
1874        expr = delegate.createIdentifier(lex().value)
1875    elif (type == Token.StringLiteral) or (type == Token.NumericLiteral):
1876        if strict and lookahead.octal:
1877            throwErrorTolerant(lookahead, Messages.StrictOctalLiteral)
1878        expr = delegate.createLiteral(lex())
1879    elif type == Token.Keyword:
1880        if matchKeyword("this"):
1881            lex()
1882            expr = delegate.createThisExpression()
1883        elif matchKeyword("function"):
1884            expr = parseFunctionExpression()
1885    elif type == Token.BooleanLiteral:
1886        token = lex()
1887        token.value = token.value == "true"
1888        expr = delegate.createLiteral(token)
1889    elif type == Token.NullLiteral:
1890        token = lex()
1891        token.value = None
1892        expr = delegate.createLiteral(token)
1893    elif match("["):
1894        expr = parseArrayInitialiser()
1895    elif match("{"):
1896        expr = parseObjectInitialiser()
1897    elif match("/") or match("/="):
1898        expr = delegate.createLiteral(scanRegExp())
1899    if expr:
1900        return delegate.markEnd(expr)
1901    throwUnexpected(lex())
1902
1903
1904def parseArguments():
1905    args = []
1906    expect("(")
1907    if not match(")"):
1908        while index < length:
1909            args.append(parseAssignmentExpression())
1910            if match(")"):
1911                break
1912            expect(",")
1913    expect(")")
1914    return args
1915
1916
1917def parseNonComputedProperty():
1918    token = None
1919    delegate.markStart()
1920    token = lex()
1921    if not isIdentifierName(token):
1922        throwUnexpected(token)
1923    return delegate.markEnd(delegate.createIdentifier(token.value))
1924
1925
1926def parseNonComputedMember():
1927    expect(".")
1928    return parseNonComputedProperty()
1929
1930
1931def parseComputedMember():
1932    expr = None
1933    expect("[")
1934    expr = parseExpression()
1935    expect("]")
1936    return expr
1937
1938
1939def parseNewExpression():
1940    callee = None
1941    args = None
1942    delegate.markStart()
1943    expectKeyword("new")
1944    callee = parseLeftHandSideExpression()
1945    args = (parseArguments() if match("(") else [])
1946    return delegate.markEnd(delegate.createNewExpression(callee, args))
1947
1948
1949def parseLeftHandSideExpressionAllowCall():
1950    marker = None
1951    expr = None
1952    args = None
1953    property = None
1954    marker = createLocationMarker()
1955    expr = (parseNewExpression()
1956            if matchKeyword("new") else parsePrimaryExpression())
1957    while (match(".") or match("[")) or match("("):
1958        if match("("):
1959            args = parseArguments()
1960            expr = delegate.createCallExpression(expr, args)
1961        elif match("["):
1962            property = parseComputedMember()
1963            expr = delegate.createMemberExpression("[", expr, property)
1964        else:
1965            property = parseNonComputedMember()
1966            expr = delegate.createMemberExpression(".", expr, property)
1967        if marker:
1968            marker.end()
1969            marker.apply(expr)
1970    return expr
1971
1972
1973def parseLeftHandSideExpression():
1974    marker = None
1975    expr = None
1976    property = None
1977    marker = createLocationMarker()
1978    expr = (parseNewExpression()
1979            if matchKeyword("new") else parsePrimaryExpression())
1980    while match(".") or match("["):
1981        if match("["):
1982            property = parseComputedMember()
1983            expr = delegate.createMemberExpression("[", expr, property)
1984        else:
1985            property = parseNonComputedMember()
1986            expr = delegate.createMemberExpression(".", expr, property)
1987        if marker:
1988            marker.end()
1989            marker.apply(expr)
1990    return expr
1991
1992
1993def parsePostfixExpression():
1994    expr = None
1995    token = None
1996    delegate.markStart()
1997    expr = parseLeftHandSideExpressionAllowCall()
1998    if lookahead.type == Token.Punctuator:
1999        if (match("++") or match("--")) and (not peekLineTerminator()):
2000            if (strict and
2001                (expr.type == Syntax.Identifier)) and isRestrictedWord(
2002                    expr.name):
2003                throwErrorTolerant(jsdict({}), Messages.StrictLHSPostfix)
2004            if not isLeftHandSide(expr):
2005                throwError(jsdict({}), Messages.InvalidLHSInAssignment)
2006            token = lex()
2007            expr = delegate.createPostfixExpression(token.value, expr)
2008    return delegate.markEndIf(expr)
2009
2010
2011def parseUnaryExpression():
2012    token = None
2013    expr = None
2014    delegate.markStart()
2015    if (lookahead.type != Token.Punctuator) and (lookahead.type !=
2016                                                 Token.Keyword):
2017        expr = parsePostfixExpression()
2018    elif match("++") or match("--"):
2019        token = lex()
2020        expr = parseUnaryExpression()
2021        if (strict and
2022            (expr.type == Syntax.Identifier)) and isRestrictedWord(expr.name):
2023            throwErrorTolerant(jsdict({}), Messages.StrictLHSPrefix)
2024        if not isLeftHandSide(expr):
2025            throwError(jsdict({}), Messages.InvalidLHSInAssignment)
2026        expr = delegate.createUnaryExpression(token.value, expr)
2027    elif ((match("+") or match("-")) or match("~")) or match("!"):
2028        token = lex()
2029        expr = parseUnaryExpression()
2030        expr = delegate.createUnaryExpression(token.value, expr)
2031    elif (matchKeyword("delete")
2032          or matchKeyword("void")) or matchKeyword("typeof"):
2033        token = lex()
2034        expr = parseUnaryExpression()
2035        expr = delegate.createUnaryExpression(token.value, expr)
2036        if (strict and (expr.operator == "delete")) and (
2037                expr.argument.type == Syntax.Identifier):
2038            throwErrorTolerant(jsdict({}), Messages.StrictDelete)
2039    else:
2040        expr = parsePostfixExpression()
2041    return delegate.markEndIf(expr)
2042
2043
2044def binaryPrecedence(token=None, allowIn=None):
2045    prec = 0
2046    if (token.type != Token.Punctuator) and (token.type != Token.Keyword):
2047        return 0
2048    while 1:
2049        if token.value == "||":
2050            prec = 1
2051            break
2052        elif token.value == "&&":
2053            prec = 2
2054            break
2055        elif token.value == "|":
2056            prec = 3
2057            break
2058        elif token.value == "^":
2059            prec = 4
2060            break
2061        elif token.value == "&":
2062            prec = 5
2063            break
2064        elif (token.value == "!==") or ((token.value == "===") or
2065                                        ((token.value == "!=") or
2066                                         (token.value == "=="))):
2067            prec = 6
2068            break
2069        elif (token.value == "instanceof") or ((token.value == ">=") or
2070                                               ((token.value == "<=") or
2071                                                ((token.value == ">") or
2072                                                 (token.value == "<")))):
2073            prec = 7
2074            break
2075        elif token.value == "in":
2076            prec = (7 if allowIn else 0)
2077            break
2078        elif (token.value == ">>>") or ((token.value == ">>") or
2079                                        (token.value == "<<")):
2080            prec = 8
2081            break
2082        elif (token.value == "-") or (token.value == "+"):
2083            prec = 9
2084            break
2085        elif (token.value == "%") or ((token.value == "/") or
2086                                      (token.value == "*")):
2087            prec = 11
2088            break
2089        else:
2090            break
2091        break
2092    return prec
2093
2094
2095def parseBinaryExpression():
2096    marker = None
2097    markers = None
2098    expr = None
2099    token = None
2100    prec = None
2101    previousAllowIn = None
2102    stack = None
2103    right = None
2104    operator = None
2105    left = None
2106    i = None
2107    previousAllowIn = state.allowIn
2108    state.allowIn = True
2109    marker = createLocationMarker()
2110    left = parseUnaryExpression()
2111    token = lookahead
2112    prec = binaryPrecedence(token, previousAllowIn)
2113    if prec == 0:
2114        return left
2115    token.prec = prec
2116    lex()
2117    markers = [marker, createLocationMarker()]
2118    right = parseUnaryExpression()
2119    stack = [left, token, right]
2120    prec = binaryPrecedence(lookahead, previousAllowIn)
2121    while prec > 0:
2122        while (len(stack) > 2) and (prec <= stack[len(stack) - 2].prec):
2123            right = stack.pop()
2124            operator = stack.pop().value
2125            left = stack.pop()
2126            expr = delegate.createBinaryExpression(operator, left, right)
2127            markers.pop()
2128            marker = markers.pop()
2129            if marker:
2130                marker.end()
2131                marker.apply(expr)
2132            stack.append(expr)
2133            markers.append(marker)
2134        token = lex()
2135        token.prec = prec
2136        stack.append(token)
2137        markers.append(createLocationMarker())
2138        expr = parseUnaryExpression()
2139        stack.append(expr)
2140        prec = binaryPrecedence(lookahead, previousAllowIn)
2141    state.allowIn = previousAllowIn
2142    i = len(stack) - 1
2143    expr = stack[i]
2144    markers.pop()
2145    while i > 1:
2146        expr = delegate.createBinaryExpression(stack[i - 1].value,
2147                                               stack[i - 2], expr)
2148        i -= 2
2149        marker = markers.pop()
2150        if marker:
2151            marker.end()
2152            marker.apply(expr)
2153    return expr
2154
2155
2156def parseConditionalExpression():
2157    expr = None
2158    previousAllowIn = None
2159    consequent = None
2160    alternate = None
2161    delegate.markStart()
2162    expr = parseBinaryExpression()
2163    if match("?"):
2164        lex()
2165        previousAllowIn = state.allowIn
2166        state.allowIn = True
2167        consequent = parseAssignmentExpression()
2168        state.allowIn = previousAllowIn
2169        expect(":")
2170        alternate = parseAssignmentExpression()
2171        expr = delegate.markEnd(
2172            delegate.createConditionalExpression(expr, consequent, alternate))
2173    else:
2174        delegate.markEnd(jsdict({}))
2175    return expr
2176
2177
2178def parseAssignmentExpression():
2179    token = None
2180    left = None
2181    right = None
2182    node = None
2183    token = lookahead
2184    delegate.markStart()
2185    left = parseConditionalExpression()
2186    node = left
2187    if matchAssign():
2188        if not isLeftHandSide(left):
2189            throwError(jsdict({}), Messages.InvalidLHSInAssignment)
2190        if (strict and
2191            (left.type == Syntax.Identifier)) and isRestrictedWord(left.name):
2192            throwErrorTolerant(token, Messages.StrictLHSAssignment)
2193        token = lex()
2194        right = parseAssignmentExpression()
2195        node = delegate.createAssignmentExpression(token.value, left, right)
2196    return delegate.markEndIf(node)
2197
2198
2199def parseExpression():
2200    expr = None
2201    delegate.markStart()
2202    expr = parseAssignmentExpression()
2203    if match(","):
2204        expr = delegate.createSequenceExpression([expr])
2205        while index < length:
2206            if not match(","):
2207                break
2208            lex()
2209            expr.expressions.append(parseAssignmentExpression())
2210    return delegate.markEndIf(expr)
2211
2212
2213def parseStatementList():
2214    list__py__ = []
2215    statement = None
2216    while index < length:
2217        if match("}"):
2218            break
2219        statement = parseSourceElement()
2220        if ('undefined' if not 'statement' in locals() else
2221                typeof(statement)) == "undefined":
2222            break
2223        list__py__.append(statement)
2224    return list__py__
2225
2226
2227def parseBlock():
2228    block = None
2229    skipComment()
2230    delegate.markStart()
2231    expect("{")
2232    block = parseStatementList()
2233    expect("}")
2234    return delegate.markEnd(delegate.createBlockStatement(block))
2235
2236
2237def parseVariableIdentifier():
2238    token = None
2239    skipComment()
2240    delegate.markStart()
2241    token = lex()
2242    if token.type != Token.Identifier:
2243        throwUnexpected(token)
2244    return delegate.markEnd(delegate.createIdentifier(token.value))
2245
2246
2247def parseVariableDeclaration(kind=None):
2248    init = None
2249    id = None
2250    skipComment()
2251    delegate.markStart()
2252    id = parseVariableIdentifier()
2253    if strict and isRestrictedWord(id.name):
2254        throwErrorTolerant(jsdict({}), Messages.StrictVarName)
2255    if kind == "const":
2256        expect("=")
2257        init = parseAssignmentExpression()
2258    elif match("="):
2259        lex()
2260        init = parseAssignmentExpression()
2261    return delegate.markEnd(delegate.createVariableDeclarator(id, init))
2262
2263
2264def parseVariableDeclarationList(kind=None):
2265    list__py__ = []
2266    while 1:
2267        list__py__.append(parseVariableDeclaration(kind))
2268        if not match(","):
2269            break
2270        lex()
2271        if not (index < length):
2272            break
2273    return list__py__
2274
2275
2276def parseVariableStatement():
2277    declarations = None
2278    expectKeyword("var")
2279    declarations = parseVariableDeclarationList()
2280    consumeSemicolon()
2281    return delegate.createVariableDeclaration(declarations, "var")
2282
2283
2284def parseConstLetDeclaration(kind=None):
2285    declarations = None
2286    skipComment()
2287    delegate.markStart()
2288    expectKeyword(kind)
2289    declarations = parseVariableDeclarationList(kind)
2290    consumeSemicolon()
2291    return delegate.markEnd(
2292        delegate.createVariableDeclaration(declarations, kind))
2293
2294
2295def parseEmptyStatement():
2296    expect(";")
2297    return delegate.createEmptyStatement()
2298
2299
2300def parseExpressionStatement():
2301    expr = parseExpression()
2302    consumeSemicolon()
2303    return delegate.createExpressionStatement(expr)
2304
2305
2306def parseIfStatement():
2307    test = None
2308    consequent = None
2309    alternate = None
2310    expectKeyword("if")
2311    expect("(")
2312    test = parseExpression()
2313    expect(")")
2314    consequent = parseStatement()
2315    if matchKeyword("else"):
2316        lex()
2317        alternate = parseStatement()
2318    else:
2319        alternate = None
2320    return delegate.createIfStatement(test, consequent, alternate)
2321
2322
2323def parseDoWhileStatement():
2324    body = None
2325    test = None
2326    oldInIteration = None
2327    expectKeyword("do")
2328    oldInIteration = state.inIteration
2329    state.inIteration = True
2330    body = parseStatement()
2331    state.inIteration = oldInIteration
2332    expectKeyword("while")
2333    expect("(")
2334    test = parseExpression()
2335    expect(")")
2336    if match(";"):
2337        lex()
2338    return delegate.createDoWhileStatement(body, test)
2339
2340
2341def parseWhileStatement():
2342    test = None
2343    body = None
2344    oldInIteration = None
2345    expectKeyword("while")
2346    expect("(")
2347    test = parseExpression()
2348    expect(")")
2349    oldInIteration = state.inIteration
2350    state.inIteration = True
2351    body = parseStatement()
2352    state.inIteration = oldInIteration
2353    return delegate.createWhileStatement(test, body)
2354
2355
2356def parseForVariableDeclaration():
2357    token = None
2358    declarations = None
2359    delegate.markStart()
2360    token = lex()
2361    declarations = parseVariableDeclarationList()
2362    return delegate.markEnd(
2363        delegate.createVariableDeclaration(declarations, token.value))
2364
2365
2366def parseForStatement():
2367    init = None
2368    test = None
2369    update = None
2370    left = None
2371    right = None
2372    body = None
2373    oldInIteration = None
2374    update = None
2375    test = update
2376    init = test
2377    expectKeyword("for")
2378    expect("(")
2379    if match(";"):
2380        lex()
2381    else:
2382        if matchKeyword("var") or matchKeyword("let"):
2383            state.allowIn = False
2384            init = parseForVariableDeclaration()
2385            state.allowIn = True
2386            if (len(init.declarations) == 1) and matchKeyword("in"):
2387                lex()
2388                left = init
2389                right = parseExpression()
2390                init = None
2391        else:
2392            state.allowIn = False
2393            init = parseExpression()
2394            state.allowIn = True
2395            if matchKeyword("in"):
2396                if not isLeftHandSide(init):
2397                    throwError(jsdict({}), Messages.InvalidLHSInForIn)
2398                lex()
2399                left = init
2400                right = parseExpression()
2401                init = None
2402        if ('undefined'
2403                if not 'left' in locals() else typeof(left)) == "undefined":
2404            expect(";")
2405    if ('undefined'
2406            if not 'left' in locals() else typeof(left)) == "undefined":
2407        if not match(";"):
2408            test = parseExpression()
2409        expect(";")
2410        if not match(")"):
2411            update = parseExpression()
2412    expect(")")
2413    oldInIteration = state.inIteration
2414    state.inIteration = True
2415    body = parseStatement()
2416    state.inIteration = oldInIteration
2417    return (delegate.createForStatement(init, test, update, body) if (
2418        'undefined' if not 'left' in locals() else typeof(left)) == "undefined"
2419            else delegate.createForInStatement(left, right, body))
2420
2421
2422def parseContinueStatement():
2423    label = None
2424    key = None
2425    expectKeyword("continue")
2426    if (ord(source[index]) if index < len(source) else None) == 59:
2427        lex()
2428        if not state.inIteration:
2429            throwError(jsdict({}), Messages.IllegalContinue)
2430        return delegate.createContinueStatement(None)
2431    if peekLineTerminator():
2432        if not state.inIteration:
2433            throwError(jsdict({}), Messages.IllegalContinue)
2434        return delegate.createContinueStatement(None)
2435    if lookahead.type == Token.Identifier:
2436        label = parseVariableIdentifier()
2437        key = "$" + label.name
2438        if not (key in state.labelSet):
2439            throwError(jsdict({}), Messages.UnknownLabel, label.name)
2440    consumeSemicolon()
2441    if (label == None) and (not state.inIteration):
2442        throwError(jsdict({}), Messages.IllegalContinue)
2443    return delegate.createContinueStatement(label)
2444
2445
2446def parseBreakStatement():
2447    label = None
2448    key = None
2449    expectKeyword("break")
2450    if (ord(source[index]) if index < len(source) else None) == 59:
2451        lex()
2452        if not (state.inIteration or state.inSwitch):
2453            throwError(jsdict({}), Messages.IllegalBreak)
2454        return delegate.createBreakStatement(None)
2455    if peekLineTerminator():
2456        if not (state.inIteration or state.inSwitch):
2457            throwError(jsdict({}), Messages.IllegalBreak)
2458        return delegate.createBreakStatement(None)
2459    if lookahead.type == Token.Identifier:
2460        label = parseVariableIdentifier()
2461        key = "$" + label.name
2462        if not (key in state.labelSet):
2463            throwError(jsdict({}), Messages.UnknownLabel, label.name)
2464    consumeSemicolon()
2465    if (label == None) and (not (state.inIteration or state.inSwitch)):
2466        throwError(jsdict({}), Messages.IllegalBreak)
2467    return delegate.createBreakStatement(label)
2468
2469
2470def parseReturnStatement():
2471    argument = None
2472    expectKeyword("return")
2473    if not state.inFunctionBody:
2474        throwErrorTolerant(jsdict({}), Messages.IllegalReturn)
2475    if (ord(source[index]) if index < len(source) else None) == 32:
2476        if isIdentifierStart((ord(source[index + 1]) if
2477                              (index + 1) < len(source) else None)):
2478            argument = parseExpression()
2479            consumeSemicolon()
2480            return delegate.createReturnStatement(argument)
2481    if peekLineTerminator():
2482        return delegate.createReturnStatement(None)
2483    if not match(";"):
2484        if (not match("}")) and (lookahead.type != Token.EOF):
2485            argument = parseExpression()
2486    consumeSemicolon()
2487    return delegate.createReturnStatement(argument)
2488
2489
2490def parseWithStatement():
2491    object = None
2492    body = None
2493    if strict:
2494        throwErrorTolerant(jsdict({}), Messages.StrictModeWith)
2495    expectKeyword("with")
2496    expect("(")
2497    object = parseExpression()
2498    expect(")")
2499    body = parseStatement()
2500    return delegate.createWithStatement(object, body)
2501
2502
2503def parseSwitchCase():
2504    test = None
2505    consequent = []
2506    statement = None
2507    skipComment()
2508    delegate.markStart()
2509    if matchKeyword("default"):
2510        lex()
2511        test = None
2512    else:
2513        expectKeyword("case")
2514        test = parseExpression()
2515    expect(":")
2516    while index < length:
2517        if (match("}") or matchKeyword("default")) or matchKeyword("case"):
2518            break
2519        statement = parseStatement()
2520        consequent.append(statement)
2521    return delegate.markEnd(delegate.createSwitchCase(test, consequent))
2522
2523
2524def parseSwitchStatement():
2525    discriminant = None
2526    cases = None
2527    clause = None
2528    oldInSwitch = None
2529    defaultFound = None
2530    expectKeyword("switch")
2531    expect("(")
2532    discriminant = parseExpression()
2533    expect(")")
2534    expect("{")
2535    if match("}"):
2536        lex()
2537        return delegate.createSwitchStatement(discriminant)
2538    cases = []
2539    oldInSwitch = state.inSwitch
2540    state.inSwitch = True
2541    defaultFound = False
2542    while index < length:
2543        if match("}"):
2544            break
2545        clause = parseSwitchCase()
2546        if clause.test == None:
2547            if defaultFound:
2548                throwError(jsdict({}), Messages.MultipleDefaultsInSwitch)
2549            defaultFound = True
2550        cases.append(clause)
2551    state.inSwitch = oldInSwitch
2552    expect("}")
2553    return delegate.createSwitchStatement(discriminant, cases)
2554
2555
2556def parseThrowStatement():
2557    argument = None
2558    expectKeyword("throw")
2559    if peekLineTerminator():
2560        throwError(jsdict({}), Messages.NewlineAfterThrow)
2561    argument = parseExpression()
2562    consumeSemicolon()
2563    return delegate.createThrowStatement(argument)
2564
2565
2566def parseCatchClause():
2567    param = None
2568    body = None
2569    skipComment()
2570    delegate.markStart()
2571    expectKeyword("catch")
2572    expect("(")
2573    if match(")"):
2574        throwUnexpected(lookahead)
2575    param = parseVariableIdentifier()
2576    if strict and isRestrictedWord(param.name):
2577        throwErrorTolerant(jsdict({}), Messages.StrictCatchVariable)
2578    expect(")")
2579    body = parseBlock()
2580    return delegate.markEnd(delegate.createCatchClause(param, body))
2581
2582
2583def parseTryStatement():
2584    block = None
2585    handlers = []
2586    finalizer = None
2587    expectKeyword("try")
2588    block = parseBlock()
2589    if matchKeyword("catch"):
2590        handlers.append(parseCatchClause())
2591    if matchKeyword("finally"):
2592        lex()
2593        finalizer = parseBlock()
2594    if (len(handlers) == 0) and (not finalizer):
2595        throwError(jsdict({}), Messages.NoCatchOrFinally)
2596    return delegate.createTryStatement(block, [], handlers, finalizer)
2597
2598
2599def parseDebuggerStatement():
2600    expectKeyword("debugger")
2601    consumeSemicolon()
2602    return delegate.createDebuggerStatement()
2603
2604
2605def parseStatement():
2606    type = lookahead.type
2607    expr = None
2608    labeledBody = None
2609    key = None
2610    if type == Token.EOF:
2611        throwUnexpected(lookahead)
2612    skipComment()
2613    delegate.markStart()
2614    if type == Token.Punctuator:
2615        while 1:
2616            if lookahead.value == ";":
2617                return delegate.markEnd(parseEmptyStatement())
2618            elif lookahead.value == "{":
2619                return delegate.markEnd(parseBlock())
2620            elif lookahead.value == "(":
2621                return delegate.markEnd(parseExpressionStatement())
2622            else:
2623                break
2624            break
2625    if type == Token.Keyword:
2626        while 1:
2627            if lookahead.value == "break":
2628                return delegate.markEnd(parseBreakStatement())
2629            elif lookahead.value == "continue":
2630                return delegate.markEnd(parseContinueStatement())
2631            elif lookahead.value == "debugger":
2632                return delegate.markEnd(parseDebuggerStatement())
2633            elif lookahead.value == "do":
2634                return delegate.markEnd(parseDoWhileStatement())
2635            elif lookahead.value == "for":
2636                return delegate.markEnd(parseForStatement())
2637            elif lookahead.value == "function":
2638                return delegate.markEnd(parseFunctionDeclaration())
2639            elif lookahead.value == "if":
2640                return delegate.markEnd(parseIfStatement())
2641            elif lookahead.value == "return":
2642                return delegate.markEnd(parseReturnStatement())
2643            elif lookahead.value == "switch":
2644                return delegate.markEnd(parseSwitchStatement())
2645            elif lookahead.value == "throw":
2646                return delegate.markEnd(parseThrowStatement())
2647            elif lookahead.value == "try":
2648                return delegate.markEnd(parseTryStatement())
2649            elif lookahead.value == "var":
2650                return delegate.markEnd(parseVariableStatement())
2651            elif lookahead.value == "while":
2652                return delegate.markEnd(parseWhileStatement())
2653            elif lookahead.value == "with":
2654                return delegate.markEnd(parseWithStatement())
2655            else:
2656                break
2657            break
2658    expr = parseExpression()
2659    if (expr.type == Syntax.Identifier) and match(":"):
2660        lex()
2661        key = "$" + expr.name
2662        if key in state.labelSet:
2663            throwError(jsdict({}), Messages.Redeclaration, "Label", expr.name)
2664        state.labelSet[key] = True
2665        labeledBody = parseStatement()
2666        del state.labelSet[key]
2667        return delegate.markEnd(
2668            delegate.createLabeledStatement(expr, labeledBody))
2669    consumeSemicolon()
2670    return delegate.markEnd(delegate.createExpressionStatement(expr))
2671
2672
2673def parseFunctionSourceElements():
2674    global strict
2675    sourceElement = None
2676    sourceElements = []
2677    token = None
2678    directive = None
2679    firstRestricted = None
2680    oldLabelSet = None
2681    oldInIteration = None
2682    oldInSwitch = None
2683    oldInFunctionBody = None
2684    skipComment()
2685    delegate.markStart()
2686    expect("{")
2687    while index < length:
2688        if lookahead.type != Token.StringLiteral:
2689            break
2690        token = lookahead
2691        sourceElement = parseSourceElement()
2692        sourceElements.append(sourceElement)
2693        if sourceElement.expression.type != Syntax.Literal:
2694            break
2695        directive = source[(token.range[0] + 1):(token.range[1] - 1)]
2696        if directive == "use strict":
2697            strict = True
2698            if firstRestricted:
2699                throwErrorTolerant(firstRestricted,
2700                                   Messages.StrictOctalLiteral)
2701        else:
2702            if (not firstRestricted) and token.octal:
2703                firstRestricted = token
2704    oldLabelSet = state.labelSet
2705    oldInIteration = state.inIteration
2706    oldInSwitch = state.inSwitch
2707    oldInFunctionBody = state.inFunctionBody
2708    state.labelSet = jsdict({})
2709    state.inIteration = False
2710    state.inSwitch = False
2711    state.inFunctionBody = True
2712    while index < length:
2713        if match("}"):
2714            break
2715        sourceElement = parseSourceElement()
2716        if ('undefined' if not 'sourceElement' in locals() else
2717                typeof(sourceElement)) == "undefined":
2718            break
2719        sourceElements.append(sourceElement)
2720    expect("}")
2721    state.labelSet = oldLabelSet
2722    state.inIteration = oldInIteration
2723    state.inSwitch = oldInSwitch
2724    state.inFunctionBody = oldInFunctionBody
2725    return delegate.markEnd(delegate.createBlockStatement(sourceElements))
2726
2727
2728def parseParams(firstRestricted=None):
2729    param = None
2730    params = []
2731    token = None
2732    stricted = None
2733    paramSet = None
2734    key = None
2735    message = None
2736    expect("(")
2737    if not match(")"):
2738        paramSet = jsdict({})
2739        while index < length:
2740            token = lookahead
2741            param = parseVariableIdentifier()
2742            key = "$" + token.value
2743            if strict:
2744                if isRestrictedWord(token.value):
2745                    stricted = token
2746                    message = Messages.StrictParamName
2747                if key in paramSet:
2748                    stricted = token
2749                    message = Messages.StrictParamDupe
2750            elif not firstRestricted:
2751                if isRestrictedWord(token.value):
2752                    firstRestricted = token
2753                    message = Messages.StrictParamName
2754                elif isStrictModeReservedWord(token.value):
2755                    firstRestricted = token
2756                    message = Messages.StrictReservedWord
2757                elif key in paramSet:
2758                    firstRestricted = token
2759                    message = Messages.StrictParamDupe
2760            params.append(param)
2761            paramSet[key] = True
2762            if match(")"):
2763                break
2764            expect(",")
2765    expect(")")
2766    return jsdict({
2767        "params": params,
2768        "stricted": stricted,
2769        "firstRestricted": firstRestricted,
2770        "message": message,
2771    })
2772
2773
2774def parseFunctionDeclaration():
2775    global strict
2776    id = None
2777    params = []
2778    body = None
2779    token = None
2780    stricted = None
2781    tmp = None
2782    firstRestricted = None
2783    message = None
2784    previousStrict = None
2785    skipComment()
2786    delegate.markStart()
2787    expectKeyword("function")
2788    token = lookahead
2789    id = parseVariableIdentifier()
2790    if strict:
2791        if isRestrictedWord(token.value):
2792            throwErrorTolerant(token, Messages.StrictFunctionName)
2793    else:
2794        if isRestrictedWord(token.value):
2795            firstRestricted = token
2796            message = Messages.StrictFunctionName
2797        elif isStrictModeReservedWord(token.value):
2798            firstRestricted = token
2799            message = Messages.StrictReservedWord
2800    tmp = parseParams(firstRestricted)
2801    params = tmp.params
2802    stricted = tmp.stricted
2803    firstRestricted = tmp.firstRestricted
2804    if tmp.message:
2805        message = tmp.message
2806    previousStrict = strict
2807    body = parseFunctionSourceElements()
2808    if strict and firstRestricted:
2809        throwError(firstRestricted, message)
2810    if strict and stricted:
2811        throwErrorTolerant(stricted, message)
2812    strict = previousStrict
2813    return delegate.markEnd(
2814        delegate.createFunctionDeclaration(id, params, [], body))
2815
2816
2817def parseFunctionExpression():
2818    global strict
2819    token = None
2820    id = None
2821    stricted = None
2822    firstRestricted = None
2823    message = None
2824    tmp = None
2825    params = []
2826    body = None
2827    previousStrict = None
2828    delegate.markStart()
2829    expectKeyword("function")
2830    if not match("("):
2831        token = lookahead
2832        id = parseVariableIdentifier()
2833        if strict:
2834            if isRestrictedWord(token.value):
2835                throwErrorTolerant(token, Messages.StrictFunctionName)
2836        else:
2837            if isRestrictedWord(token.value):
2838                firstRestricted = token
2839                message = Messages.StrictFunctionName
2840            elif isStrictModeReservedWord(token.value):
2841                firstRestricted = token
2842                message = Messages.StrictReservedWord
2843    tmp = parseParams(firstRestricted)
2844    params = tmp.params
2845    stricted = tmp.stricted
2846    firstRestricted = tmp.firstRestricted
2847    if tmp.message:
2848        message = tmp.message
2849    previousStrict = strict
2850    body = parseFunctionSourceElements()
2851    if strict and firstRestricted:
2852        throwError(firstRestricted, message)
2853    if strict and stricted:
2854        throwErrorTolerant(stricted, message)
2855    strict = previousStrict
2856    return delegate.markEnd(
2857        delegate.createFunctionExpression(id, params, [], body))
2858
2859
2860def parseSourceElement():
2861    if lookahead.type == Token.Keyword:
2862        while 1:
2863            if (lookahead.value == "let") or (lookahead.value == "const"):
2864                return parseConstLetDeclaration(lookahead.value)
2865            elif lookahead.value == "function":
2866                return parseFunctionDeclaration()
2867            else:
2868                return parseStatement()
2869            break
2870    if lookahead.type != Token.EOF:
2871        return parseStatement()
2872
2873
2874def parseSourceElements():
2875    global strict
2876    sourceElement = None
2877    sourceElements = []
2878    token = None
2879    directive = None
2880    firstRestricted = None
2881    while index < length:
2882        token = lookahead
2883        if token.type != Token.StringLiteral:
2884            break
2885        sourceElement = parseSourceElement()
2886        sourceElements.append(sourceElement)
2887        if sourceElement.expression.type != Syntax.Literal:
2888            break
2889        directive = source[(token.range[0] + 1):(token.range[1] - 1)]
2890        if directive == "use strict":
2891            strict = True
2892            if firstRestricted:
2893                throwErrorTolerant(firstRestricted,
2894                                   Messages.StrictOctalLiteral)
2895        else:
2896            if (not firstRestricted) and token.octal:
2897                firstRestricted = token
2898    while index < length:
2899        sourceElement = parseSourceElement()
2900        if ('undefined' if not 'sourceElement' in locals() else
2901                typeof(sourceElement)) == "undefined":
2902            break
2903        sourceElements.append(sourceElement)
2904    return sourceElements
2905
2906
2907def parseProgram():
2908    global strict
2909    body = None
2910    skipComment()
2911    delegate.markStart()
2912    strict = False
2913    peek()
2914    body = parseSourceElements()
2915    return delegate.markEnd(delegate.createProgram(body))
2916
2917
2918def collectToken():
2919    start = None
2920    loc = None
2921    token = None
2922    range = None
2923    value = None
2924    skipComment()
2925    start = index
2926    loc = jsdict({
2927        "start":
2928        jsdict({
2929            "line": lineNumber,
2930            "column": index - lineStart,
2931        }),
2932    })
2933    token = extra.advance()
2934    loc.end = jsdict({
2935        "line": lineNumber,
2936        "column": index - lineStart,
2937    })
2938    if token.type != Token.EOF:
2939        range = [token.range[0], token.range[1]]
2940        value = source[token.range[0]:token.range[1]]
2941        extra.tokens.append(
2942            jsdict({
2943                "type": TokenName[token.type],
2944                "value": value,
2945                "range": range,
2946                "loc": loc,
2947            }))
2948    return token
2949
2950
2951def collectRegex():
2952    pos = None
2953    loc = None
2954    regex = None
2955    token = None
2956    skipComment()
2957    pos = index
2958    loc = jsdict({
2959        "start":
2960        jsdict({
2961            "line": lineNumber,
2962            "column": index - lineStart,
2963        }),
2964    })
2965    regex = extra.scanRegExp()
2966    loc.end = jsdict({
2967        "line": lineNumber,
2968        "column": index - lineStart,
2969    })
2970    if not extra.tokenize:
2971        if len(extra.tokens) > 0:
2972            token = extra.tokens[len(extra.tokens) - 1]
2973            if (token.range[0] == pos) and (token.type == "Punctuator"):
2974                if (token.value == "/") or (token.value == "/="):
2975                    extra.tokens.pop()
2976        extra.tokens.append(
2977            jsdict({
2978                "type": "RegularExpression",
2979                "value": regex.literal,
2980                "range": [pos, index],
2981                "loc": loc,
2982            }))
2983    return regex
2984
2985
2986def filterTokenLocation():
2987    i = None
2988    entry = None
2989    token = None
2990    tokens = []
2991    i = 0
2992    while 1:
2993        if not (i < len(extra.tokens)):
2994            break
2995        entry = extra.tokens[i]
2996        token = jsdict({
2997            "type": entry.type,
2998            "value": entry.value,
2999        })
3000        if extra.range:
3001            token.range = entry.range
3002        if extra.loc:
3003            token.loc = entry.loc
3004        tokens.append(token)
3005        i += 1
3006    extra.tokens = tokens
3007
3008
3009class LocationMarker(object):
3010    def __init__(self=None):
3011        self.marker = [index, lineNumber, index - lineStart, 0, 0, 0]
3012
3013    def end(self=None):
3014        self.marker[3] = index
3015        self.marker[4] = lineNumber
3016        self.marker[5] = index - lineStart
3017
3018    def apply(self=None, node=None):
3019        if extra.range:
3020            node.range = [self.marker[0], self.marker[3]]
3021        if extra.loc:
3022            node.loc = jsdict({
3023                "start":
3024                jsdict({
3025                    "line": self.marker[1],
3026                    "column": self.marker[2],
3027                }),
3028                "end":
3029                jsdict({
3030                    "line": self.marker[4],
3031                    "column": self.marker[5],
3032                }),
3033            })
3034        node = delegate.postProcess(node)
3035
3036
3037def createLocationMarker():
3038    if (not extra.loc) and (not extra.range):
3039        return None
3040    skipComment()
3041    return LocationMarker()
3042
3043
3044def patch():
3045    global advance, scanRegExp
3046    if ('undefined' if not ('tokens' in extra) else typeof(
3047            extra.tokens)) != "undefined":
3048        extra.advance = advance
3049        extra.scanRegExp = scanRegExp
3050        advance = collectToken
3051        scanRegExp = collectRegex
3052
3053
3054def unpatch():
3055    global advance, scanRegExp
3056    if ('undefined' if not ('scanRegExp' in extra) else typeof(
3057            extra.scanRegExp)) == "function":
3058        advance = extra.advance
3059        scanRegExp = extra.scanRegExp
3060
3061
3062def tokenize(code, **options):
3063    global delegate, source, index, lineNumber, lineStart, length, lookahead, state, extra
3064    options = jsdict(options)
3065    toString = None
3066    token = None
3067    tokens = None
3068    toString = str
3069    if (('undefined' if not 'code' in locals() else typeof(code)) !=
3070            "string") and (not isinstance(code, str)):
3071        code = toString(code)
3072    delegate = SyntaxTreeDelegate
3073    source = code
3074    index = 0
3075    lineNumber = (1 if len(source) > 0 else 0)
3076    lineStart = 0
3077    length = len(source)
3078    lookahead = None
3079    state = jsdict({
3080        "allowIn": True,
3081        "labelSet": jsdict({}),
3082        "inFunctionBody": False,
3083        "inIteration": False,
3084        "inSwitch": False,
3085        "lastCommentStart": -1,
3086    })
3087    extra = jsdict({})
3088    options = options or jsdict({})
3089    options.tokens = True
3090    extra.tokens = []
3091    extra.tokenize = True
3092    extra.openParenToken = -1
3093    extra.openCurlyToken = -1
3094    extra.range = (('undefined' if not ('range' in options) else typeof(
3095        options.range)) == "boolean") and options.range
3096    extra.loc = (('undefined' if not ('loc' in options) else typeof(
3097        options.loc)) == "boolean") and options.loc
3098    if (('undefined' if not ('comment' in options) else typeof(
3099            options.comment)) == "boolean") and options.comment:
3100        extra.comments = []
3101    if (('undefined' if not ('tolerant' in options) else typeof(
3102            options.tolerant)) == "boolean") and options.tolerant:
3103        extra.errors = []
3104    if length > 0:
3105        if (typeof(source[0])) == "undefined":
3106            if isinstance(code, str):
3107                source = code.valueOf()
3108    patch()
3109    try:
3110        peek()
3111        if lookahead.type == Token.EOF:
3112            return extra.tokens
3113        token = lex()
3114        while lookahead.type != Token.EOF:
3115            try:
3116                token = lex()
3117            except Exception as lexError:
3118                token = lookahead
3119                if extra.errors:
3120                    extra.errors.append(lexError)
3121                    break
3122                else:
3123                    raise
3124        filterTokenLocation()
3125        tokens = extra.tokens
3126        if ('undefined' if not ('comments' in extra) else typeof(
3127                extra.comments)) != "undefined":
3128            tokens.comments = extra.comments
3129        if ('undefined' if not ('errors' in extra) else typeof(
3130                extra.errors)) != "undefined":
3131            tokens.errors = extra.errors
3132    except Exception as e:
3133        raise
3134    finally:
3135        unpatch()
3136        extra = jsdict({})
3137    return tokens
3138
3139
3140def parse(code, **options):
3141    global delegate, source, index, lineNumber, lineStart, length, lookahead, state, extra
3142    options = jsdict(options)
3143    program = None
3144    toString = None
3145    toString = str
3146    if (('undefined' if not 'code' in locals() else typeof(code)) !=
3147            "string") and (not isinstance(code, str)):
3148        code = toString(code)
3149    delegate = SyntaxTreeDelegate
3150    source = code
3151    index = 0
3152    lineNumber = (1 if len(source) > 0 else 0)
3153    lineStart = 0
3154    length = len(source)
3155    lookahead = None
3156    state = jsdict({
3157        "allowIn": True,
3158        "labelSet": jsdict({}),
3159        "inFunctionBody": False,
3160        "inIteration": False,
3161        "inSwitch": False,
3162        "lastCommentStart": -1,
3163        "markerStack": [],
3164    })
3165    extra = jsdict({})
3166    if ('undefined'
3167            if not 'options' in locals() else typeof(options)) != "undefined":
3168        extra.range = (('undefined' if not ('range' in options) else typeof(
3169            options.range)) == "boolean") and options.range
3170        extra.loc = (('undefined' if not ('loc' in options) else typeof(
3171            options.loc)) == "boolean") and options.loc
3172        if (extra.loc and
3173            (options.source != None)) and (options.source != undefined):
3174            extra.source = toString(options.source)
3175        if (('undefined' if not ('tokens' in options) else typeof(
3176                options.tokens)) == "boolean") and options.tokens:
3177            extra.tokens = []
3178        if (('undefined' if not ('comment' in options) else typeof(
3179                options.comment)) == "boolean") and options.comment:
3180            extra.comments = []
3181        if (('undefined' if not ('tolerant' in options) else typeof(
3182                options.tolerant)) == "boolean") and options.tolerant:
3183            extra.errors = []
3184    if length > 0:
3185        if (typeof(source[0])) == "undefined":
3186            if isinstance(code, str):
3187                source = code.valueOf()
3188    patch()
3189    try:
3190        program = parseProgram()
3191        if ('undefined' if not ('comments' in extra) else typeof(
3192                extra.comments)) != "undefined":
3193            program.comments = extra.comments
3194        if ('undefined' if not ('tokens' in extra) else typeof(
3195                extra.tokens)) != "undefined":
3196            filterTokenLocation()
3197            program.tokens = extra.tokens
3198        if ('undefined' if not ('errors' in extra) else typeof(
3199                extra.errors)) != "undefined":
3200            program.errors = extra.errors
3201    except Exception as e:
3202        raise
3203    finally:
3204        unpatch()
3205        extra = jsdict({})
3206    return program
3207
3208
3209parse('var = 490 \n a=4;')
3210