// File: AshOlogn[P]ash-language-interpreter/src/main.cpp
// Function: main
int main(int argc, char** argv) {
  
  //read in source code
  char* sourceFile = argv[1];
  fstream in(sourceFile, fstream::in);

  in.seekg(0, in.end);
  uint32_t length = in.tellg();
  in.seekg(0, in.beg);
  
  char* sourceCode = new char[length+1];
  in.read(sourceCode, length);
  sourceCode[length] = 0;
  in.close();

  //convert source code into array of lines
  vector<char*>* codeLines = getLines(sourceCode);
  
  //generate array of Tokens from source code 
  vector<Token> tokens;
  
  try {
    tokens = lex(sourceCode, codeLines);
  } catch(exception& e) {
    cout << e.what() << endl;
    return 1;
  }
	
  //get list of statements from list of tokens (parse)
  vector<AbstractStatementNode*>* statements;
  
  try {
    statements = parse(&tokens, codeLines); 
  } catch(exception& e) {
    cout << e.what() << endl;
    return 1;
  }
  
  vector<AbstractStatementNode*>::iterator it2;
	
  //execute statements
  for(it2 = statements->begin(); it2 != statements->end(); it2++) {

		try {
			(*it2)->execute();
		}	catch(exception& e) {
			cout << e.what() << endl;
			return 1;
		}	
  }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x320, %rsp            # imm = 0x320
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x228(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
movl $0x8, %edx
callq 0x4330
movq -0x2d8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x4340
jmp 0x4c18
leaq -0x228(%rbp), %rdi
callq 0x4400
movq %rdx, -0x2e8(%rbp)
movq %rax, -0x2e0(%rbp)
jmp 0x4c34
movq -0x2e8(%rbp), %rax
movq -0x2e0(%rbp), %rcx
movq %rcx, -0x248(%rbp)
movq %rax, -0x240(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x5220
movq %rax, -0x2f0(%rbp)
jmp 0x4c65
movq -0x2f0(%rbp), %rax
movl %eax, -0x238(%rbp)
xorl %edx, %edx
movl %edx, %esi
leaq -0x228(%rbp), %rdi
callq 0x4340
jmp 0x4c84
movl -0x238(%rbp), %eax
incl %eax
movl %eax, %edi
callq 0x4030
movq %rax, -0x2f8(%rbp)
jmp 0x4c9c
movq -0x2f8(%rbp), %rax
movq %rax, -0x250(%rbp)
movq -0x250(%rbp), %rsi
movl -0x238(%rbp), %eax
movl %eax, %edx
leaq -0x228(%rbp), %rdi
callq 0x42d0
jmp 0x4cc7
movq -0x250(%rbp), %rax
movl -0x238(%rbp), %ecx
movb $0x0, (%rax,%rcx)
leaq -0x228(%rbp), %rdi
callq 0x4050
jmp 0x4ce6
movq -0x250(%rbp), %rdi
callq 0x50b0
movq %rax, -0x300(%rbp)
jmp 0x4cfb
movq -0x300(%rbp), %rax
movq %rax, -0x258(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x5240
movq -0x250(%rbp), %rsi
movq -0x258(%rbp), %rdx
leaq -0x288(%rbp), %rdi
callq 0x8630
jmp 0x4d31
leaq -0x270(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x5260
leaq -0x288(%rbp), %rdi
callq 0x5290
jmp 0x4e33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
jmp 0x508c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
movl -0x234(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5080
movq -0x230(%rbp), %rdi
callq 0x40d0
movq %rax, -0x290(%rbp)
movq -0x290(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0x4f21a(%rip), %rdi     # 0x53fd8
callq 0x4250
movq %rax, -0x308(%rbp)
jmp 0x4dcc
movq -0x308(%rbp), %rdi
movq 0x4f1de(%rip), %rsi     # 0x53fb8
callq 0x4270
jmp 0x4de1
movl $0x1, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
callq 0x43e0
jmp 0x4e12
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
callq 0x43e0
jmp 0x4e2e
jmp 0x505c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
jmp 0x5080
jmp 0x5080
movq -0x258(%rbp), %rsi
leaq -0x270(%rbp), %rdi
callq 0x39e00
movq %rax, -0x310(%rbp)
jmp 0x4e4f
movq -0x310(%rbp), %rax
movq %rax, -0x2a0(%rbp)
jmp 0x4f12
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
movl -0x234(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5080
movq -0x230(%rbp), %rdi
callq 0x40d0
movq %rax, -0x2a8(%rbp)
movq -0x2a8(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0x4f124(%rip), %rdi     # 0x53fd8
callq 0x4250
movq %rax, -0x318(%rbp)
jmp 0x4ec2
movq -0x318(%rbp), %rdi
movq 0x4f0e8(%rip), %rsi     # 0x53fb8
callq 0x4270
jmp 0x4ed7
movl $0x1, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
callq 0x43e0
jmp 0x4f08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
callq 0x43e0
jmp 0x4f0d
jmp 0x505c
jmp 0x5080
leaq -0x2b0(%rbp), %rdi
callq 0x5300
movq -0x2a0(%rbp), %rdi
callq 0x5320
movq %rax, -0x2b8(%rbp)
movq -0x2b8(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq -0x2a0(%rbp), %rdi
callq 0x5390
movq %rax, -0x2c0(%rbp)
leaq -0x2b0(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x5350
testb $0x1, %al
jne 0x4f6e
jmp 0x5052
leaq -0x2b0(%rbp), %rdi
callq 0x53c0
movq (%rax), %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x4f87
jmp 0x5036
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
movl -0x234(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5080
movq -0x230(%rbp), %rdi
callq 0x40d0
movq %rax, -0x2c8(%rbp)
movq -0x2c8(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0x4effa(%rip), %rdi     # 0x53fd8
callq 0x4250
movq %rax, -0x320(%rbp)
jmp 0x4fec
movq -0x320(%rbp), %rdi
movq 0x4efbe(%rip), %rsi     # 0x53fb8
callq 0x4270
jmp 0x5001
movl $0x1, -0x4(%rbp)
movl $0x1, -0x294(%rbp)
callq 0x43e0
jmp 0x5032
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x230(%rbp)
movl %eax, -0x234(%rbp)
callq 0x43e0
jmp 0x5034
jmp 0x505c
jmp 0x5080
jmp 0x5038
leaq -0x2b0(%rbp), %rdi
xorl %esi, %esi
callq 0x53e0
movq %rax, -0x2d0(%rbp)
jmp 0x4f3f
movl $0x0, -0x294(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x5290
leaq -0x228(%rbp), %rdi
callq 0x4090
movl -0x4(%rbp), %eax
addq $0x320, %rsp            # imm = 0x320
popq %rbp
retq
leaq -0x270(%rbp), %rdi
callq 0x5290
leaq -0x228(%rbp), %rdi
callq 0x4090
movq -0x230(%rbp), %rdi
callq 0x4420
movq %rax, %rdi
callq 0x52f0
nopl (%rax)