package parser

import (
	
	
	
	

	
	
	
	
)

func ( *_parser) () *ast.BlockStatement {
	 := &ast.BlockStatement{}
	.LeftBrace = .expect(token.LEFT_BRACE)
	.List = .parseStatementList()
	.RightBrace = .expect(token.RIGHT_BRACE)

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.SEMICOLON)
	return &ast.EmptyStatement{Semicolon: }
}

func ( *_parser) () ( []ast.Statement) {
	for .token != token.RIGHT_BRACE && .token != token.EOF {
		.scope.allowLet = true
		 = append(, .parseStatement())
	}

	return
}

func ( *_parser) () ast.Statement {

	if .token == token.EOF {
		.errorUnexpectedToken(.token)
		return &ast.BadStatement{From: .idx, To: .idx + 1}
	}

	switch .token {
	case token.SEMICOLON:
		return .parseEmptyStatement()
	case token.LEFT_BRACE:
		return .parseBlockStatement()
	case token.IF:
		return .parseIfStatement()
	case token.DO:
		return .parseDoWhileStatement()
	case token.WHILE:
		return .parseWhileStatement()
	case token.FOR:
		return .parseForOrForInStatement()
	case token.BREAK:
		return .parseBreakStatement()
	case token.CONTINUE:
		return .parseContinueStatement()
	case token.DEBUGGER:
		return .parseDebuggerStatement()
	case token.WITH:
		return .parseWithStatement()
	case token.VAR:
		return .parseVariableStatement()
	case token.LET:
		 := .peek()
		if  == token.LEFT_BRACKET || .scope.allowLet && (token.IsId() ||  == token.LEFT_BRACE) {
			return .parseLexicalDeclaration(.token)
		}
		.insertSemicolon = true
	case token.CONST:
		return .parseLexicalDeclaration(.token)
	case token.ASYNC:
		if  := .parseMaybeAsyncFunction(true);  != nil {
			return &ast.FunctionDeclaration{
				Function: ,
			}
		}
	case token.FUNCTION:
		return &ast.FunctionDeclaration{
			Function: .parseFunction(true, false, .idx),
		}
	case token.CLASS:
		return &ast.ClassDeclaration{
			Class: .parseClass(true),
		}
	case token.SWITCH:
		return .parseSwitchStatement()
	case token.RETURN:
		return .parseReturnStatement()
	case token.THROW:
		return .parseThrowStatement()
	case token.TRY:
		return .parseTryStatement()
	}

	 := .parseExpression()

	if ,  := .(*ast.Identifier);  && .token == token.COLON {
		// LabelledStatement
		 := .idx
		.next() // :
		 := .Name
		for ,  := range .scope.labels {
			if  ==  {
				.error(.Idx0(), "Label '%s' already exists", )
			}
		}
		.scope.labels = append(.scope.labels, ) // Push the label
		.scope.allowLet = false
		 := .()
		.scope.labels = .scope.labels[:len(.scope.labels)-1] // Pop the label
		return &ast.LabelledStatement{
			Label:     ,
			Colon:     ,
			Statement: ,
		}
	}

	.optionalSemicolon()

	return &ast.ExpressionStatement{
		Expression: ,
	}
}

func ( *_parser) () ast.Statement {

	 := &ast.TryStatement{
		Try:  .expect(token.TRY),
		Body: .parseBlockStatement(),
	}

	if .token == token.CATCH {
		 := .idx
		.next()
		var  ast.BindingTarget
		if .token == token.LEFT_PARENTHESIS {
			.next()
			 = .parseBindingTarget()
			.expect(token.RIGHT_PARENTHESIS)
		}
		.Catch = &ast.CatchStatement{
			Catch:     ,
			Parameter: ,
			Body:      .parseBlockStatement(),
		}
	}

	if .token == token.FINALLY {
		.next()
		.Finally = .parseBlockStatement()
	}

	if .Catch == nil && .Finally == nil {
		.error(.Try, "Missing catch or finally after try")
		return &ast.BadStatement{From: .Try, To: .Body.Idx1()}
	}

	return 
}

func ( *_parser) () *ast.ParameterList {
	 := .expect(token.LEFT_PARENTHESIS)
	var  []*ast.Binding
	var  ast.Expression
	if !.scope.inFuncParams {
		.scope.inFuncParams = true
		defer func() {
			.scope.inFuncParams = false
		}()
	}
	for .token != token.RIGHT_PARENTHESIS && .token != token.EOF {
		if .token == token.ELLIPSIS {
			.next()
			 = .reinterpretAsDestructBindingTarget(.parseAssignmentExpression())
			break
		}
		.parseVariableDeclaration(&)
		if .token != token.RIGHT_PARENTHESIS {
			.expect(token.COMMA)
		}
	}
	 := .expect(token.RIGHT_PARENTHESIS)

	return &ast.ParameterList{
		Opening: ,
		List:    ,
		Rest:    ,
		Closing: ,
	}
}

func ( *_parser) ( bool) *ast.FunctionLiteral {
	if .peek() == token.FUNCTION {
		 := .idx
		.next()
		return .parseFunction(, true, )
	}
	return nil
}

func ( *_parser) (,  bool,  file.Idx) *ast.FunctionLiteral {

	 := &ast.FunctionLiteral{
		Function: ,
		Async:    ,
	}
	.expect(token.FUNCTION)

	if .token == token.MULTIPLY {
		.Generator = true
		.next()
	}

	if ! {
		if  != .scope.allowAwait {
			.scope.allowAwait = 
			defer func() {
				.scope.allowAwait = !
			}()
		}
		if .Generator != .scope.allowYield {
			.scope.allowYield = .Generator
			defer func() {
				.scope.allowYield = !.Generator
			}()
		}
	}

	.tokenToBindingId()
	var  *ast.Identifier
	if .token == token.IDENTIFIER {
		 = .parseIdentifier()
	} else if  {
		// Use expect error handling
		.expect(token.IDENTIFIER)
	}
	.Name = 

	if  {
		if  != .scope.allowAwait {
			.scope.allowAwait = 
			defer func() {
				.scope.allowAwait = !
			}()
		}
		if .Generator != .scope.allowYield {
			.scope.allowYield = .Generator
			defer func() {
				.scope.allowYield = !.Generator
			}()
		}
	}

	.ParameterList = .parseFunctionParameterList()
	.Body, .DeclarationList = .parseFunctionBlock(, , .scope.allowYield)
	.Source = .slice(.Idx0(), .Idx1())

	return 
}

func ( *_parser) (, ,  bool) ( *ast.BlockStatement,  []*ast.VariableDeclaration) {
	.openScope()
	.scope.inFunction = true
	.scope.inAsync = 
	.scope.allowAwait = 
	.scope.allowYield = 
	defer .closeScope()
	 = .parseBlockStatement()
	 = .scope.declarationList
	return
}

func ( *_parser) ( bool) (ast.ConciseBody, []*ast.VariableDeclaration) {
	if .token == token.LEFT_BRACE {
		return .parseFunctionBlock(, , false)
	}
	if  != .scope.inAsync ||  != .scope.allowAwait {
		 := .scope.inAsync
		 := .scope.allowAwait
		.scope.inAsync = 
		.scope.allowAwait = 
		 := .scope.allowYield
		.scope.allowYield = false
		defer func() {
			.scope.inAsync = 
			.scope.allowAwait = 
			.scope.allowYield = 
		}()
	}

	return &ast.ExpressionBody{
		Expression: .parseAssignmentExpression(),
	}, nil
}

func ( *_parser) ( bool) *ast.ClassLiteral {
	if !.scope.allowLet && .token == token.CLASS {
		.errorUnexpectedToken(token.CLASS)
	}

	 := &ast.ClassLiteral{
		Class: .expect(token.CLASS),
	}

	.tokenToBindingId()
	var  *ast.Identifier
	if .token == token.IDENTIFIER {
		 = .parseIdentifier()
	} else if  {
		// Use expect error handling
		.expect(token.IDENTIFIER)
	}

	.Name = 

	if .token != token.LEFT_BRACE {
		.expect(token.EXTENDS)
		.SuperClass = .parseLeftHandSideExpressionAllowCall()
	}

	.expect(token.LEFT_BRACE)

	for .token != token.RIGHT_BRACE && .token != token.EOF {
		if .token == token.SEMICOLON {
			.next()
			continue
		}
		 := .idx
		 := false
		if .token == token.STATIC {
			switch .peek() {
			case token.ASSIGN, token.SEMICOLON, token.RIGHT_BRACE, token.LEFT_PARENTHESIS:
				// treat as identifier
			default:
				.next()
				if .token == token.LEFT_BRACE {
					 := &ast.ClassStaticBlock{
						Static: ,
					}
					.Block, .DeclarationList = .parseFunctionBlock(false, true, false)
					.Source = .slice(.Block.LeftBrace, .Block.Idx1())
					.Body = append(.Body, )
					continue
				}
				 = true
			}
		}

		var  ast.PropertyKind
		var  bool
		 := .idx
		if .literal == "get" || .literal == "set" {
			if  := .peek();  != token.SEMICOLON &&  != token.LEFT_PARENTHESIS {
				if .literal == "get" {
					 = ast.PropertyKindGet
				} else {
					 = ast.PropertyKindSet
				}
				.next()
			}
		} else if .token == token.ASYNC {
			if  := .peek();  != token.SEMICOLON &&  != token.LEFT_PARENTHESIS {
				 = true
				 = ast.PropertyKindMethod
				.next()
			}
		}
		 := false
		if .token == token.MULTIPLY && ( == "" ||  == ast.PropertyKindMethod) {
			 = true
			 = ast.PropertyKindMethod
			.next()
		}

		, , ,  := .parseObjectPropertyKey()
		if  == nil {
			continue
		}
		 :=  == token.ILLEGAL
		,  := .(*ast.PrivateIdentifier)

		if  && ! &&  == "prototype" {
			.error(.Idx0(), "Classes may not have a static property named 'prototype'")
		}

		if  == "" && .token == token.LEFT_PARENTHESIS {
			 = ast.PropertyKindMethod
		}

		if  != "" {
			// method
			if  == "constructor" && ! {
				if ! {
					if  != ast.PropertyKindMethod {
						.error(.Idx0(), "Class constructor may not be an accessor")
					} else if  {
						.error(.Idx0(), "Class constructor may not be an async method")
					} else if  {
						.error(.Idx0(), "Class constructor may not be a generator")
					}
				} else if  {
					.error(.Idx0(), "Class constructor may not be a private method")
				}
			}
			 := &ast.MethodDefinition{
				Idx:      ,
				Key:      ,
				Kind:     ,
				Body:     .parseMethodDefinition(, , , ),
				Static:   ,
				Computed: ,
			}
			.Body = append(.Body, )
		} else {
			// field
			 := ! &&  == "constructor"
			if ! {
				if ,  := .(*ast.PrivateIdentifier);  {
					 = .Name == "constructor"
				}
			}
			if  {
				.error(.Idx0(), "Classes may not have a field named 'constructor'")
			}
			var  ast.Expression
			if .token == token.ASSIGN {
				.next()
				 = .parseExpression()
			}

			if !.implicitSemicolon && .token != token.SEMICOLON && .token != token.RIGHT_BRACE {
				.errorUnexpectedToken(.token)
				break
			}
			.Body = append(.Body, &ast.FieldDefinition{
				Idx:         ,
				Key:         ,
				Initializer: ,
				Static:      ,
				Computed:    ,
			})
		}
	}

	.RightBrace = .expect(token.RIGHT_BRACE)
	.Source = .slice(.Class, .RightBrace+1)

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.DEBUGGER)

	 := &ast.DebuggerStatement{
		Debugger: ,
	}

	.semicolon()

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.RETURN)

	if !.scope.inFunction {
		.error(, "Illegal return statement")
		.nextStatement()
		return &ast.BadStatement{From: , To: .idx}
	}

	 := &ast.ReturnStatement{
		Return: ,
	}

	if !.implicitSemicolon && .token != token.SEMICOLON && .token != token.RIGHT_BRACE && .token != token.EOF {
		.Argument = .parseExpression()
	}

	.semicolon()

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.THROW)

	if .implicitSemicolon {
		if .chr == -1 { // Hackish
			.error(, "Unexpected end of input")
		} else {
			.error(, "Illegal newline after throw")
		}
		.nextStatement()
		return &ast.BadStatement{From: , To: .idx}
	}

	 := &ast.ThrowStatement{
		Throw:    ,
		Argument: .parseExpression(),
	}

	.semicolon()

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.SWITCH)
	.expect(token.LEFT_PARENTHESIS)
	 := &ast.SwitchStatement{
		Switch:       ,
		Discriminant: .parseExpression(),
		Default:      -1,
	}
	.expect(token.RIGHT_PARENTHESIS)

	.expect(token.LEFT_BRACE)

	 := .scope.inSwitch
	.scope.inSwitch = true
	defer func() {
		.scope.inSwitch = 
	}()

	for  := 0; .token != token.EOF; ++ {
		if .token == token.RIGHT_BRACE {
			.RightBrace = .idx
			.next()
			break
		}

		 := .parseCaseStatement()
		if .Test == nil {
			if .Default != -1 {
				.error(.Case, "Already saw a default in switch")
			}
			.Default = 
		}
		.Body = append(.Body, )
	}

	return 
}

func ( *_parser) () ast.Statement {
	 := &ast.WithStatement{}
	.With = .expect(token.WITH)
	.expect(token.LEFT_PARENTHESIS)
	.Object = .parseExpression()
	.expect(token.RIGHT_PARENTHESIS)
	.scope.allowLet = false
	.Body = .parseStatement()

	return 
}

func ( *_parser) () *ast.CaseStatement {

	 := &ast.CaseStatement{
		Case: .idx,
	}
	if .token == token.DEFAULT {
		.next()
	} else {
		.expect(token.CASE)
		.Test = .parseExpression()
	}
	.expect(token.COLON)

	for {
		if .token == token.EOF ||
			.token == token.RIGHT_BRACE ||
			.token == token.CASE ||
			.token == token.DEFAULT {
			break
		}
		.scope.allowLet = true
		.Consequent = append(.Consequent, .parseStatement())

	}

	return 
}

func ( *_parser) () ast.Statement {
	 := .scope.inIteration
	.scope.inIteration = true
	defer func() {
		.scope.inIteration = 
	}()
	.scope.allowLet = false
	return .parseStatement()
}

func ( *_parser) ( file.Idx,  ast.ForInto) *ast.ForInStatement {

	// Already have consumed "<into> in"

	 := .parseExpression()
	.expect(token.RIGHT_PARENTHESIS)

	return &ast.ForInStatement{
		For:    ,
		Into:   ,
		Source: ,
		Body:   .parseIterationStatement(),
	}
}

func ( *_parser) ( file.Idx,  ast.ForInto) *ast.ForOfStatement {

	// Already have consumed "<into> of"

	 := .parseAssignmentExpression()
	.expect(token.RIGHT_PARENTHESIS)

	return &ast.ForOfStatement{
		For:    ,
		Into:   ,
		Source: ,
		Body:   .parseIterationStatement(),
	}
}

func ( *_parser) ( file.Idx,  ast.ForLoopInitializer) *ast.ForStatement {

	// Already have consumed "<initializer> ;"

	var ,  ast.Expression

	if .token != token.SEMICOLON {
		 = .parseExpression()
	}
	.expect(token.SEMICOLON)

	if .token != token.RIGHT_PARENTHESIS {
		 = .parseExpression()
	}
	.expect(token.RIGHT_PARENTHESIS)

	return &ast.ForStatement{
		For:         ,
		Initializer: ,
		Test:        ,
		Update:      ,
		Body:        .parseIterationStatement(),
	}
}

func ( *_parser) () ast.Statement {
	 := .expect(token.FOR)
	.expect(token.LEFT_PARENTHESIS)

	var  ast.ForLoopInitializer

	 := false
	 := false
	var  ast.ForInto
	if .token != token.SEMICOLON {

		 := .scope.allowIn
		.scope.allowIn = false
		 := .token
		if  == token.LET {
			switch .peek() {
			case token.IDENTIFIER, token.LEFT_BRACKET, token.LEFT_BRACE:
			default:
				 = token.IDENTIFIER
			}
		}
		if  == token.VAR ||  == token.LET ||  == token.CONST {
			 := .idx
			.next()
			var  []*ast.Binding
			if  == token.VAR {
				 = .parseVarDeclarationList()
			} else {
				 = .parseVariableDeclarationList()
			}
			if len() == 1 {
				if .token == token.IN {
					.next() // in
					 = true
				} else if .token == token.IDENTIFIER && .literal == "of" {
					.next()
					 = true
				}
			}
			if  ||  {
				if [0].Initializer != nil {
					.error([0].Initializer.Idx0(), "for-in loop variable declaration may not have an initializer")
				}
				if  == token.VAR {
					 = &ast.ForIntoVar{
						Binding: [0],
					}
				} else {
					 = &ast.ForDeclaration{
						Idx:     ,
						IsConst:  == token.CONST,
						Target:  [0].Target,
					}
				}
			} else {
				.ensurePatternInit()
				if  == token.VAR {
					 = &ast.ForLoopInitializerVarDeclList{
						List: ,
					}
				} else {
					 = &ast.ForLoopInitializerLexicalDecl{
						LexicalDeclaration: ast.LexicalDeclaration{
							Idx:   ,
							Token: ,
							List:  ,
						},
					}
				}
			}
		} else {
			 := .parseExpression()
			if .token == token.IN {
				.next()
				 = true
			} else if .token == token.IDENTIFIER && .literal == "of" {
				.next()
				 = true
			}
			if  ||  {
				switch e := .(type) {
				case *ast.Identifier, *ast.DotExpression, *ast.PrivateDotExpression, *ast.BracketExpression, *ast.Binding:
					// These are all acceptable
				case *ast.ObjectLiteral:
					 = .reinterpretAsObjectAssignmentPattern()
				case *ast.ArrayLiteral:
					 = .reinterpretAsArrayAssignmentPattern()
				default:
					.error(, "Invalid left-hand side in for-in or for-of")
					.nextStatement()
					return &ast.BadStatement{From: , To: .idx}
				}
				 = &ast.ForIntoExpression{
					Expression: ,
				}
			} else {
				 = &ast.ForLoopInitializerExpression{
					Expression: ,
				}
			}
		}
		.scope.allowIn = 
	}

	if  {
		return .parseForIn(, )
	}
	if  {
		return .parseForOf(, )
	}

	.expect(token.SEMICOLON)
	return .parseFor(, )
}

func ( *_parser) ( []*ast.Binding) {
	for ,  := range  {
		if ,  := .Target.(ast.Pattern);  {
			if .Initializer == nil {
				.error(.Idx1(), "Missing initializer in destructuring declaration")
				break
			}
		}
	}
}

func ( *_parser) () *ast.VariableStatement {

	 := .expect(token.VAR)

	 := .parseVarDeclarationList()
	.ensurePatternInit()
	.semicolon()

	return &ast.VariableStatement{
		Var:  ,
		List: ,
	}
}

func ( *_parser) ( token.Token) *ast.LexicalDeclaration {
	 := .expect()
	if !.scope.allowLet {
		.error(, "Lexical declaration cannot appear in a single-statement context")
	}

	 := .parseVariableDeclarationList()
	.ensurePatternInit()
	.semicolon()

	return &ast.LexicalDeclaration{
		Idx:   ,
		Token: ,
		List:  ,
	}
}

func ( *_parser) () ast.Statement {
	 := .scope.inIteration
	.scope.inIteration = true
	defer func() {
		.scope.inIteration = 
	}()

	 := &ast.DoWhileStatement{}
	.Do = .expect(token.DO)
	if .token == token.LEFT_BRACE {
		.Body = .parseBlockStatement()
	} else {
		.scope.allowLet = false
		.Body = .parseStatement()
	}

	.expect(token.WHILE)
	.expect(token.LEFT_PARENTHESIS)
	.Test = .parseExpression()
	.RightParenthesis = .expect(token.RIGHT_PARENTHESIS)
	if .token == token.SEMICOLON {
		.next()
	}

	return 
}

func ( *_parser) () ast.Statement {
	 := .expect(token.WHILE)
	.expect(token.LEFT_PARENTHESIS)
	 := &ast.WhileStatement{
		While: ,
		Test:  .parseExpression(),
	}
	.expect(token.RIGHT_PARENTHESIS)
	.Body = .parseIterationStatement()

	return 
}

func ( *_parser) () ast.Statement {
	.expect(token.IF)
	.expect(token.LEFT_PARENTHESIS)
	 := &ast.IfStatement{
		Test: .parseExpression(),
	}
	.expect(token.RIGHT_PARENTHESIS)

	if .token == token.LEFT_BRACE {
		.Consequent = .parseBlockStatement()
	} else {
		.scope.allowLet = false
		.Consequent = .parseStatement()
	}

	if .token == token.ELSE {
		.next()
		.scope.allowLet = false
		.Alternate = .parseStatement()
	}

	return 
}

func ( *_parser) () ( []ast.Statement) {
	for .token != token.EOF {
		.scope.allowLet = true
		 = append(, .parseStatement())
	}

	return 
}

func ( *_parser) () *ast.Program {
	 := &ast.Program{
		Body:            .parseSourceElements(),
		DeclarationList: .scope.declarationList,
		File:            .file,
	}
	.file.SetSourceMap(.parseSourceMap())
	return 
}

func extractSourceMapLine( string) string {
	for {
		 := strings.LastIndexByte(, '\n')
		 := [+1:]
		if  != "" &&  != "})" {
			if strings.HasPrefix(, "//# sourceMappingURL=") {
				return 
			}
			break
		}
		if  >= 0 {
			 = [:]
		} else {
			break
		}
	}
	return ""
}

func ( *_parser) () *sourcemap.Consumer {
	if .opts.disableSourceMaps {
		return nil
	}
	if  := extractSourceMapLine(.str);  != "" {
		 := strings.Index(, "=")
		 := [+1:]

		var  []byte
		var  error
		if strings.HasPrefix(, "data:application/json") {
			 := strings.Index(, ",")
			 := [+1:]
			,  = base64.StdEncoding.DecodeString()
		} else {
			if  := file.ResolveSourcemapURL(.file.Name(), );  != nil {
				if .opts.sourceMapLoader != nil {
					,  = .opts.sourceMapLoader(.String())
				} else {
					if .Scheme == "" || .Scheme == "file" {
						,  = os.ReadFile(.Path)
					} else {
						 = fmt.Errorf("unsupported source map URL scheme: %s", .Scheme)
					}
				}
			}
		}

		if  != nil {
			.error(file.Idx(0), "Could not load source map: %v", )
			return nil
		}
		if  == nil {
			return nil
		}

		if ,  := sourcemap.Parse(.file.Name(), );  == nil {
			return 
		} else {
			.error(file.Idx(0), "Could not parse source map: %v", )
		}
	}
	return nil
}

func ( *_parser) () ast.Statement {
	 := .expect(token.BREAK)
	 := .implicitSemicolon
	if .token == token.SEMICOLON {
		 = true
		.next()
	}

	if  || .token == token.RIGHT_BRACE {
		.implicitSemicolon = false
		if !.scope.inIteration && !.scope.inSwitch {
			goto 
		}
		return &ast.BranchStatement{
			Idx:   ,
			Token: token.BREAK,
		}
	}

	.tokenToBindingId()
	if .token == token.IDENTIFIER {
		 := .parseIdentifier()
		if !.scope.hasLabel(.Name) {
			.error(, "Undefined label '%s'", .Name)
			return &ast.BadStatement{From: , To: .Idx1()}
		}
		.semicolon()
		return &ast.BranchStatement{
			Idx:   ,
			Token: token.BREAK,
			Label: ,
		}
	}

	.expect(token.IDENTIFIER)

:
	.error(, "Illegal break statement")
	.nextStatement()
	return &ast.BadStatement{From: , To: .idx}
}

func ( *_parser) () ast.Statement {
	 := .expect(token.CONTINUE)
	 := .implicitSemicolon
	if .token == token.SEMICOLON {
		 = true
		.next()
	}

	if  || .token == token.RIGHT_BRACE {
		.implicitSemicolon = false
		if !.scope.inIteration {
			goto 
		}
		return &ast.BranchStatement{
			Idx:   ,
			Token: token.CONTINUE,
		}
	}

	.tokenToBindingId()
	if .token == token.IDENTIFIER {
		 := .parseIdentifier()
		if !.scope.hasLabel(.Name) {
			.error(, "Undefined label '%s'", .Name)
			return &ast.BadStatement{From: , To: .Idx1()}
		}
		if !.scope.inIteration {
			goto 
		}
		.semicolon()
		return &ast.BranchStatement{
			Idx:   ,
			Token: token.CONTINUE,
			Label: ,
		}
	}

	.expect(token.IDENTIFIER)

:
	.error(, "Illegal continue statement")
	.nextStatement()
	return &ast.BadStatement{From: , To: .idx}
}

// Find the next statement after an error (recover)
func ( *_parser) () {
	for {
		switch .token {
		case token.BREAK, token.CONTINUE,
			token.FOR, token.IF, token.RETURN, token.SWITCH,
			token.VAR, token.DO, token.TRY, token.WITH,
			token.WHILE, token.THROW, token.CATCH, token.FINALLY:
			// Return only if parser made some progress since last
			// sync or if it has not reached 10 next calls without
			// progress. Otherwise consume at least one token to
			// avoid an endless parser loop
			if .idx == .recover.idx && .recover.count < 10 {
				.recover.count++
				return
			}
			if .idx > .recover.idx {
				.recover.idx = .idx
				.recover.count = 0
				return
			}
			// Reaching here indicates a parser bug, likely an
			// incorrect token list in this function, but it only
			// leads to skipping of possibly correct code if a
			// previous error is present, and thus is preferred
			// over a non-terminating parse.
		case token.EOF:
			return
		}
		.next()
	}
}