// File: /workspace/github_cpp_makefile_star2_O1/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 0x367d
cmpl $0x23, (%rax)
jne 0x55af
movq %rax, %r14
movq 0x8(%rax), %r15
leaq 0x8614(%rip), %rsi      # 0xdb26
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
xorl %r12d, %r12d
testb %al, %al
jne 0x555e
movl $0x18, %r13d
leaq 0x1134d(%rip), %r12     # 0x16880
movq %r13, %rbp
addq $0x10, %r13
cmpq $0xd8, %r13
je 0x5559
movq (%rbp,%r12), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
testb %al, %al
je 0x5533
movl -0x8(%rbp,%r12), %r12d
testl %r12d, %r12d
js 0x55af
leal -0x2(%r12), %eax
cmpl $0x9, %eax
ja 0x55af
leaq 0x7e7c(%rip), %rcx      # 0xd3f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x5482
testq %rax, %rax
je 0x5bbe
movq %rax, %rbx
xorl %ebp, %ebp
cmpl $0x4, %r12d
setne %bpl
addl $0x23, %ebp
movl $0x28, %edi
callq 0x21d0
movl %ebp, (%rax)
jmp 0x577b
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
callq 0x367d
movq %rax, %r14
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
movl (%r14), %eax
cmpl $0x6, %eax
jae 0x5743
movl $0x27, %ecx
btl %eax, %ecx
jae 0x5743
xorl %ebx, %ebx
jmp 0x574e
movl $0x28, %edi
callq 0x21d0
movl $0x21, (%rax)
jmp 0x5685
movq %rbx, %rdi
callq 0x367d
movq %rax, %r14
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
movl (%r14), %eax
cmpl $0x6, %eax
jae 0x5760
movl $0x27, %ecx
btl %eax, %ecx
jae 0x5760
xorl %ebx, %ebx
jmp 0x576b
movl $0x28, %edi
callq 0x21d0
movl $0x28, (%rax)
jmp 0x5685
movl $0x28, %edi
callq 0x21d0
movl $0x26, (%rax)
jmp 0x5685
movl $0x28, %edi
callq 0x21d0
movl $0x27, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
jmp 0x55be
movq %rbx, %rdi
callq 0x5ea4
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x367d
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movq %rax, %r13
movl $0x2, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
cmpl $0x4, (%r15)
jne 0x5795
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x56e5
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %r12
movl (%r12), %ebp
cmpl $0x5, %ebp
je 0x5730
movq %rbx, %rdi
callq 0x5376
testq %rax, %rax
je 0x5ba2
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r13, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movq %rax, %r13
cmpl $0x5, %ebp
jne 0x56d5
movq $0x0, 0x10(%rsp)
jmp 0x58cb
movq %rbx, %rdi
callq 0x5ea4
movq %rax, %rbx
movl $0x28, %edi
callq 0x21d0
movl $0x25, (%rax)
jmp 0x577b
movq %rbx, %rdi
callq 0x5ea4
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 0x55be
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
movq %rbx, %rdi
callq 0x367d
cmpl $0x2, (%rax)
jne 0x5be8
movq $0x0, 0x10(%rsp)
leaq 0x110bd(%rip), %rax     # 0x16880
movl $0xc0, %r12d
addq %r12, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x57e1
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x2, (%rax)
jae 0x57f8
movb $0x1, %al
movq %rax, 0x10(%rsp)
xorl %ecx, %ecx
jmp 0x58c3
movq %rbx, %rdi
callq 0x367d
movq %rax, %rbp
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
cmpl $0x23, (%rbp)
jne 0x5883
movq 0x8(%rbp), %r15
movq %r15, %rdi
leaq 0x8302(%rip), %rsi      # 0xdb26
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
testb %al, %al
jne 0x5883
movq %r13, 0x18(%rsp)
xorl %ecx, %ecx
leaq 0x10(%rcx), %r13
cmpq %r12, %r13
je 0x586e
leaq 0x11037(%rip), %rax     # 0x16880
movq 0x18(%rcx,%rax), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
movq %r13, %rcx
testb %al, %al
je 0x5839
leaq 0x11017(%rip), %rax     # 0x16880
addq %rax, %r13
jmp 0x5873
movq 0x8(%rsp), %r13
cmpl $0xb, (%r13)
movq 0x18(%rsp), %r13
je 0x57f1
movq %rbx, %rdi
callq 0x5376
testq %rax, %rax
je 0x5ba9
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r13, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movb $0x1, %cl
movq %rax, %r13
testb %cl, %cl
jne 0x57d1
movq %r13, 0x18(%rsp)
movq %rbx, %rdi
callq 0x367d
cmpl $0x23, (%rax)
jne 0x59f4
movq %rax, %rbp
movq 0x8(%rax), %r13
leaq 0x8237(%rip), %rsi      # 0xdb26
movq %r13, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
testb %al, %al
jne 0x59f4
xorl %ecx, %ecx
leaq 0x10f73(%rip), %rax     # 0x16880
movl $0xc0, %r12d
addq %r12, %rax
movq %rax, 0x8(%rsp)
leaq 0x10(%rcx), %r15
cmpq %r12, %r15
je 0x5950
leaq 0x10f55(%rip), %rax     # 0x16880
movq 0x18(%rcx,%rax), %rsi
movq %r13, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
movq %r15, %rcx
testb %al, %al
je 0x591b
leaq 0x10f35(%rip), %rax     # 0x16880
addq %rax, %r15
jmp 0x5955
movq 0x8(%rsp), %r15
cmpl $0xb, (%r15)
jne 0x59f4
movl $0x28, %edi
callq 0x21d0
movq %rax, %r13
movl $0x2, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rbx, %rdi
callq 0x367d
cmpl $0x4, (%rax)
jne 0x5a71
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x599e
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movl (%rax), %r12d
cmpl $0x5, %r12d
je 0x59e9
movq %rbx, %rdi
callq 0x5376
testq %rax, %rax
je 0x5bcb
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r13, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movq %rax, %r13
cmpl $0x5, %r12d
jne 0x598e
xorl %r12d, %r12d
jmp 0x5a09
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
xorl %r13d, %r13d
movq 0x10(%rsp), %r12
testb $0x1, %r12b
je 0x5a1c
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
movl $0x28, %edi
callq 0x21d0
movq %rax, %rbx
movl $0x2a, (%rax)
xorl %r14d, %r14d
movq %r14, 0x8(%rax)
movq 0x18(%rsp), %rax
movq %rax, 0x10(%rbx)
movq %r13, 0x18(%rbx)
movl %r14d, 0x20(%rbx)
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 0x55be
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
movq %rbx, %rdi
callq 0x367d
cmpl $0x2, (%rax)
jne 0x5bf9
xorl %r12d, %r12d
movl $0xc0, %ecx
leaq 0x10de2(%rip), %rax     # 0x16880
addq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rbx), %rax
testq %rax, %rax
jne 0x5ab6
movq (%rbx), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
cmpl $0x2, (%rax)
jae 0x5ac9
movb $0x1, %r12b
xorl %ecx, %ecx
jmp 0x5b95
movq %rbx, %rdi
callq 0x367d
movq %rax, %rbp
movl $0x1, %esi
movq %rbx, %rdi
callq 0x36fe
cmpl $0x23, (%rbp)
jne 0x5b59
movq 0x8(%rbp), %r15
movq %r15, %rdi
leaq 0x8031(%rip), %rsi      # 0xdb26
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
testb %al, %al
jne 0x5b59
movq %r12, 0x10(%rsp)
xorl %ecx, %ecx
leaq 0x10(%rcx), %r12
movl $0xc0, %eax
cmpq %rax, %r12
je 0x5b44
leaq 0x10d61(%rip), %rax     # 0x16880
movq 0x18(%rcx,%rax), %rsi
movq %r15, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2da2
movq %r12, %rcx
testb %al, %al
je 0x5b0a
leaq 0x10d41(%rip), %rax     # 0x16880
addq %rax, %r12
jmp 0x5b49
movq 0x8(%rsp), %r12
cmpl $0xb, (%r12)
movq 0x10(%rsp), %r12
je 0x5ac2
movq %rbx, %rdi
callq 0x5376
testq %rax, %rax
je 0x5bcb
movq %rax, %r15
movl $0x28, %edi
callq 0x21d0
movl $0x2, (%rax)
movq $0x0, 0x8(%rax)
movq %r13, 0x10(%rax)
movq %r15, 0x18(%rax)
movl $0x0, 0x20(%rax)
movb $0x1, %cl
movq %rax, %r13
testb %cl, %cl
jne 0x5aa6
jmp 0x5a09
movl 0x18(%r12), %esi
jmp 0x5bac
movl 0x18(%rbp), %esi
movl 0x18(%r14), %edx
leaq 0x9325(%rip), %rdi      # 0xeedc
xorl %eax, %eax
callq 0x34a8
movl 0x18(%r14), %esi
leaq 0x92ce(%rip), %rdi      # 0xee97
jmp 0x5bf2
movl 0x18(%rbp), %esi
movl 0x18(%r14), %edx
leaq 0x93c5(%rip), %rdi      # 0xef9e
jmp 0x5bb7
movl 0x18(%r14), %esi
leaq 0x947e(%rip), %rdi      # 0xf064
jmp 0x5bf2
movl 0x18(%rax), %esi
leaq 0x9357(%rip), %rdi      # 0xef49
xorl %eax, %eax
callq 0x34a8
movl 0x18(%rax), %esi
leaq 0x940f(%rip), %rdi      # 0xf012
jmp 0x5bf2