// File: /workspace/github_cpp_makefile_star2_O1/exrd[P]neteruhsp/neteruhsp/neteruhsp.cc
// Function: neteruhsp::load_script(neteruhsp::execute_environment_t*, char const*, neteruhsp::load_arg_t const*)
void load_script( execute_environment_t* e, const char* script, const load_arg_t* arg )
{
	// プリプロセス
	char* preprocessed = prepro_do( script );

	if ( arg && arg->dump_preprocessed_ )
	{
		printf( "====PREPROCESSED SCRIPT FILE(%d bytes)\n----begin----\n%s\n----end----\n", static_cast<int>( strlen( preprocessed ) ), preprocessed );
	}

	// パース
	tokenize_context_t tokenizer;
	initialize_tokenize_context( &tokenizer, preprocessed );

	auto parser = create_parse_context();
	initialize_parse_context( parser, tokenizer );

	auto ast = parse_script( *parser );

	if ( arg && arg->dump_ast_ )
	{
		dump_ast( ast );
	}

	uninitialize_tokenize_context( &tokenizer );

	destroy_string( preprocessed );
	preprocessed = nullptr;

	// 特定の部分木マッチング
	// 先に必要な変数のインスタンスを作っておき、ラベルテーブルも生成しておく
	{
		struct _
		{
			static void walk( execute_environment_t* e, ast_node_t* node )
			{
				if ( node->tag_==NODE_VARIABLE || node->tag_==NODE_IDENTIFIER_EXPR/*変数配列の可能性あり*/ )
				{
					auto var_name = node->token_->content_;
					if ( search_variable( e->variable_table_, var_name ) == nullptr )
					{
						// 適当な変数として初期化しておく
						value_t v;
						v.type_ = VALUE_INT;
						v.ivalue_ = 0;
						variable_set( e->variable_table_, v, var_name, 0 );
					}
				}
				else if ( node->tag_ == NODE_LABEL )
				{
					auto label_node = create_list_node();
					label_node_t* label =reinterpret_cast<label_node_t*>( xmalloc( sizeof(label_node_t) ) );
					label->name_ = create_string( node->token_->content_ );
					label_node->value_ = label;
					list_append( *e->label_table_, label_node );
				}
				if ( node->left_ != nullptr )
				{ walk( e, node->left_ ); }
				if ( node->right_ != nullptr )
				{ walk( e, node->right_ ); }
			}
		};

		list_node_t* st =ast->head_;
		while( st != nullptr )
		{
			ast_node_t* node = reinterpret_cast<ast_node_t*>( st->value_ );
			_::walk( e, node );
			st = st->next_;
		}
	}

	// コード生成
	generate_and_append_code( e, ast );

	// パーサーとASTを保存しておく
	{
		auto parser_node = create_list_node();
		parser_node->value_ = parser;
		list_append( *e->parser_list_, parser_node );
	}
	{
		auto ast_node = create_list_node();
		ast_node->value_ = ast;
		list_append( *e->ast_list_, ast_node );
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r13
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x3ae2
movq %rax, %r14
testq %r13, %r13
je 0x8221
cmpb $0x1, (%r13)
jne 0x8221
movq %r14, %rdi
callq 0x20b0
leaq 0x865f(%rip), %rdi      # 0x10874
movl %eax, %esi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2050
movq %rsp, %r12
movq %r14, (%r12)
xorl %ebp, %ebp
movq %rbp, 0x8(%r12)
movq %r14, 0x10(%r12)
movl $0x18, %edi
callq 0x21d0
movq %rax, %r15
movl $0x10, %edi
callq 0x21d0
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq %rax, (%r15)
movq %rbp, 0x8(%r15)
movq %r12, 0x10(%r15)
movq %r15, %rdi
callq 0x52f5
movq %rax, %r12
testq %r13, %r13
je 0x827d
cmpb $0x1, 0x1(%r13)
jne 0x827d
movq %r12, %rdi
xorl %esi, %esi
callq 0x8309
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
movq $0x0, 0x10(%rsp)
movq %r14, %rdi
callq 0x21a0
movq (%r12), %r14
testq %r14, %r14
je 0x82b0
movq 0x10(%r14), %rsi
movq %rbx, %rdi
callq 0x835a
movq 0x8(%r14), %r14
jmp 0x8299
movq %rbx, %rdi
movq %r12, %rsi
callq 0x846c
movl $0x18, %edi
callq 0x21d0
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq %r15, 0x10(%rax)
movq (%rbx), %rdi
movq %rax, %rsi
callq 0x2c58
movl $0x18, %edi
callq 0x21d0
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq %r12, 0x10(%rax)
movq 0x8(%rbx), %rdi
movq %rax, %rsi
callq 0x2c58
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq