// File: /workspace/github_cpp_makefile_star2_O2/exrd[P]neteruhsp/neteruhsp/main.cc
// Function: main
int main( int argc, const char* argv[] )
{
	using namespace neteruhsp;

	// オプション
	bool has_error = false;
	const char* filename = nullptr;
	bool show_script = false;
	bool show_preprocessed_script = false;
	bool show_ast = false;
	bool show_execute_code = false;
	bool show_help = false;

	// オプション解析
	for( int i=1/* 0飛ばし */; i<argc; ++i )
	{
		const auto arg = argv[i];
		if ( arg[0] == '-' )
		{
			switch( arg[1] )
			{
				case 'f':
					if ( i+1 < argc )
					{
						++i;
						filename = argv[i];
					}
					else
					{
						fprintf( stderr, "ERROR : cannot read script file path\n" );
						has_error = true;
					}
					break;
				case 's':
					show_script = true;
					break;
				case 'p':
					show_preprocessed_script = true;
					break;
				case 'a':
					show_ast = true;
					break;
				case 'e':
					show_execute_code = true;
					break;
				case 'h':
					show_help = true;
					break;
				default:
					fprintf( stderr, "ERROR : unknown argument :%s\n", arg );
					has_error = true;
					break;
			}
		}
		else
		{
			fprintf( stderr, "ERROR : cannot parse argument :%s\n", arg );
			has_error = true;
			break;
		}
	}

	if ( filename == nullptr )
	{
		fprintf( stderr, "ERROR : have to specify script file\n" );
		has_error = true;
	}

	if ( show_help || has_error )
	{
		printf(
			"neteruhsp : commandline tool options\n"
			"  <bin> [<options>...] -f <SCRIPT_FILE>\n"
			"    -f : specify file path to execute\n"
			"\n"
			"  options are followings\n"
			"    -s : show loaded script file contents\n"
			"    -p : show preprocessed script contents\n"
			"    -a : show abstract-syntax-tree constructed from loaded script\n"
			"    -e : show instruction code for execution\n"
			"    -h : show (this) help\n"
		);
		fflush( stdout );
		fflush( stderr );
		return ( has_error ? -1 : 0 );
	}

	// システムここから
	initialize_system();

	// ファイル読み込み
	size_t script_size = 0;
	char* script = nullptr;
	{
		FILE* file = fopen( filename, "r" );
		if ( file == nullptr )
		{
			printf( "ERROR : cannot read such file %s\n", filename );
			return -1;
		}

		fseek( file, 0, SEEK_END );
		const size_t initial_size = ftell( file );

		size_t buffer_size = initial_size +4;// 初期バッファ
		script = reinterpret_cast<char*>( xmalloc( buffer_size +1 ) );

		fseek( file, 0, SEEK_SET );

		for( ; ; )
		{
			const auto c = fgetc(file);
			if ( c == EOF )
			{ break; }

			const auto ch = static_cast<char>( c );
			if ( buffer_size <= script_size )
			{
				buffer_size *= 2;
				script = reinterpret_cast<char*>( xrealloc( script, buffer_size ) );
			}
			script[script_size++] = ch;
		}
		script[script_size] = '\0';

		fclose( file );
	}
	assert( script != nullptr );

	if ( show_script )
	{
		printf( "====LOADED SCRIPT FILE(%d bytes)\n----begin----\n%s\n----end----\n", static_cast<int>( script_size ), script );
	}

	// 実行
	{
		{
			auto env =create_execute_environment();

			load_arg_t la;
			la.dump_preprocessed_ = show_preprocessed_script;
			la.dump_ast_ = show_ast;
			load_script( env, script, &la );

			if ( show_execute_code )
			{
				printf( "====Instruction Code for execution\n" );
				dump_code( env->execute_code_ );
			}

			execute( env );
			destroy_execute_environment( env );
		}

		printf(
			"====\n"
			">>Execution finished, press ENTER key to exit\n"
		);
		fflush( stdout );
		getchar();
	}

	xfree( script );
	uninitialize_system();

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r14
movl %edi, %ebp
pushq $0x1
popq %r13
xorl %r11d, %r11d
leaq 0x8c5d(%rip), %rsi      # 0xb04a
leaq 0x8c10(%rip), %r12      # 0xb004
xorl %ebx, %ebx
xorl %r15d, %r15d
xorl %edi, %edi
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %r10d, %r10d
cmpl %ebp, %r13d
jge 0x2548
movslq %r13d, %rax
movq (%r14,%rax,8), %rdx
cmpb $0x2d, (%rdx)
jne 0x250f
movzbl 0x1(%rdx), %eax
leal -0x61(%rax), %ecx
cmpl $0x7, %ecx
ja 0x2437
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movb $0x1, %r11b
jmp 0x2466
cmpl $0x70, %eax
je 0x2463
cmpl $0x73, %eax
jne 0x246b
movb $0x1, %r8b
jmp 0x2466
movb $0x1, %r15b
jmp 0x2466
leal 0x1(%r13), %eax
cmpl %ebp, %eax
jge 0x24bc
movslq %eax, %rcx
movq (%r14,%rcx,8), %r9
movl %eax, %r13d
jmp 0x2466
movb $0x1, %bl
jmp 0x2466
movb $0x1, %dil
incl %r13d
jmp 0x2404
movq %rdi, 0x10(%rsp)
movq 0x12b69(%rip), %rax     # 0x14fe0
movq (%rax), %rdi
movq %rbx, 0x8(%rsp)
movq %r11, 0x18(%rsp)
xorl %eax, %eax
movq %r8, 0x20(%rsp)
movq %r15, 0x30(%rsp)
movq %r9, %r15
movq %rsi, %rbx
callq 0x2230
movq %rbx, %rsi
movq %r15, %r9
movq 0x30(%rsp), %r15
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %r11
movq 0x8(%rsp), %rbx
jmp 0x2507
movq 0x12b1d(%rip), %rax     # 0x14fe0
movq (%rax), %rcx
movq %rdi, 0x10(%rsp)
leaq 0x8b52(%rip), %rdi      # 0xb024
movq %r11, 0x18(%rsp)
pushq $0x25
popq %rsi
pushq $0x1
popq %rdx
movq %r8, 0x20(%rsp)
movq %r9, 0x8(%rsp)
callq 0x22c0
leaq 0x8b57(%rip), %rsi      # 0xb04a
movq 0x8(%rsp), %r9
movq 0x20(%rsp), %r8
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %r11
movb $0x1, %r10b
jmp 0x2466
movq %rdi, %r12
movq 0x12ac7(%rip), %rax     # 0x14fe0
movq (%rax), %rdi
movq %r11, %r14
leaq 0x8b42(%rip), %rsi      # 0xb068
xorl %eax, %eax
movq %r8, %r13
movq %r15, %rbp
movq %r9, %r15
callq 0x2230
movq %r15, %r9
movq %rbp, %r15
movq %r13, %r8
movq %r12, %rdi
movq %r14, %r11
movb $0x1, %r10b
testq %r9, %r9
je 0x270d
testb $0x1, %r15b
jne 0x255d
testb $0x1, %r10b
je 0x25a3
leaq 0x8c03(%rip), %rdi      # 0xb167
movq %r10, %rbx
callq 0x2240
movq 0x12a4d(%rip), %rax     # 0x14fc0
movq (%rax), %rdi
callq 0x2180
movq 0x12a5e(%rip), %rax     # 0x14fe0
movq (%rax), %rdi
callq 0x2180
andb $0x1, %bl
movzbl %bl, %ebp
negl %ebp
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r8, %r13
movq %rdi, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r9, %r14
callq 0x2750
leaq 0x9574(%rip), %rsi      # 0xbb33
movq %r14, %rdi
callq 0x2190
testq %rax, %rax
je 0x26f4
movq %rax, %r15
movq %rbx, 0x8(%rsp)
xorl %r14d, %r14d
pushq $0x2
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x2170
movq %r15, %rdi
callq 0x2030
leaq 0x4(%rax), %r12
leaq 0x5(%rax), %rdi
callq 0x27d1
movq %rax, %rbx
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2170
movq %r15, %rdi
callq 0x2260
cmpl $-0x1, %eax
je 0x263a
movl %eax, %ebp
cmpq %r14, %r12
ja 0x2631
addq %r12, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2870
movq %rax, %rbx
movb %bpl, (%rbx,%r14)
incq %r14
jmp 0x260c
movb $0x0, (%rbx,%r14)
movq %r15, %rdi
callq 0x2160
testb $0x1, %r13b
je 0x2661
leaq 0x8a7e(%rip), %rdi      # 0xb0d2
movl %r14d, %esi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2050
callq 0x6dd8
movq %rax, %r14
movq 0x10(%rsp), %r13
andb $0x1, %r13b
leaq 0x2e(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x18(%rsp), %r13
andb $0x1, %r13b
movb %r13b, 0x1(%rdx)
movq %rax, %rdi
movq %rbx, %rsi
callq 0x6f55
testb $0x1, 0x8(%rsp)
je 0x26ae
leaq 0x8a71(%rip), %rdi      # 0xb111
callq 0x2240
movq 0x20(%r14), %rdi
callq 0x9ea5
xorl %ebp, %ebp
movq %r14, %rdi
xorl %esi, %esi
callq 0x7ad9
movq %r14, %rdi
callq 0x6e15
leaq 0x8a6b(%rip), %rdi      # 0xb134
callq 0x2240
movq 0x128eb(%rip), %rax     # 0x14fc0
movq (%rax), %rdi
callq 0x2180
callq 0x2200
movq %rbx, %rdi
callq 0x286b
callq 0x27d6
jmp 0x2592
leaq 0x89b5(%rip), %rdi      # 0xb0b0
movq %r14, %rsi
xorl %eax, %eax
callq 0x2050
pushq $-0x1
popq %rbp
jmp 0x2592
movq 0x128cc(%rip), %rax     # 0x14fe0
movq (%rax), %rcx
movq %rdi, %r12
leaq 0x896a(%rip), %rdi      # 0xb08b
movq %r11, %r14
pushq $0x24
popq %rsi
pushq $0x1
popq %rdx
movq %r8, %r13
movq %r15, %rbp
movq %r9, %r15
callq 0x22c0
movq %r15, %r9
movq %rbp, %r15
movq %r13, %r8
movq %r12, %rdi
movq %r14, %r11
movb $0x1, %r10b
jmp 0x2551
nop