// File: czmccrory[P]ManchesterBaby/assembler.cpp
// Function: Assembler::assembleLineFirstPass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, int*)
void Assembler::assembleLineFirstPass(string* line, int* lineCounter)
{
	string bufferLine;

	string parsed = parse(line);

	if (parsed == "") // nothing useful left on line
	{
		return;
	}

	// if theres a "LABEL": add it to symbol table along with current line number as address
	if (parsed.find(":") != string::npos)
	{
		//cout << "Label found: " << parsed;
		string label = parsed.substr(0, parsed.length()-1);

		addVariableToSymbolTable(label, *lineCounter);

		parsed = parse(line);

	}

	// if "VAR", declareVar(next word)
	if (parsed == "VAR")
	{
		int var;
		stringstream ss;
		try 
		{
			ss << parse(line);
			ss >> var;
		}
		catch (AssemblerException &e)
		{
			cout << "\033[1;31mAssembler Error: \033[0m" << e.what() << endl;
			exit(0);
		}
    
		bufferLine = declareVariable(var);
		cout << "Machine Code: " << bufferLine << "\n" << endl;

		(*lineCounter)++;

	}
	else if(iSet.contains(parsed)) // recognised instruction
	{
		if (parsed != "STP" && parsed != "CMP" && parsed != "INC" && parsed != "DEC") // has an operand
		{
			try 
			{
				string instrOperand = parse(line);
				if (instrOperand.find("#") == string::npos) // if direct addressing do nothing
				{
					bufferLine = encodeInstructionAddress(parsed, instrOperand);
				}
				cout << "Machine Code: " << bufferLine << "\n" << endl;
			}
			catch (AssemblerException &e)
			{
				cout << "\033[1;31mAssembler Error: \033[0m" << e.what() << endl;
				exit(0);
			}
		}
		
		(*lineCounter) = (*lineCounter + 1);
	}
	else
	{
		throw AssemblerException("Unidentified Opcode, this Opcode is not part of the instruction set");
		exit(0);
	 }	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x410, %rsp            # imm = 0x410
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x378(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x3390
movq -0x378(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0x5ea0
jmp 0x56b1
leaq 0x5a2c(%rip), %rsi      # 0xb0e4
leaq -0x58(%rbp), %rdi
callq 0x80b0
movb %al, -0x379(%rbp)
jmp 0x56c9
movb -0x379(%rbp), %al
testb $0x1, %al
jne 0x56d5
jmp 0x5703
movl $0x1, -0x68(%rbp)
jmp 0x5e5e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5e82
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5e79
leaq -0x58(%rbp), %rdi
leaq 0x5a29(%rip), %rsi      # 0xb137
xorl %eax, %eax
movl %eax, %edx
callq 0x34c0
cmpq $-0x1, %rax
je 0x5806
leaq -0x58(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x33d0
movq -0x388(%rbp), %rsi
movq %rax, %rcx
decq %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x88(%rbp), %rdi
callq 0x32c0
jmp 0x5750
leaq -0xa8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x3100
jmp 0x5765
movq -0x378(%rbp), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %edx
leaq -0xa8(%rbp), %rsi
callq 0x62c0
jmp 0x5780
leaq -0xa8(%rbp), %rdi
callq 0x31c0
movq -0x378(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x5ea0
jmp 0x57a5
leaq -0x58(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x3330
leaq -0xc8(%rbp), %rdi
callq 0x31c0
leaq -0x88(%rbp), %rdi
callq 0x31c0
jmp 0x5806
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x57f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x31c0
leaq -0x88(%rbp), %rdi
callq 0x31c0
jmp 0x5e79
leaq 0x58c3(%rip), %rsi      # 0xb0d0
leaq -0x58(%rbp), %rdi
callq 0x80b0
movb %al, -0x389(%rbp)
jmp 0x581e
movb -0x389(%rbp), %al
testb $0x1, %al
jne 0x582d
jmp 0x5a38
leaq -0x258(%rbp), %rdi
callq 0x31f0
jmp 0x583b
movq -0x378(%rbp), %rsi
leaq -0x248(%rbp), %rax
movq %rax, -0x398(%rbp)
movq -0x10(%rbp), %rdx
leaq -0x278(%rbp), %rdi
callq 0x5ea0
jmp 0x5862
movq -0x398(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0x3270
jmp 0x5877
leaq -0x278(%rbp), %rdi
callq 0x31c0
leaq -0x258(%rbp), %rdi
leaq -0xcc(%rbp), %rsi
callq 0x31b0
jmp 0x5898
jmp 0x595b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x58c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x278(%rbp), %rdi
callq 0x31c0
movl -0x64(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5a27
movq -0x60(%rbp), %rdi
callq 0x30e0
movq %rax, -0x280(%rbp)
movq 0xa6e6(%rip), %rdi      # 0xffd0
leaq 0x5793(%rip), %rsi      # 0xb084
callq 0x3290
movq %rax, -0x3a0(%rbp)
jmp 0x58ff
movq -0x280(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq -0x3a0(%rbp), %rdi
movq %rax, %rsi
callq 0x3290
movq %rax, -0x3a8(%rbp)
jmp 0x5927
movq -0x3a8(%rbp), %rdi
movq 0xa683(%rip), %rsi      # 0xffb8
callq 0x32d0
jmp 0x593c
xorl %edi, %edi
callq 0x3320
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x3420
jmp 0x5956
jmp 0x5a27
movq -0x378(%rbp), %rsi
movl -0xcc(%rbp), %edx
leaq -0x2a0(%rbp), %rdi
callq 0x6420
jmp 0x5976
leaq -0x38(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
movq %rsi, -0x3b8(%rbp)
callq 0x3330
movq -0x3b8(%rbp), %rdi
callq 0x31c0
movq 0xa630(%rip), %rdi      # 0xffd0
leaq 0x572d(%rip), %rsi      # 0xb0d4
callq 0x3290
movq %rax, -0x3b0(%rbp)
jmp 0x59b5
movq -0x3b0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3270
movq %rax, -0x3c0(%rbp)
jmp 0x59ce
movq -0x3c0(%rbp), %rdi
leaq 0x5707(%rip), %rsi      # 0xb0e3
callq 0x3290
movq %rax, -0x3c8(%rbp)
jmp 0x59ea
movq -0x3c8(%rbp), %rdi
movq 0xa5c0(%rip), %rsi      # 0xffb8
callq 0x32d0
jmp 0x59ff
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
leaq -0x258(%rbp), %rdi
callq 0x3220
jmp 0x5e57
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x258(%rbp), %rdi
callq 0x3220
jmp 0x5e79
movq -0x378(%rbp), %rax
movq %rax, -0x3d0(%rbp)
leaq -0x2c0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3100
jmp 0x5a58
movq -0x3d0(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x4100
movb %al, -0x3d1(%rbp)
jmp 0x5a73
leaq -0x2c0(%rbp), %rdi
callq 0x31c0
movb -0x3d1(%rbp), %al
testb $0x1, %al
jne 0x5a8e
jmp 0x5d88
leaq 0x5583(%rip), %rsi      # 0xb018
leaq -0x58(%rbp), %rdi
callq 0x80e0
movb %al, -0x3d2(%rbp)
jmp 0x5aa6
movb -0x3d2(%rbp), %al
testb $0x1, %al
jne 0x5ab5
jmp 0x5d74
leaq 0x5558(%rip), %rsi      # 0xb014
leaq -0x58(%rbp), %rdi
callq 0x80e0
movb %al, -0x3d3(%rbp)
jmp 0x5acd
movb -0x3d3(%rbp), %al
testb $0x1, %al
jne 0x5adc
jmp 0x5d74
leaq 0x554c(%rip), %rsi      # 0xb02f
leaq -0x58(%rbp), %rdi
callq 0x80e0
movb %al, -0x3d4(%rbp)
jmp 0x5af4
movb -0x3d4(%rbp), %al
testb $0x1, %al
jne 0x5b03
jmp 0x5d74
leaq 0x5529(%rip), %rsi      # 0xb033
leaq -0x58(%rbp), %rdi
callq 0x80e0
movb %al, -0x3d5(%rbp)
jmp 0x5b1b
movb -0x3d5(%rbp), %al
testb $0x1, %al
jne 0x5b2a
jmp 0x5d74
movq -0x378(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0x2e0(%rbp), %rdi
callq 0x5ea0
jmp 0x5b43
leaq -0x2e0(%rbp), %rdi
leaq 0x5594(%rip), %rsi      # 0xb0e5
xorl %eax, %eax
movl %eax, %edx
callq 0x34c0
cmpq $-0x1, %rax
jne 0x5c57
leaq -0x320(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3100
jmp 0x5b76
leaq -0x340(%rbp), %rdi
leaq -0x2e0(%rbp), %rsi
callq 0x3100
jmp 0x5b8b
movq -0x378(%rbp), %rsi
leaq -0x300(%rbp), %rdi
leaq -0x320(%rbp), %rdx
leaq -0x340(%rbp), %rcx
callq 0x6460
jmp 0x5bae
leaq -0x38(%rbp), %rdi
leaq -0x300(%rbp), %rsi
callq 0x3330
leaq -0x300(%rbp), %rdi
callq 0x31c0
leaq -0x340(%rbp), %rdi
callq 0x31c0
leaq -0x320(%rbp), %rdi
callq 0x31c0
jmp 0x5c57
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0x31c0
jmp 0x5e79
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5cda
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5cce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5c49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x340(%rbp), %rdi
callq 0x31c0
leaq -0x320(%rbp), %rdi
callq 0x31c0
jmp 0x5cce
movq 0xa372(%rip), %rdi      # 0xffd0
leaq 0x546f(%rip), %rsi      # 0xb0d4
callq 0x3290
movq %rax, -0x3e0(%rbp)
jmp 0x5c73
movq -0x3e0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x3270
movq %rax, -0x3e8(%rbp)
jmp 0x5c8c
movq -0x3e8(%rbp), %rdi
leaq 0x5449(%rip), %rsi      # 0xb0e3
callq 0x3290
movq %rax, -0x3f0(%rbp)
jmp 0x5ca8
movq -0x3f0(%rbp), %rdi
movq 0xa302(%rip), %rsi      # 0xffb8
callq 0x32d0
jmp 0x5cbd
leaq -0x2e0(%rbp), %rdi
callq 0x31c0
jmp 0x5d72
leaq -0x2e0(%rbp), %rdi
callq 0x31c0
movl -0x64(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5e79
movq -0x60(%rbp), %rdi
callq 0x30e0
movq %rax, -0x348(%rbp)
movq 0xa2cf(%rip), %rdi      # 0xffd0
leaq 0x537c(%rip), %rsi      # 0xb084
callq 0x3290
movq %rax, -0x3f8(%rbp)
jmp 0x5d16
movq -0x348(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq -0x3f8(%rbp), %rdi
movq %rax, %rsi
callq 0x3290
movq %rax, -0x400(%rbp)
jmp 0x5d3e
movq -0x400(%rbp), %rdi
movq 0xa26c(%rip), %rsi      # 0xffb8
callq 0x32d0
jmp 0x5d53
xorl %edi, %edi
callq 0x3320
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x3420
jmp 0x5d6d
jmp 0x5e79
jmp 0x5d74
movq -0x18(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
jmp 0x5e55
movb $0x1, -0x36a(%rbp)
movl $0x28, %edi
callq 0x3140
movq %rax, -0x410(%rbp)
leaq -0x369(%rbp), %rdi
movq %rdi, -0x408(%rbp)
callq 0x3460
movq -0x408(%rbp), %rdx
leaq 0x5326(%rip), %rsi      # 0xb0e7
leaq -0x368(%rbp), %rdi
callq 0x7630
jmp 0x5dcf
movq -0x410(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x8040
jmp 0x5de4
movq -0x410(%rbp), %rdi
movb $0x0, -0x36a(%rbp)
leaq 0x9f67(%rip), %rsi      # 0xfd60
leaq 0x2200(%rip), %rdx      # 0x8000
callq 0x3430
jmp 0x5e9c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x5e30
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x368(%rbp), %rdi
callq 0x31c0
leaq -0x369(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x36a(%rbp)
jne 0x5e47
jmp 0x5e53
movq -0x410(%rbp), %rdi
callq 0x3210
jmp 0x5e79
jmp 0x5e57
movl $0x0, -0x68(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x31c0
leaq -0x38(%rbp), %rdi
callq 0x31c0
addq $0x410, %rsp            # imm = 0x410
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x31c0
leaq -0x38(%rbp), %rdi
callq 0x31c0
movq -0x60(%rbp), %rdi
callq 0x3450
movq %rax, %rdi
callq 0x7fd0
nopl (%rax)