// File: /workspace/github_cpp_makefile_star2_O3/exrd[P]neteruhsp/neteruhsp/neteruhsp.cc
// Function: neteruhsp::parse_control_safe(neteruhsp::parse_context_t&)
ast_node_t* parse_control_safe( parse_context_t& c )
{
	const auto ident = read_token( c );
	if ( ident->tag_ != TOKEN_IDENTIFIER )
	{
		unread_token( c );
		return nullptr;
	}

	const auto keyword = query_keyword( ident->content_ );
	if ( keyword < 0 )
	{
		unread_token( c );
		return nullptr;
	}

	switch( keyword )
	{
		case KEYWORD_END:
			return create_ast_node( NODE_END );
		case KEYWORD_RETURN:
		{
			const auto next = read_token( c );
			unread_token( c );

			ast_node_t* expr =nullptr;
			if ( !is_eos_like_token( next->tag_ ) )
			{
				expr = parse_expression( c );
			}
			return create_ast_node( NODE_RETURN, expr );
		}
		case KEYWORD_GOTO:
		case KEYWORD_GOSUB:
		{
			const auto label = parse_label_safe( c );
			if ( label == nullptr )
			{
				raise_error( "gotoまたはgosubにはラベルの指定が必須です@@ %d行目", ident->appear_line_ );
			}
			return create_ast_node( keyword==KEYWORD_GOTO ? NODE_GOTO : NODE_GOSUB, label );
		}
		case KEYWORD_REPEAT:
		{
			const auto next = read_token( c );
			unread_token( c );

			ast_node_t* expr =nullptr;
			if ( !is_eos_like_token( next->tag_ ) )
			{
				expr = parse_expression( c );
			}
			return create_ast_node( NODE_REPEAT, expr );
		}
		case KEYWORD_LOOP:
			return create_ast_node( NODE_LOOP );
		case KEYWORD_CONTINUE:
			return create_ast_node( NODE_CONTINUE );
		case KEYWORD_BREAK:
			return create_ast_node( NODE_BREAK );
		case KEYWORD_IF:
		{
			const auto expr = parse_expression( c );

			const auto next = read_token( c );

			const auto is_else_token = []( const token_t* n )
			{
				if ( n->tag_==TOKEN_IDENTIFIER && query_keyword(n->content_)==KEYWORD_ELSE )
				{ return true; }
				return false;
			};

			bool repair_token =false;

			ast_node_t* true_statements = create_ast_node( NODE_BLOCK_STATEMENTS );
			ast_node_t* false_statements = nullptr;
			if ( next->tag_ == TOKEN_LBRACE )
			{
				for( ; ; )
				{
					const auto pp = prev_token( c );
					if ( pp->tag_ == TOKEN_RBRACE )
					{
						// RBRACEは食われてた
						break;
					}
					const auto statement = parse_statement( c );
					if ( statement == nullptr )
					{
						raise_error( "if文の解析中、解析できないステートメントに到達しました@@ %d行目、%d行目から", pp->appear_line_, ident->appear_line_ );
					}
					true_statements = create_ast_node( NODE_BLOCK_STATEMENTS, true_statements, statement );
				}
			}
			else
			{
				unread_token( c );
				{
					const auto nn = read_token( c );
					if ( nn->tag_ != TOKEN_EOS )
					{
						raise_error( "if文の解析中：ifの条件式の後は { か : しか置けません@@ %d行目", nn->appear_line_ );
					}
				}

				for( ; ; )
				{
					const auto pp = prev_token( c );
					if ( pp->tag_==TOKEN_EOL || pp->tag_==TOKEN_EOF )
					{
						// EOLまたはEOFは食われてた
						repair_token =true;
						break;
					}
					const auto nn = read_token( c );
					unread_token( c );
					if ( is_else_token( nn ) )
					{ break; }

					const auto statement = parse_statement( c );
					if ( statement == nullptr )
					{
						raise_error( "if文の解析中、解析できないステートメントに到達しました@@ %d行目、%d行目から", nn->appear_line_, ident->appear_line_ );
					}
					true_statements = create_ast_node( NODE_BLOCK_STATEMENTS, true_statements, statement );
				}
			}

			// elseはあるか？
			const auto nn = read_token( c );
			if ( is_else_token( nn ) )
			{
				repair_token = false;
				false_statements = create_ast_node( NODE_BLOCK_STATEMENTS );

				const auto nextf = read_token( c );
				if ( nextf->tag_ == TOKEN_LBRACE )
				{
					for( ; ; )
					{
						const auto ppf = prev_token( c );
						if ( ppf->tag_ == TOKEN_RBRACE )
						{
							// RBRACEは食われてた
							break;
						}
						const auto statement = parse_statement( c );
						if ( statement == nullptr )
						{
							raise_error( "ifのelse文の解析中、解析できないステートメントに到達しました@@ %d行目、%d行目から", nn->appear_line_, ident->appear_line_ );
						}
						false_statements = create_ast_node( NODE_BLOCK_STATEMENTS, false_statements, statement );
					}
				}
				else
				{
					unread_token( c );
					{
						const auto nnf = read_token( c );
						if ( nnf->tag_ != TOKEN_EOS )
						{
							raise_error( "ifのelse文の解析中：elseの後は { か : しか置けません@@ %d行目", nnf->appear_line_ );
						}
					}

					for( ; ; )
					{
						const auto pp = prev_token( c );
						if ( pp->tag_==TOKEN_EOL || pp->tag_==TOKEN_EOF )
						{
							// EOLまたはEOFは食われてた
							repair_token = true;
							break;
						}
						const auto nnf = read_token( c );
						unread_token( c );
						if ( is_else_token( nnf ) )
						{ break; }

						const auto statement = parse_statement( c );
						if ( statement == nullptr )
						{
							raise_error( "ifのelse文の解析中、解析できないステートメントに到達しました@@ %d行目、%d行目から", nnf->appear_line_, ident->appear_line_ );
						}
						false_statements = create_ast_node( NODE_BLOCK_STATEMENTS, false_statements, statement );
					}
				}
			}
			else
			{
				unread_token( c );
			}

			// EOLを食いすぎてしまった場合用
			if ( repair_token )
			{
				unread_token( c );
			}

			ast_node_t* dispatcher = create_ast_node( NODE_IF_DISPATCHER, true_statements, false_statements );
			return create_ast_node( NODE_IF, expr, dispatcher );
		}
		case KEYWORD_ELSE:
			raise_error( "ハンドルされないelseを検出しました@@ %d行目", ident->appear_line_ );
			break;
	}

	unread_token( c );
	return nullptr;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
callq 0x3619
cmpl $0x23, (%rax)
jne 0x51eb
movq %rax, %r14
movq 0x8(%rax), %r15
leaq 0x7998(%rip), %rsi      # 0xcae6
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
testb %al, %al
jne 0x51eb
movl $0x18, %r12d
leaq 0x10710(%rip), %r13     # 0x15880
movq %r12, %rbp
addq $0x10, %r12
cmpq $0xd8, %r12
je 0x5196
movq (%rbp,%r13), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
testb %al, %al
je 0x5170
movl -0x8(%rbp,%r13), %r15d
testl %r15d, %r15d
js 0x51eb
leal -0x2(%r15), %eax
cmpl $0x9, %eax
ja 0x51eb
leaq 0x7200(%rip), %rcx      # 0xc3b0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x50be
testq %rax, %rax
je 0x57ac
movq %rax, %rbx
xorl %ebp, %ebp
cmpl $0x4, %r15d
setne %bpl
addl $0x23, %ebp
movl $0x28, %edi
callq 0x21d0
movl %ebp, (%rax)
jmp 0x53a8
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
callq 0x3619
movq %rax, %r14
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
movl (%r14), %eax
cmpl $0x6, %eax
jae 0x5370
movl $0x27, %ecx
btl %eax, %ecx
jae 0x5370
xorl %ebx, %ebx
jmp 0x537b
movl $0x28, %edi
callq 0x21d0
movl $0x21, (%rax)
jmp 0x52c1
movq %rbx, %rdi
callq 0x3619
movq %rax, %r14
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
movl (%r14), %eax
cmpl $0x6, %eax
jae 0x538d
movl $0x27, %ecx
btl %eax, %ecx
jae 0x538d
xorl %ebx, %ebx
jmp 0x5398
movl $0x28, %edi
callq 0x21d0
movl $0x28, (%rax)
jmp 0x52c1
movl $0x28, %edi
callq 0x21d0
movl $0x26, (%rax)
jmp 0x52c1
movl $0x28, %edi
callq 0x21d0
movl $0x27, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
jmp 0x51fa
movq %rbx, %rdi
callq 0x5aa6
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x3619
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movq %rax, %rbp
movl $0x2, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
cmpl $0x4, (%r15)
jne 0x53c2
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x5321
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %r12
cmpl $0x5, (%r12)
je 0x54d6
movq %rbx, %rdi
callq 0x4fbd
testq %rax, %rax
je 0x5790
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %rbp, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movq %rax, %rbp
jmp 0x5311
movq %rbx, %rdi
callq 0x5aa6
movq %rax, %rbx
movl $0x28, %edi
callq 0x21d0
movl $0x25, (%rax)
jmp 0x53a8
movq %rbx, %rdi
callq 0x5aa6
movq %rax, %rbx
movl $0x28, %edi
callq 0x21d0
movl $0x22, (%rax)
xorl %ecx, %ecx
movq %rcx, 0x8(%rax)
movq %rbx, 0x10(%rax)
movq %rcx, 0x18(%rax)
movl $0x0, 0x20(%rax)
jmp 0x51fa
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
movq %rbx, %rdi
callq 0x3619
cmpl $0x2, (%rax)
jne 0x57e0
movl $0xc0, %eax
addq %r13, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x53fd
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x2, (%rax)
setb %r12b
jb 0x54e0
movq %rbp, (%rsp)
movq %rbx, %rdi
callq 0x3619
movq %rax, %rbp
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
cmpl $0x23, (%rbp)
jne 0x548f
movq 0x8(%rbp), %r15
movq %r15, %rdi
leaq 0x76a8(%rip), %rsi      # 0xcae6
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
testb %al, %al
jne 0x548f
movl %r12d, 0x10(%rsp)
xorl %ecx, %ecx
leaq 0x10(%rcx), %r12
movl $0xc0, %eax
cmpq %rax, %r12
je 0x547f
movq 0x18(%rcx,%r13), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
movq %r12, %rcx
testb %al, %al
je 0x5453
addq %r13, %r12
jmp 0x5484
movq 0x8(%rsp), %r12
cmpl $0xb, (%r12)
je 0x5670
movq %rbx, %rdi
callq 0x4fbd
testq %rax, %rax
je 0x5797
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movq %rax, %rbp
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq (%rsp), %rcx
movq %rcx, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
jmp 0x53ed
movl $0x0, 0x10(%rsp)
jmp 0x54e6
movb $0x1, %al
movl %eax, 0x10(%rsp)
movq %rbx, %rdi
callq 0x3619
cmpl $0x23, (%rax)
jne 0x55fc
movq %rax, %r12
movq 0x8(%rax), %r15
leaq 0x75e1(%rip), %rsi      # 0xcae6
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
testb %al, %al
jne 0x55fc
movq %r12, 0x18(%rsp)
movq %rbp, (%rsp)
xorl %ecx, %ecx
movl $0xc0, %r12d
leaq (%r12,%r13), %rax
movq %rax, 0x8(%rsp)
leaq 0x10(%rcx), %rbp
cmpq %r12, %rbp
je 0x5562
movq 0x18(%rcx,%r13), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
movq %rbp, %rcx
testb %al, %al
je 0x5534
addq %r13, %rbp
movq %rbp, %rax
movq (%rsp), %rbp
jmp 0x556b
movq (%rsp), %rbp
movq 0x8(%rsp), %rax
cmpl $0xb, (%rax)
jne 0x55fc
movl $0x28, %edi
callq 0x21d0
movq %rax, %r12
movl $0x2, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rbx, %rdi
callq 0x3619
cmpl $0x4, (%rax)
jne 0x5679
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x55b3
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x5, (%rax)
je 0x5620
movq %rbx, %rdi
callq 0x4fbd
testq %rax, %rax
je 0x57b9
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r12, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movq %rax, %r12
jmp 0x55a3
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
xorl %r12d, %r12d
cmpb $0x0, 0x10(%rsp)
je 0x5620
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
movl $0x28, %edi
callq 0x21d0
movq %rax, %rbx
movl $0x2a, (%rax)
xorl %r14d, %r14d
movq %r14, 0x8(%rax)
movq %rbp, 0x10(%rax)
movq %r12, 0x18(%rax)
movl %r14d, 0x20(%rax)
movl $0x28, %edi
callq 0x21d0
movl $0x29, (%rax)
movq %r14, 0x8(%rax)
movq 0x20(%rsp), %rcx
movq %rcx, 0x10(%rax)
movq %rbx, 0x18(%rax)
movl %r14d, 0x20(%rax)
jmp 0x51fa
movq (%rsp), %rbp
jmp 0x54e6
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
movq %rbx, %rdi
callq 0x3619
cmpl $0x2, (%rax)
jne 0x57f1
movl $0xc0, %eax
addq %r13, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x56b4
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x2, (%rax)
jb 0x577e
movq %rbx, %rdi
callq 0x3619
movq %rax, %rbp
movl $0x1, %esi
movq %rbx, %rdi
callq 0x3669
cmpl $0x23, (%rbp)
jne 0x573f
movq 0x8(%rbp), %r15
movq %r15, %rdi
leaq 0x73f9(%rip), %rsi      # 0xcae6
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
testb %al, %al
jne 0x573f
movq %r12, 0x10(%rsp)
xorl %ecx, %ecx
leaq 0x10(%rcx), %r12
movl $0xc0, %eax
cmpq %rax, %r12
je 0x572e
movq 0x18(%rcx,%r13), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d26
movq %r12, %rcx
testb %al, %al
je 0x5702
addq %r13, %r12
jmp 0x5733
movq 0x8(%rsp), %r12
cmpl $0xb, (%r12)
movq 0x10(%rsp), %r12
je 0x5787
movq %rbx, %rdi
callq 0x4fbd
testq %rax, %rax
je 0x57c3
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r12, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movq %rax, %r12
jmp 0x56a4
movq (%rsp), %rbp
jmp 0x5613
movq (%rsp), %rbp
jmp 0x5620
movl 0x18(%r12), %esi
jmp 0x579a
movl 0x18(%rbp), %esi
movl 0x18(%r14), %edx
leaq 0x8631(%rip), %rdi      # 0xddd6
xorl %eax, %eax
callq 0x344d
movl 0x18(%r14), %esi
leaq 0x85da(%rip), %rdi      # 0xdd91
jmp 0x57ea
movq 0x18(%rsp), %rax
movl 0x18(%rax), %esi
jmp 0x57c6
movl 0x18(%rbp), %esi
movl 0x18(%r14), %edx
leaq 0x86c7(%rip), %rdi      # 0xde98
jmp 0x57a5
movl 0x18(%r14), %esi
leaq 0x8780(%rip), %rdi      # 0xdf5e
jmp 0x57ea
movl 0x18(%rax), %esi
leaq 0x8659(%rip), %rdi      # 0xde43
xorl %eax, %eax
callq 0x344d
movl 0x18(%rax), %esi
leaq 0x8711(%rip), %rdi      # 0xdf0c
jmp 0x57ea