// File: /workspace/github_cpp_makefile_star2_O2/CobaltXII[P]cxcc/cxcc.cpp
// Function: main
int main(int argc, char** argv) {
	if (argc != 2 && argc != 3 && argc != 4) {
		usage(argv[0]);
	} else if (argc == 4) {
		if (std::string(argv[3]) != "-o") {
			usage(argv[0]);
		}
	}

	// Open the file.
	std::ifstream file_stream(argv[1]);
	if (!file_stream.is_open()) {
		std::cerr << "Could not open file \"" << argv[1] << "\"." << std::endl;
		exit(1);
	}

	// Load the file.
	std::string file_content(
		(std::istreambuf_iterator<char>(file_stream)),
		(std::istreambuf_iterator<char>())
	);
	file_stream.close();

	// Parse the second argument.
	std::string outfile;
	if (argc == 3) {
		outfile = argv[2];
	} else if (argc == 4) {
		outfile = "tmp" + std::to_string(time(NULL)) + ".s";
	} else {
		outfile = std::string(argv[1]) + ".s";
	}

	// Open the output file.
	std::FILE* output_file = fopen(outfile.c_str(), "w");

	// Parse the file (implicity lexes the file).
	program_t program = parser_t(argv[1], file_content).parse();

	// Validate the program.
	semantic_analyzer_t semantic_analyzer(argv[1], file_content);
	semantic_analyzer.validate(program);

	// Compile the program.
	compiler_t compiler(program, output_file);
	compiler.compile();
	fclose(output_file);

	// Optionally assembly the output using gcc.
	if (argc == 4) {
		// Assemble the output.
		std::stringstream gcc_cmd;
		gcc_cmd << "gcc " << outfile << " -o " << argv[2];
		system(gcc_cmd.str().c_str());
		// Remove the temporary file.
		std::stringstream rm_cmd;
		rm_cmd << "rm -f " << outfile;
		system(rm_cmd.str().c_str());
	}

	// Exit successfully.
	exit(EXIT_SUCCESS);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x698, %rsp            # imm = 0x698
movq %rsi, %rbx
movl %edi, %r14d
leal -0x5(%r14), %eax
cmpl $-0x4, %eax
ja 0x3496
movq (%rbx), %rdi
callq 0x33b8
cmpl $0x4, %r14d
jne 0x34d6
movq 0x18(%rbx), %rsi
leaq 0x490(%rsp), %r15
leaq 0x308(%rsp), %rdx
movq %r15, %rdi
callq 0x3a1e
leaq 0xd40d(%rip), %rsi      # 0x108cc
movq %r15, %rdi
callq 0x3ad7
movl %eax, %ebp
movq %r15, %rdi
callq 0x2100
testb %bpl, %bpl
jne 0x348e
movq 0x8(%rbx), %rsi
leaq 0x490(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x23b0
leaq 0x508(%rsp), %rdi
callq 0x2070
testb %al, %al
je 0x356b
movq 0x490(%rsp), %rax
movq -0x18(%rax), %rax
movq 0x578(%rsp,%rax), %rsi
leaq 0x68(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x58(%rsp), %rdi
pushq $-0x1
popq %rdx
xorl %ecx, %ecx
movl %edx, %r8d
callq 0xfb68
leaq 0x490(%rsp), %rdi
callq 0x2060
leaq 0x18(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
cmpl $0x4, %r14d
je 0x35a9
cmpl $0x3, %r14d
jne 0x362c
movq 0x10(%rbx), %rsi
leaq 0x8(%rsp), %rdi
callq 0x23d0
jmp 0x368b
movq 0x14a7e(%rip), %rdi     # 0x17ff0
leaq 0xd356(%rip), %rsi      # 0x108cf
callq 0x2220
movq 0x8(%rbx), %rsi
movq %rax, %rdi
callq 0x2220
leaq 0xd354(%rip), %rsi      # 0x108e5
movq %rax, %rdi
callq 0x2220
movq %rax, %rdi
callq 0x2110
pushq $0x1
popq %rdi
callq 0x2290
xorl %edi, %edi
callq 0x2200
leaq 0xd8(%rsp), %rdi
movq %rax, %rsi
callq 0x3b00
leaq 0xd321(%rip), %rsi      # 0x108e8
leaq 0x180(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x3ab3
leaq 0xd309(%rip), %rdx      # 0x108ec
leaq 0x308(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x3ae1
leaq 0x8(%rsp), %rdi
leaq 0x308(%rsp), %r15
movq %r15, %rsi
callq 0x22a0
movq %r15, %rdi
callq 0x2100
leaq 0x180(%rsp), %rdi
callq 0x2100
leaq 0xd8(%rsp), %rdi
jmp 0x3686
movq 0x8(%rbx), %rsi
leaq 0x180(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x3a1e
leaq 0xd2a0(%rip), %rdx      # 0x108ec
leaq 0x308(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x3ae1
leaq 0x8(%rsp), %rdi
leaq 0x308(%rsp), %r15
movq %r15, %rsi
callq 0x22a0
movq %r15, %rdi
callq 0x2100
leaq 0x180(%rsp), %rdi
callq 0x2100
movq 0x8(%rsp), %rdi
leaq 0xd258(%rip), %rsi      # 0x108ef
callq 0x2280
movq %rax, %r15
movq 0x8(%rbx), %rsi
leaq 0x138(%rsp), %rdi
leaq 0x180(%rsp), %rdx
callq 0x3a1e
leaq 0x118(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x22e0
leaq 0x308(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x118(%rsp), %rdx
callq 0x3b60
leaq 0x40(%rsp), %rdi
leaq 0x308(%rsp), %rsi
callq 0x3d98
leaq 0x308(%rsp), %rdi
callq 0x3ed0
leaq 0x118(%rsp), %rdi
callq 0x2100
leaq 0x138(%rsp), %rdi
callq 0x2100
movq 0x8(%rbx), %rsi
leaq 0xb8(%rsp), %rdi
leaq 0x308(%rsp), %rdx
callq 0x3a1e
leaq 0x98(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x22e0
leaq 0xd8(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x3ee6
leaq 0x98(%rsp), %rdi
callq 0x2100
leaq 0xb8(%rsp), %rdi
callq 0x2100
leaq 0xd8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x3f48
leaq 0x28(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x430e
leaq 0x158(%rsp), %rdi
leaq 0x28(%rsp), %rsi
movq %r15, %rdx
callq 0x4368
leaq 0x28(%rsp), %rdi
callq 0x43a6
leaq 0x158(%rsp), %rdi
callq 0x43c8
movq %r15, %rdi
callq 0x2230
cmpl $0x4, %r14d
jne 0x38c7
leaq 0x308(%rsp), %rdi
callq 0x2170
leaq 0x318(%rsp), %rdi
leaq 0xd0f4(%rip), %rsi      # 0x108f1
callq 0x2220
leaq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x21f0
leaq 0xd0e0(%rip), %rsi      # 0x108f6
movq %rax, %rdi
callq 0x2220
movq 0x10(%rbx), %rsi
movq %rax, %rdi
callq 0x2220
leaq 0x320(%rsp), %rsi
leaq 0x180(%rsp), %rdi
callq 0x2340
movq 0x180(%rsp), %rdi
callq 0x21c0
leaq 0x180(%rsp), %rdi
callq 0x2100
leaq 0x180(%rsp), %rdi
callq 0x2170
leaq 0x190(%rsp), %rdi
leaq 0xd086(%rip), %rsi      # 0x108fb
callq 0x2220
leaq 0x8(%rsp), %rsi
movq %rax, %rdi
callq 0x21f0
leaq 0x198(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x2340
movq 0x78(%rsp), %rdi
callq 0x21c0
leaq 0x78(%rsp), %rdi
callq 0x2100
leaq 0x180(%rsp), %rdi
callq 0x2190
leaq 0x308(%rsp), %rdi
callq 0x2190
xorl %edi, %edi
callq 0x2290
movq %rax, %rbx
leaq 0x78(%rsp), %rdi
callq 0x2100
jmp 0x38e2
jmp 0x38df
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
callq 0x2190
jmp 0x390a
jmp 0x3907
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
callq 0x2100
jmp 0x390a
jmp 0x3907
movq %rax, %rbx
leaq 0x308(%rsp), %rdi
callq 0x2190
jmp 0x391e
jmp 0x391b
movq %rax, %rbx
leaq 0x160(%rsp), %rdi
jmp 0x3930
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x43a6
jmp 0x393c
jmp 0x3939
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x458c
jmp 0x3972
movq %rax, %rbx
leaq 0x98(%rsp), %rdi
callq 0x2100
jmp 0x3960
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x2100
jmp 0x3972
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x43a6
jmp 0x39e9
movq %rax, %rbx
leaq 0x308(%rsp), %rdi
callq 0x3ed0
jmp 0x3993
movq %rax, %rbx
leaq 0x118(%rsp), %rdi
callq 0x2100
jmp 0x39b7
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
callq 0x2100
jmp 0x39d1
movq %rax, %rbx
leaq 0x138(%rsp), %rdi
jmp 0x39d9
movq %rax, %rbx
leaq 0x180(%rsp), %rdi
jmp 0x39d9
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x2100
jmp 0x39e9
jmp 0x39e6
jmp 0x39e6
jmp 0x39e6
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2100
jmp 0x39f8
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x2100
jmp 0x3a09
jmp 0x3a06
movq %rax, %rbx
leaq 0x490(%rsp), %rdi
callq 0x2090
movq %rbx, %rdi
callq 0x2390