#NEWLINE# def Statement( tokenizer , staticContext ) : #NEWLINE# #INDENT# 'Parses a Statement.' #NEWLINE# tokenType = tokenizer . get ( True ) #NEWLINE# builder = staticContext . builder #NEWLINE# if ( tokenType == 'function' ) : #NEWLINE# #INDENT# if ( len ( staticContext . statementStack ) > 1 ) : #NEWLINE# #INDENT# kind = 'statement_form' #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# kind = 'declared_form' #NEWLINE# #UNINDENT# return FunctionDefinition ( tokenizer , staticContext , True , kind ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'left_curly' ) : #NEWLINE# #INDENT# node = Statements ( tokenizer , staticContext ) #NEWLINE# tokenizer . mustMatch ( 'right_curly' ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'if' ) : #NEWLINE# #INDENT# node = builder . IF_build ( tokenizer ) #NEWLINE# builder . IF_setCondition ( node , ParenExpression ( tokenizer , staticContext ) ) #NEWLINE# staticContext . statementStack . append ( node ) #NEWLINE# builder . IF_setThenPart ( node , Statement ( tokenizer , staticContext ) ) #NEWLINE# if tokenizer . match ( 'else' ) : #NEWLINE# #INDENT# comments = tokenizer . getComments ( ) #NEWLINE# elsePart = Statement ( tokenizer , staticContext ) #NEWLINE# builder . COMMENTS_add ( elsePart , node , comments ) #NEWLINE# builder . IF_setElsePart ( node , elsePart ) #NEWLINE# #UNINDENT# staticContext . statementStack . pop ( ) #NEWLINE# builder . IF_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'switch' ) : #NEWLINE# #INDENT# node = builder . SWITCH_build ( tokenizer ) #NEWLINE# builder . SWITCH_setDiscriminant ( node , ParenExpression ( tokenizer , staticContext ) ) #NEWLINE# staticContext . statementStack . append ( node ) #NEWLINE# tokenizer . mustMatch ( 'left_curly' ) #NEWLINE# tokenType = tokenizer . get ( ) #NEWLINE# while ( tokenType != 'right_curly' ) : #NEWLINE# #INDENT# if ( tokenType == 'default' ) : #NEWLINE# #INDENT# if ( node . defaultIndex >= 0 ) : #NEWLINE# #INDENT# raise SyntaxError ( 'More than one switch default' , tokenizer ) #NEWLINE# #UNINDENT# childNode = builder . DEFAULT_build ( tokenizer ) #NEWLINE# builder . SWITCH_setDefaultIndex ( node , ( len ( node ) - 1 ) ) #NEWLINE# tokenizer . mustMatch ( 'colon' ) #NEWLINE# builder . DEFAULT_initializeStatements ( childNode , tokenizer ) #NEWLINE# while True : #NEWLINE# #INDENT# tokenType = tokenizer . peek ( True ) #NEWLINE# if ( ( tokenType == 'case' ) or ( tokenType == 'default' ) or ( tokenType == 'right_curly' ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# builder . DEFAULT_addStatement ( childNode , Statement ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# builder . DEFAULT_finish ( childNode ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'case' ) : #NEWLINE# #INDENT# childNode = builder . CASE_build ( tokenizer ) #NEWLINE# builder . CASE_setLabel ( childNode , Expression ( tokenizer , staticContext ) ) #NEWLINE# tokenizer . mustMatch ( 'colon' ) #NEWLINE# builder . CASE_initializeStatements ( childNode , tokenizer ) #NEWLINE# while True : #NEWLINE# #INDENT# tokenType = tokenizer . peek ( True ) #NEWLINE# if ( ( tokenType == 'case' ) or ( tokenType == 'default' ) or ( tokenType == 'right_curly' ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# builder . CASE_addStatement ( childNode , Statement ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# builder . CASE_finish ( childNode ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid switch case' , tokenizer ) #NEWLINE# #UNINDENT# #UNINDENT# builder . SWITCH_addCase ( node , childNode ) #NEWLINE# tokenType = tokenizer . get ( ) #NEWLINE# #UNINDENT# staticContext . statementStack . pop ( ) #NEWLINE# builder . SWITCH_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'for' ) : #NEWLINE# #INDENT# node = builder . FOR_build ( tokenizer ) #NEWLINE# forBlock = None #NEWLINE# if ( tokenizer . match ( 'identifier' ) and ( tokenizer . token . value == 'each' ) ) : #NEWLINE# #INDENT# builder . FOR_rebuildForEach ( node ) #NEWLINE# #UNINDENT# tokenizer . mustMatch ( 'left_paren' ) #NEWLINE# tokenType = tokenizer . peek ( ) #NEWLINE# childNode = None #NEWLINE# if ( tokenType != 'semicolon' ) : #NEWLINE# #INDENT# staticContext . inForLoopInit = True #NEWLINE# if ( ( tokenType == 'var' ) or ( tokenType == 'const' ) ) : #NEWLINE# #INDENT# tokenizer . get ( ) #NEWLINE# childNode = Variables ( tokenizer , staticContext ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'let' ) : #NEWLINE# #INDENT# tokenizer . get ( ) #NEWLINE# if ( tokenizer . peek ( ) == 'left_paren' ) : #NEWLINE# #INDENT# childNode = LetBlock ( tokenizer , staticContext , False ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# forBlock = builder . BLOCK_build ( tokenizer , staticContext . blockId ) #NEWLINE# staticContext . blockId += 1 #NEWLINE# staticContext . statementStack . append ( forBlock ) #NEWLINE# childNode = Variables ( tokenizer , staticContext , forBlock ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# childNode = Expression ( tokenizer , staticContext ) #NEWLINE# #UNINDENT# #UNINDENT# staticContext . inForLoopInit = False #NEWLINE# #UNINDENT# if ( childNode and tokenizer . match ( 'in' ) ) : #NEWLINE# #INDENT# builder . FOR_rebuildForIn ( node ) #NEWLINE# builder . FOR_setObject ( node , Expression ( tokenizer , staticContext ) , forBlock ) #NEWLINE# if ( ( childNode . type == 'var' ) or ( childNode . type == 'let' ) ) : #NEWLINE# #INDENT# if ( len ( childNode ) != 1 ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid for..in left-hand side' , tokenizer ) #NEWLINE# #UNINDENT# builder . FOR_setIterator ( node , childNode , forBlock ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . FOR_setIterator ( node , childNode , forBlock ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# builder . FOR_setSetup ( node , childNode ) #NEWLINE# tokenizer . mustMatch ( 'semicolon' ) #NEWLINE# if node . isEach : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid for each..in loop' , tokenizer ) #NEWLINE# #UNINDENT# if ( tokenizer . peek ( ) == 'semicolon' ) : #NEWLINE# #INDENT# builder . FOR_setCondition ( node , None ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . FOR_setCondition ( node , Expression ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# tokenizer . mustMatch ( 'semicolon' ) #NEWLINE# if ( tokenizer . peek ( ) == 'right_paren' ) : #NEWLINE# #INDENT# builder . FOR_setUpdate ( node , None ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . FOR_setUpdate ( node , Expression ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# #UNINDENT# tokenizer . mustMatch ( 'right_paren' ) #NEWLINE# builder . FOR_setBody ( node , nest ( tokenizer , staticContext , node , Statement ) ) #NEWLINE# if forBlock : #NEWLINE# #INDENT# builder . BLOCK_finish ( forBlock ) #NEWLINE# staticContext . statementStack . pop ( ) #NEWLINE# #UNINDENT# builder . FOR_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'while' ) : #NEWLINE# #INDENT# node = builder . WHILE_build ( tokenizer ) #NEWLINE# builder . WHILE_setCondition ( node , ParenExpression ( tokenizer , staticContext ) ) #NEWLINE# builder . WHILE_setBody ( node , nest ( tokenizer , i , node , Statement ) ) #NEWLINE# builder . WHILE_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'do' ) : #NEWLINE# #INDENT# node = builder . DO_build ( tokenizer ) #NEWLINE# builder . DO_setBody ( node , nest ( tokenizer , staticContext , node , Statement , 'while' ) ) #NEWLINE# builder . DO_setCondition ( node , ParenExpression ( tokenizer , staticContext ) ) #NEWLINE# builder . DO_finish ( node ) #NEWLINE# if ( not staticContext . ecma3OnlyMode ) : #NEWLINE# #INDENT# tokenizer . match ( 'semicolon' ) #NEWLINE# return node #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( tokenType == 'break' ) or ( tokenType == 'continue' ) ) : #NEWLINE# #INDENT# if ( tokenType == 'break' ) : #NEWLINE# #INDENT# node = builder . BREAK_build ( tokenizer ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# node = builder . CONTINUE_build ( tokenizer ) #NEWLINE# #UNINDENT# if ( tokenizer . peekOnSameLine ( ) == 'identifier' ) : #NEWLINE# #INDENT# tokenizer . get ( ) #NEWLINE# if ( tokenType == 'break' ) : #NEWLINE# #INDENT# builder . BREAK_setLabel ( node , tokenizer . token . value ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . CONTINUE_setLabel ( node , tokenizer . token . value ) #NEWLINE# #UNINDENT# #UNINDENT# statementStack = staticContext . statementStack #NEWLINE# i = len ( statementStack ) #NEWLINE# label = ( node . label if hasattr ( node , 'label' ) else None ) #NEWLINE# if label : #NEWLINE# #INDENT# while True : #NEWLINE# #INDENT# i -= 1 #NEWLINE# if ( i < 0 ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Label not found' , tokenizer ) #NEWLINE# #UNINDENT# if ( getattr ( statementStack [ i ] , 'label' , None ) == label ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# while ( ( i < ( len ( statementStack ) - 1 ) ) and ( statementStack [ ( i + 1 ) ] . type == 'label' ) ) : #NEWLINE# #INDENT# i += 1 #NEWLINE# #UNINDENT# if ( ( i < ( len ( statementStack ) - 1 ) ) and getattr ( statementStack [ ( i + 1 ) ] , 'isLoop' , False ) ) : #NEWLINE# #INDENT# i += 1 #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'continue' ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid continue' , tokenizer ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# while True : #NEWLINE# #INDENT# i -= 1 #NEWLINE# if ( i < 0 ) : #NEWLINE# #INDENT# if ( tokenType == 'break' ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid break' , tokenizer ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid continue' , tokenizer ) #NEWLINE# #UNINDENT# #UNINDENT# if ( getattr ( statementStack [ i ] , 'isLoop' , False ) or ( ( tokenType == 'break' ) and ( statementStack [ i ] . type == 'switch' ) ) ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if ( tokenType == 'break' ) : #NEWLINE# #INDENT# builder . BREAK_finish ( node ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . CONTINUE_finish ( node ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'try' ) : #NEWLINE# #INDENT# node = builder . TRY_build ( tokenizer ) #NEWLINE# builder . TRY_setTryBlock ( node , Block ( tokenizer , staticContext ) ) #NEWLINE# while tokenizer . match ( 'catch' ) : #NEWLINE# #INDENT# childNode = builder . CATCH_build ( tokenizer ) #NEWLINE# tokenizer . mustMatch ( 'left_paren' ) #NEWLINE# nextTokenType = tokenizer . get ( ) #NEWLINE# if ( ( nextTokenType == 'left_bracket' ) or ( nextTokenType == 'left_curly' ) ) : #NEWLINE# #INDENT# tokenizer . unget ( ) #NEWLINE# exception = DestructuringExpression ( tokenizer , staticContext , True ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( nextTokenType == 'identifier' ) : #NEWLINE# #INDENT# exception = builder . CATCH_wrapException ( tokenizer ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# raise SyntaxError ( 'Missing identifier in catch' , tokenizer ) #NEWLINE# #UNINDENT# #UNINDENT# builder . CATCH_setException ( childNode , exception ) #NEWLINE# if tokenizer . match ( 'if' ) : #NEWLINE# #INDENT# if staticContext . ecma3OnlyMode : #NEWLINE# #INDENT# raise SyntaxError ( 'Illegal catch guard' , tokenizer ) #NEWLINE# #UNINDENT# if ( ( node . getChildrenLength ( ) > 0 ) and ( not node . getUnrelatedChildren ( ) [ 0 ] . guard ) ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Guarded catch after unguarded' , tokenizer ) #NEWLINE# #UNINDENT# builder . CATCH_setGuard ( childNode , Expression ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# builder . CATCH_setGuard ( childNode , None ) #NEWLINE# #UNINDENT# tokenizer . mustMatch ( 'right_paren' ) #NEWLINE# builder . CATCH_setBlock ( childNode , Block ( tokenizer , staticContext ) ) #NEWLINE# builder . CATCH_finish ( childNode ) #NEWLINE# builder . TRY_addCatch ( node , childNode ) #NEWLINE# #UNINDENT# builder . TRY_finishCatches ( node ) #NEWLINE# if tokenizer . match ( 'finally' ) : #NEWLINE# #INDENT# builder . TRY_setFinallyBlock ( node , Block ( tokenizer , staticContext ) ) #NEWLINE# #UNINDENT# if ( ( node . getChildrenLength ( ) == 0 ) and ( not hasattr ( node , 'finallyBlock' ) ) ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Invalid try statement' , tokenizer ) #NEWLINE# #UNINDENT# builder . TRY_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( tokenType == 'catch' ) or ( tokenType == 'finally' ) ) : #NEWLINE# #INDENT# raise SyntaxError ( ( tokens [ tokenType ] + ' without preceding try' ) , tokenizer ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'throw' ) : #NEWLINE# #INDENT# node = builder . THROW_build ( tokenizer ) #NEWLINE# builder . THROW_setException ( node , Expression ( tokenizer , staticContext ) ) #NEWLINE# builder . THROW_finish ( node ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'return' ) : #NEWLINE# #INDENT# node = returnOrYield ( tokenizer , staticContext ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'with' ) : #NEWLINE# #INDENT# node = builder . WITH_build ( tokenizer ) #NEWLINE# builder . WITH_setObject ( node , ParenExpression ( tokenizer , staticContext ) ) #NEWLINE# builder . WITH_setBody ( node , nest ( tokenizer , staticContext , node , Statement ) ) #NEWLINE# builder . WITH_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( tokenType == 'var' ) or ( tokenType == 'const' ) ) : #NEWLINE# #INDENT# node = Variables ( tokenizer , staticContext ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'let' ) : #NEWLINE# #INDENT# if ( tokenizer . peek ( ) == 'left_paren' ) : #NEWLINE# #INDENT# node = LetBlock ( tokenizer , staticContext , True ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# node = Variables ( tokenizer , staticContext ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'debugger' ) : #NEWLINE# #INDENT# node = builder . DEBUGGER_build ( tokenizer ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( tokenType == 'newline' ) or ( tokenType == 'semicolon' ) ) : #NEWLINE# #INDENT# node = builder . SEMICOLON_build ( tokenizer ) #NEWLINE# builder . SEMICOLON_setExpression ( node , None ) #NEWLINE# builder . SEMICOLON_finish ( tokenizer ) #NEWLINE# return node #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( tokenType == 'identifier' ) : #NEWLINE# #INDENT# tokenType = tokenizer . peek ( ) #NEWLINE# if ( tokenType == 'colon' ) : #NEWLINE# #INDENT# label = tokenizer . token . value #NEWLINE# statementStack = staticContext . statementStack #NEWLINE# i = ( len ( statementStack ) - 1 ) #NEWLINE# while ( i >= 0 ) : #NEWLINE# #INDENT# if ( getattr ( statementStack [ i ] , 'label' , None ) == label ) : #NEWLINE# #INDENT# raise SyntaxError ( 'Duplicate label' , tokenizer ) #NEWLINE# #UNINDENT# i -= 1 #NEWLINE# #UNINDENT# tokenizer . get ( ) #NEWLINE# node = builder . LABEL_build ( tokenizer ) #NEWLINE# builder . LABEL_setLabel ( node , label ) #NEWLINE# builder . LABEL_setStatement ( node , nest ( tokenizer , staticContext , node , Statement ) ) #NEWLINE# builder . LABEL_finish ( node ) #NEWLINE# return node #NEWLINE# #UNINDENT# #UNINDENT# node = builder . SEMICOLON_build ( tokenizer ) #NEWLINE# tokenizer . unget ( ) #NEWLINE# builder . SEMICOLON_setExpression ( node , Expression ( tokenizer , staticContext ) ) #NEWLINE# node . end = node . expression . end #NEWLINE# builder . SEMICOLON_finish ( node ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# MagicalSemicolon ( tokenizer ) #NEWLINE# return node