// File: AndrewAlbert[P]Compiler-Theory/SourceCode/compiler.cpp
// Function: main
int main(int argc, char **argv){
	bool debug;
	string filename;
	if( (argc == 2) || (argc == 3) ){
		if( (string(argv[1]) == "--help") || (string(argv[1]) == "--h") ){
			cout << "\nThis is a compiler written for the University of Cincinnati class: EECE6083 Compiler Theory" << endl;
			cout << "\nThe compiler is an LL(1) recursive descent compiler and utilizes the C++ programming language to scan, parse, and type check the program and LLVM to generate the compiler backend." << endl;
			cout << "\nTo use this compiler, compile and then run from the command line using the arguments: [ --help | --h | --debug | --d ] filename." << endl;
			cout << "\nThe compiler will scan and parse your file and generate code if parsing is successful. Otherwise relevant errors and warnings will be shown." << endl;
			cout << "\n--debug or --d argument will print out each token as it is scanned and print out each scope's symbol table after the scope is exited." << endl;
			return 0;
		}
		else if( (string(argv[1]) == "--debug") || (string(argv[1]) == "--d") ){
			debug = true;
			filename = string(argv[2]);
		}
		else if(argc == 2){
			debug = false;
			filename = string(argv[1]);
		}	
	}
	else{
		commandError();
		return 0;
	}

	//Initialize scanner and symbol tables.
	Scanner *scanner = new Scanner;
	scopeTracker *scopes = new scopeTracker(debug);
	codeGenerator *gen = new codeGenerator;

	//Contains token currently being scanned/parsed
	token_type *token = new token_type;

	scanner->token = token;
	//Initialize scanner, then begin parsing if there are no errors
	if(scanner->InitScanner(filename, debug)){
		*token = scanner->getToken();
		gen->attachOutputFile( (filename) + ".c" );
		Parser parser(token, scanner, scopes, gen);
	}
	delete scanner;
	delete scopes;
	delete gen;

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x460, %rsp            # imm = 0x460
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3370
cmpl $0x2, -0x8(%rbp)
je 0x23772
cmpl $0x3, -0x8(%rbp)
jne 0x23d4c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x370(%rbp)
leaq -0x59(%rbp), %rdi
movq %rdi, -0x368(%rbp)
callq 0x3430
movq -0x370(%rbp), %rsi
movq -0x368(%rbp), %rdx
movb $0x0, -0x92(%rbp)
movb $0x0, -0x93(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x62d0
jmp 0x237b8
leaq 0x4040(%rip), %rsi      # 0x277ff
leaq -0x58(%rbp), %rdi
callq 0x6520
movb %al, -0x371(%rbp)
jmp 0x237d0
movb -0x371(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x372(%rbp)
jne 0x2385a
jmp 0x237e5
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x388(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x3430
movq -0x388(%rbp), %rsi
movq -0x380(%rbp), %rdx
movb $0x1, -0x92(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x62d0
jmp 0x2382a
movb $0x1, -0x93(%rbp)
leaq 0x3fce(%rip), %rsi      # 0x27806
leaq -0x90(%rbp), %rdi
callq 0x6520
movb %al, -0x389(%rbp)
jmp 0x2384c
movb -0x389(%rbp), %al
movb %al, -0x372(%rbp)
jmp 0x2385a
movb -0x372(%rbp), %al
movb %al, -0x38a(%rbp)
testb $0x1, -0x93(%rbp)
jne 0x23871
jmp 0x2387d
leaq -0x90(%rbp), %rdi
callq 0x31a0
testb $0x1, -0x92(%rbp)
jne 0x23888
jmp 0x23894
leaq -0x91(%rbp), %rdi
callq 0x32e0
leaq -0x58(%rbp), %rdi
callq 0x31a0
leaq -0x59(%rbp), %rdi
callq 0x32e0
movb -0x38a(%rbp), %al
testb $0x1, %al
jne 0x238b5
jmp 0x23a50
movq 0xf714(%rip), %rdi      # 0x32fd0
leaq 0x3f47(%rip), %rsi      # 0x2780a
callq 0x3270
movq %rax, -0x398(%rbp)
jmp 0x238d1
movq -0x398(%rbp), %rdi
movq 0xf6d9(%rip), %rsi      # 0x32fb8
callq 0x32c0
jmp 0x238e6
movq 0xf6e3(%rip), %rdi      # 0x32fd0
leaq 0x3f73(%rip), %rsi      # 0x27867
callq 0x3270
movq %rax, -0x3a0(%rbp)
jmp 0x23902
movq -0x3a0(%rbp), %rdi
movq 0xf6a8(%rip), %rsi      # 0x32fb8
callq 0x32c0
jmp 0x23917
movq 0xf6b2(%rip), %rdi      # 0x32fd0
leaq 0x3ff7(%rip), %rsi      # 0x2791c
callq 0x3270
movq %rax, -0x3a8(%rbp)
jmp 0x23933
movq -0x3a8(%rbp), %rdi
movq 0xf677(%rip), %rsi      # 0x32fb8
callq 0x32c0
jmp 0x23948
movq 0xf681(%rip), %rdi      # 0x32fd0
leaq 0x4048(%rip), %rsi      # 0x2799e
callq 0x3270
movq %rax, -0x3b0(%rbp)
jmp 0x23964
movq -0x3b0(%rbp), %rdi
movq 0xf646(%rip), %rsi      # 0x32fb8
callq 0x32c0
jmp 0x23979
movq 0xf650(%rip), %rdi      # 0x32fd0
leaq 0x40a5(%rip), %rsi      # 0x27a2c
callq 0x3270
movq %rax, -0x3b8(%rbp)
jmp 0x23995
movq -0x3b8(%rbp), %rdi
movq 0xf615(%rip), %rsi      # 0x32fb8
callq 0x32c0
jmp 0x239aa
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
jmp 0x2409e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23a31
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23a28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23a0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
testb $0x1, -0x93(%rbp)
jne 0x23a01
jmp 0x23a0d
leaq -0x90(%rbp), %rdi
callq 0x31a0
jmp 0x23a0f
testb $0x1, -0x92(%rbp)
jne 0x23a1a
jmp 0x23a26
leaq -0x91(%rbp), %rdi
callq 0x32e0
jmp 0x23a28
leaq -0x58(%rbp), %rdi
callq 0x31a0
leaq -0x59(%rbp), %rdi
callq 0x32e0
jmp 0x240b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x240b3
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x3c8(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x3430
movq -0x3c8(%rbp), %rsi
movq -0x3c0(%rbp), %rdx
movb $0x0, -0xe2(%rbp)
movb $0x0, -0xe3(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x62d0
jmp 0x23a9c
leaq 0x4010(%rip), %rsi      # 0x27ab3
leaq -0xb8(%rbp), %rdi
callq 0x6520
movb %al, -0x3c9(%rbp)
jmp 0x23ab7
movb -0x3c9(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x3ca(%rbp)
jne 0x23b41
jmp 0x23acc
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x3e0(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x3d8(%rbp)
callq 0x3430
movq -0x3e0(%rbp), %rsi
movq -0x3d8(%rbp), %rdx
movb $0x1, -0xe2(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x62d0
jmp 0x23b11
movb $0x1, -0xe3(%rbp)
leaq 0x3f9c(%rip), %rsi      # 0x27abb
leaq -0xe0(%rbp), %rdi
callq 0x6520
movb %al, -0x3e1(%rbp)
jmp 0x23b33
movb -0x3e1(%rbp), %al
movb %al, -0x3ca(%rbp)
jmp 0x23b41
movb -0x3ca(%rbp), %al
movb %al, -0x3e2(%rbp)
testb $0x1, -0xe3(%rbp)
jne 0x23b58
jmp 0x23b64
leaq -0xe0(%rbp), %rdi
callq 0x31a0
testb $0x1, -0xe2(%rbp)
jne 0x23b6f
jmp 0x23b7b
leaq -0xe1(%rbp), %rdi
callq 0x32e0
leaq -0xb8(%rbp), %rdi
callq 0x31a0
leaq -0xb9(%rbp), %rdi
callq 0x32e0
movb -0x3e2(%rbp), %al
testb $0x1, %al
jne 0x23ba2
jmp 0x23cb3
movb $0x1, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x3f8(%rbp)
leaq -0x109(%rbp), %rdi
movq %rdi, -0x3f0(%rbp)
callq 0x3430
movq -0x3f8(%rbp), %rsi
movq -0x3f0(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0x62d0
jmp 0x23be4
leaq -0x38(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x3340
leaq -0x108(%rbp), %rdi
callq 0x31a0
leaq -0x109(%rbp), %rdi
callq 0x32e0
jmp 0x23d48
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23c85
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23c79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x23c60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
testb $0x1, -0xe3(%rbp)
jne 0x23c52
jmp 0x23c5e
leaq -0xe0(%rbp), %rdi
callq 0x31a0
jmp 0x23c60
testb $0x1, -0xe2(%rbp)
jne 0x23c6b
jmp 0x23c77
leaq -0xe1(%rbp), %rdi
callq 0x32e0
jmp 0x23c79
leaq -0xb8(%rbp), %rdi
callq 0x31a0
leaq -0xb9(%rbp), %rdi
callq 0x32e0
jmp 0x240b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x109(%rbp), %rdi
callq 0x32e0
jmp 0x240b3
cmpl $0x2, -0x8(%rbp)
jne 0x23d46
movb $0x0, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x408(%rbp)
leaq -0x131(%rbp), %rdi
movq %rdi, -0x400(%rbp)
callq 0x3430
movq -0x408(%rbp), %rsi
movq -0x400(%rbp), %rdx
leaq -0x130(%rbp), %rdi
callq 0x62d0
jmp 0x23cff
leaq -0x38(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x3340
leaq -0x130(%rbp), %rdi
callq 0x31a0
leaq -0x131(%rbp), %rdi
callq 0x32e0
jmp 0x23d46
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x131(%rbp), %rdi
callq 0x32e0
jmp 0x240b3
jmp 0x23d48
jmp 0x23d4a
jmp 0x23d69
callq 0x23710
jmp 0x23d53
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
jmp 0x2409e
movl $0x178, %edi            # imm = 0x178
callq 0x3290
movq %rax, -0x410(%rbp)
jmp 0x23d7c
movq -0x410(%rbp), %rdi
callq 0x3740
jmp 0x23d8a
movq -0x410(%rbp), %rax
movq %rax, -0x140(%rbp)
movl $0x20, %edi
callq 0x3290
movq %rax, -0x418(%rbp)
jmp 0x23dab
movq -0x418(%rbp), %rdi
movzbl -0x11(%rbp), %esi
andl $0x1, %esi
callq 0x18200
jmp 0x23dc0
movq -0x418(%rbp), %rax
movq %rax, -0x148(%rbp)
movl $0x338, %edi            # imm = 0x338
callq 0x3290
movq %rax, -0x420(%rbp)
jmp 0x23de1
movq -0x420(%rbp), %rdi
callq 0x18cb0
jmp 0x23def
movq -0x420(%rbp), %rax
movq %rax, -0x150(%rbp)
movl $0x128, %edi            # imm = 0x128
callq 0x3290
movq %rax, -0x428(%rbp)
jmp 0x23e10
movq -0x428(%rbp), %rdi
callq 0x6160
movq -0x428(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rcx
movq -0x140(%rbp), %rax
movq %rcx, 0x170(%rax)
movq -0x140(%rbp), %rax
movq %rax, -0x430(%rbp)
leaq -0x178(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3130
jmp 0x23e5f
movq -0x430(%rbp), %rdi
movzbl -0x11(%rbp), %edx
andl $0x1, %edx
leaq -0x178(%rbp), %rsi
callq 0x37e0
movb %al, -0x431(%rbp)
jmp 0x23e81
leaq -0x178(%rbp), %rdi
callq 0x31a0
movb -0x431(%rbp), %al
testb $0x1, %al
jne 0x23e9c
jmp 0x23ffa
movq -0x140(%rbp), %rsi
leaq -0x2a0(%rbp), %rdi
callq 0x5520
jmp 0x23eb1
movq -0x158(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
movq %rsi, -0x448(%rbp)
callq 0x12600
movq -0x448(%rbp), %rdi
callq 0x61d0
movq -0x150(%rbp), %rax
movq %rax, -0x440(%rbp)
leaq 0x3bd3(%rip), %rdx      # 0x27abf
leaq -0x2c0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x12a60
jmp 0x23efe
movq -0x440(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x195c0
jmp 0x23f13
leaq -0x2c0(%rbp), %rdi
callq 0x31a0
movq -0x158(%rbp), %rsi
movq -0x140(%rbp), %rdx
movq -0x148(%rbp), %rcx
movq -0x150(%rbp), %r8
leaq -0x360(%rbp), %rdi
callq 0x8000
jmp 0x23f49
leaq -0x360(%rbp), %rdi
callq 0x8840
jmp 0x23ffa
movq -0x410(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
movl $0x178, %esi            # imm = 0x178
callq 0x32a0
jmp 0x240b3
movq -0x418(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
movl $0x20, %esi
callq 0x32a0
jmp 0x240b3
movq -0x420(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
movl $0x338, %esi            # imm = 0x338
callq 0x32a0
jmp 0x240b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x31a0
jmp 0x240b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0x31a0
jmp 0x240b3
movq -0x140(%rbp), %rax
movq %rax, -0x450(%rbp)
cmpq $0x0, %rax
je 0x2402b
movq -0x450(%rbp), %rdi
callq 0x3780
movq -0x450(%rbp), %rdi
movl $0x178, %esi            # imm = 0x178
callq 0x32a0
movq -0x148(%rbp), %rax
movq %rax, -0x458(%rbp)
cmpq $0x0, %rax
je 0x2405c
movq -0x458(%rbp), %rdi
callq 0x18240
movq -0x458(%rbp), %rdi
movl $0x20, %esi
callq 0x32a0
movq -0x150(%rbp), %rax
movq %rax, -0x460(%rbp)
cmpq $0x0, %rax
je 0x2408d
movq -0x460(%rbp), %rdi
callq 0x19160
movq -0x460(%rbp), %rdi
movl $0x338, %esi            # imm = 0x338
callq 0x32a0
movl $0x0, -0x4(%rbp)
movl $0x1, -0x98(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x31a0
movl -0x4(%rbp), %eax
addq $0x460, %rsp            # imm = 0x460
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x31a0
movq -0x68(%rbp), %rdi
callq 0x3420