// File: /workspace/github_cpp_makefile_star2_O1/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
cmpl $0x2, %edi
jl 0x2612
movq %rsi, %r14
movl %edi, %ebp
movl $0x1, %r13d
leaq 0xab2f(%rip), %r11      # 0xd004
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %r9d, %r9d
xorl %r8d, %r8d
xorl %edi, %edi
xorl %r10d, %r10d
xorl %esi, %esi
movslq %r13d, %rax
movq (%r14,%rax,8), %rdx
movb (%rdx), %r12b
cmpb $0x2d, %r12b
jne 0x254e
movzbl 0x1(%rdx), %eax
leal -0x61(%rax), %ecx
cmpl $0x7, %ecx
ja 0x2514
movslq (%r11,%rcx,4), %rax
addq %r11, %rax
jmpq *%rax
movb $0x1, %dil
jmp 0x25a4
cmpl $0x70, %eax
je 0x2549
cmpl $0x73, %eax
jne 0x25b8
movb $0x1, %r9b
jmp 0x25a4
movb $0x1, %r10b
jmp 0x25a4
leal 0x1(%r13), %eax
cmpl %ebp, %eax
jge 0x25d5
movslq %eax, %rcx
movq (%r14,%rcx,8), %rbx
movl %eax, %r13d
jmp 0x25a4
movb $0x1, %sil
jmp 0x25a4
movb $0x1, %r8b
jmp 0x25a4
movq %rdi, 0x20(%rsp)
movq 0x14a86(%rip), %rax     # 0x16fe0
movq (%rax), %rdi
movq %rsi, 0x8(%rsp)
leaq 0xaaff(%rip), %rsi      # 0xd068
xorl %eax, %eax
movq %r9, 0x18(%rsp)
movq %rbx, 0x10(%rsp)
movq %r8, %rbx
movq %r10, %r15
callq 0x2230
leaq 0xaa7d(%rip), %r11      # 0xd004
movq %r15, %r10
movq %rbx, %r8
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r9
movq 0x20(%rsp), %rdi
movq 0x8(%rsp), %rsi
movb $0x1, %r15b
cmpb $0x2d, %r12b
jne 0x2626
incl %r13d
cmpl %ebp, %r13d
jl 0x24e7
jmp 0x2626
movq %rdi, 0x20(%rsp)
movq 0x14a1c(%rip), %rax     # 0x16fe0
movq (%rax), %rdi
movq %rsi, 0x8(%rsp)
leaq 0xaa77(%rip), %rsi      # 0xd04a
jmp 0x2569
movq %rsi, 0x8(%rsp)
movq %r9, 0x18(%rsp)
movq %rbx, 0x10(%rsp)
movq %rdi, %rbx
movq %r8, 0x28(%rsp)
movq %r10, %r15
callq 0x22e0
leaq 0xaa09(%rip), %r11      # 0xd004
movq %r15, %r10
movq 0x28(%rsp), %r8
movq %rbx, %rdi
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r9
jmp 0x259c
xorl %esi, %esi
xorl %r10d, %r10d
xorl %edi, %edi
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %ebx, %ebx
xorl %r15d, %r15d
jmp 0x262e
andb $0x1, %r8b
andb $0x1, %dil
testq %rbx, %rbx
je 0x27fe
testb $0x1, %r10b
jne 0x2643
testb $0x1, %r15b
je 0x2688
leaq 0xab5e(%rip), %rdi      # 0xd1a8
callq 0x2240
movq 0x1496a(%rip), %rax     # 0x16fc0
movq (%rax), %rdi
callq 0x2180
movq 0x1497b(%rip), %rax     # 0x16fe0
movq (%rax), %rdi
callq 0x2180
andb $0x1, %r15b
movzbl %r15b, %ebp
negl %ebp
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r9, %r13
movq %r8, 0x28(%rsp)
movq %rdi, 0x20(%rsp)
movq %rsi, 0x8(%rsp)
callq 0x2850
leaq 0xb4cd(%rip), %rsi      # 0xdb73
movq %rbx, %rdi
callq 0x2190
movq %rax, %r15
testq %rax, %rax
je 0x272e
xorl %r14d, %r14d
movq %r15, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x2170
movq %r15, %rdi
callq 0x2030
leaq 0x4(%rax), %r12
leaq 0x5(%rax), %rdi
callq 0x28d1
movq %rax, %rbx
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2170
movq %r15, %rdi
callq 0x2260
movl %eax, %ebp
cmpl $-0x1, %eax
je 0x2718
cmpq %r14, %r12
ja 0x2711
addq %r12, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2974
movq %rax, %rbx
movb %bpl, (%rbx,%r14)
incq %r14
cmpl $-0x1, %ebp
jne 0x26ec
movb $0x0, (%rbx,%r14)
movq %r15, %rdi
callq 0x2160
xorl %ebp, %ebp
jmp 0x2749
leaq 0xa97b(%rip), %rdi      # 0xd0b0
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2050
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
xorl %ebx, %ebx
testq %r15, %r15
je 0x2677
testq %rbx, %rbx
je 0x282f
testb $0x1, %r13b
je 0x2775
leaq 0xa9ab(%rip), %rdi      # 0xd113
movl %r14d, %esi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2050
callq 0x7fec
movq %rax, %r14
leaq 0x36(%rsp), %rdx
movq 0x28(%rsp), %rax
movb %al, (%rdx)
movq 0x20(%rsp), %rax
movb %al, 0x1(%rdx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x81db
testb $0x1, 0x8(%rsp)
je 0x27b8
leaq 0xa9a8(%rip), %rdi      # 0xd152
callq 0x2240
movq 0x20(%r14), %rdi
callq 0xbfaa
xorl %ebp, %ebp
movq %r14, %rdi
xorl %esi, %esi
callq 0x9006
movq %r14, %rdi
callq 0x806a
leaq 0xa9a2(%rip), %rdi      # 0xd175
callq 0x2240
movq 0x147e1(%rip), %rax     # 0x16fc0
movq (%rax), %rdi
callq 0x2180
callq 0x2200
movq %rbx, %rdi
callq 0x296f
callq 0x28d6
jmp 0x2677
movq %r9, %r12
movq %rbx, %r13
movq %rsi, %rbx
movq %rdi, %r14
movq %r8, %r15
movq %r10, %rbp
callq 0x22fc
movq %rbp, %r10
movq %r15, %r8
movq %r14, %rdi
movq %rbx, %rsi
movq %r13, %rbx
movq %r12, %r9
movb $0x1, %r15b
jmp 0x2637
leaq 0xa89c(%rip), %rdi      # 0xd0d2
leaq 0xa8a7(%rip), %rsi      # 0xd0e4
leaq 0xa8b2(%rip), %rcx      # 0xd0f6
movl $0x88, %edx
callq 0x20f0
nop