// File: KJTang[P]SimpleCompiler/Assembler.cpp
// Function: Assembler::init()
bool Assembler::init() {
    std::istringstream iss(asmcode);
    std::string curToken;
    while (iss>>curToken) {
        auto it = this->opList.find(curToken);
        if (it == opList.end()) {
            // Label
            if (curToken[curToken.size()-1] == ':') {
                this->labelMap.insert(std::make_pair(curToken.substr(0, curToken.size()-1), line));
                continue;
            }
            // Invalid Operator
            std::cout<<"Invalid Operator: "<<curToken<<std::endl;
            return false;
        }
        Instruction newIns;
        newIns.opName = curToken;   // TODO: only used for test here, delete this later
        newIns.op = (*it).second.first;
        std::string arg;
        for (int i = 0; i != (*it).second.second; i++) {
            iss>>arg;    
            newIns.args.push_back(arg);
            ++line;
        }
        this->instructions.push_back(newIns);
        ++line;
        // function declaration
        if (newIns.op == OP::FUNC) {
            this->funcMap.insert(std::make_pair(newIns.args[0], line));
        }
        // variable declaration
        if (newIns.op == OP::INT) {
            this->varMap.insert(std::make_pair(newIns.args[0], varID++));
        }
    }
    this->instructions.push_back({"CALL", OP::CALL, std::vector<std::string> {"main"}});
    this->instructions.push_back({"EXIT", OP::EXIT, std::vector<std::string> {}});
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x510, %rsp            # imm = 0x510
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rsi
movq %rsi, -0x3e8(%rbp)
leaq -0x190(%rbp), %rdi
movl $0x8, %edx
callq 0x3430
leaq -0x1b0(%rbp), %rdi
callq 0x33a0
leaq -0x190(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x3350
movq %rax, -0x3f0(%rbp)
jmp 0x14203
movq -0x3f0(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3340
movb %al, -0x3f1(%rbp)
jmp 0x14221
movb -0x3f1(%rbp), %al
testb $0x1, %al
jne 0x14230
jmp 0x1473c
movq -0x3e8(%rbp), %rdi
addq $0x40, %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x15420
movq %rax, -0x400(%rbp)
jmp 0x14250
movq -0x3e8(%rbp), %rdi
movq -0x400(%rbp), %rax
movq %rax, -0x1c8(%rbp)
addq $0x40, %rdi
callq 0x15450
movq %rax, -0x1d0(%rbp)
leaq -0x1c8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x7c50
testb $0x1, %al
jne 0x14291
jmp 0x1444e
leaq -0x1b0(%rbp), %rdi
movq %rdi, -0x410(%rbp)
callq 0x3200
movq -0x410(%rbp), %rdi
movq %rax, %rsi
decq %rsi
callq 0x34e0
movq %rax, -0x408(%rbp)
jmp 0x142bf
movq -0x408(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3a, %eax
jne 0x143ee
movq -0x3e8(%rbp), %rax
addq $0x90, %rax
movq %rax, -0x420(%rbp)
leaq -0x1b0(%rbp), %rdi
movq %rdi, -0x418(%rbp)
callq 0x3200
movq -0x418(%rbp), %rsi
movq %rax, %rcx
decq %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x218(%rbp), %rdi
callq 0x32c0
jmp 0x14318
movq -0x3e8(%rbp), %rdx
addq $0x88, %rdx
leaq -0x1f8(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x154c0
jmp 0x1433b
movq -0x420(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x15480
movb %dl, -0x429(%rbp)
movq %rax, -0x428(%rbp)
jmp 0x1435d
movb -0x429(%rbp), %al
movq -0x428(%rbp), %rcx
movq %rcx, -0x228(%rbp)
movb %al, -0x220(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x15500
leaq -0x218(%rbp), %rdi
callq 0x34f8
jmp 0x141e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x14b36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x143dd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x15500
leaq -0x218(%rbp), %rdi
callq 0x34f8
jmp 0x14b36
movq 0x13bdb(%rip), %rdi     # 0x27fd0
leaq 0x70a8(%rip), %rsi      # 0x1b4a4
callq 0x3280
movq %rax, -0x438(%rbp)
jmp 0x1440a
movq -0x438(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x3250
movq %rax, -0x440(%rbp)
jmp 0x14426
movq -0x440(%rbp), %rdi
movq 0x13b84(%rip), %rsi     # 0x27fb8
callq 0x32e0
jmp 0x1443b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x22c(%rbp)
jmp 0x14b10
leaq -0x270(%rbp), %rdi
movq %rdi, -0x448(%rbp)
callq 0x15520
movq -0x448(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x3060
jmp 0x14476
leaq -0x1c8(%rbp), %rdi
callq 0x15550
movl 0x20(%rax), %eax
movl %eax, -0x250(%rbp)
leaq -0x290(%rbp), %rdi
callq 0x33a0
movl $0x0, -0x294(%rbp)
movl -0x294(%rbp), %eax
movl %eax, -0x44c(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x15550
movq %rax, %rcx
movl -0x44c(%rbp), %eax
cmpl 0x24(%rcx), %eax
je 0x14546
leaq -0x190(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x3350
jmp 0x144dc
leaq -0x248(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0x15580
jmp 0x144f1
movq -0x3e8(%rbp), %rax
movl 0x88(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x88(%rax)
movl -0x294(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x294(%rbp)
jmp 0x144a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x1472b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x1471f
movq -0x3e8(%rbp), %rdi
addq $0x70, %rdi
leaq -0x270(%rbp), %rsi
callq 0x155f0
jmp 0x1455f
movq -0x3e8(%rbp), %rax
movl 0x88(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x88(%rax)
cmpl $0x18, -0x250(%rbp)
jne 0x14632
movq -0x3e8(%rbp), %rax
addq $0xc0, %rax
movq %rax, -0x458(%rbp)
leaq -0x248(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x156a0
movq -0x3e8(%rbp), %rdx
movq %rax, %rsi
addq $0x88, %rdx
leaq -0x2c0(%rbp), %rdi
callq 0x15660
jmp 0x145c5
movq -0x458(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x15480
movb %dl, -0x461(%rbp)
movq %rax, -0x460(%rbp)
jmp 0x145e7
movb -0x461(%rbp), %al
movq -0x460(%rbp), %rcx
movq %rcx, -0x2d0(%rbp)
movb %al, -0x2c8(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0x15500
jmp 0x14632
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
leaq -0x2c0(%rbp), %rdi
callq 0x15500
jmp 0x1471f
cmpl $0x14, -0x250(%rbp)
jne 0x14702
movq -0x3e8(%rbp), %rax
addq $0xf0, %rax
movq %rax, -0x470(%rbp)
leaq -0x248(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x156a0
movq -0x3e8(%rbp), %rcx
movq %rax, %rsi
movl 0x8c(%rcx), %eax
movl %eax, %edx
incl %edx
movl %edx, 0x8c(%rcx)
movl %eax, -0x2fc(%rbp)
leaq -0x2f8(%rbp), %rdi
leaq -0x2fc(%rbp), %rdx
callq 0x156c0
jmp 0x14698
movq -0x470(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
callq 0x15480
movb %dl, -0x479(%rbp)
movq %rax, -0x478(%rbp)
jmp 0x146ba
movb -0x479(%rbp), %al
movq -0x478(%rbp), %rcx
movq %rcx, -0x310(%rbp)
movb %al, -0x308(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x15500
jmp 0x14702
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x15500
jmp 0x1471f
leaq -0x290(%rbp), %rdi
callq 0x34f8
leaq -0x270(%rbp), %rdi
callq 0x87c0
jmp 0x141e7
leaq -0x290(%rbp), %rdi
callq 0x34f8
leaq -0x270(%rbp), %rdi
callq 0x87c0
jmp 0x14b36
movq -0x3e8(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x498(%rbp)
leaq -0x350(%rbp), %rax
movq %rax, -0x490(%rbp)
leaq -0x351(%rbp), %rdi
movq %rdi, -0x488(%rbp)
callq 0x3480
movq -0x490(%rbp), %rdi
movq -0x488(%rbp), %rdx
leaq 0x68ee(%rip), %rsi      # 0x1b072
callq 0x3390
jmp 0x1478b
movb $0x1, -0x394(%rbp)
movl $0x17, -0x330(%rbp)
leaq -0x328(%rbp), %rax
movq %rax, -0x4b0(%rbp)
movb $0x1, -0x392(%rbp)
leaq -0x388(%rbp), %rax
movq %rax, -0x4a8(%rbp)
movq %rax, -0x390(%rbp)
leaq -0x391(%rbp), %rdi
movq %rdi, -0x4a0(%rbp)
callq 0x3480
movq -0x4a8(%rbp), %rdi
movq -0x4a0(%rbp), %rdx
leaq 0x6cc9(%rip), %rsi      # 0x1b4b7
callq 0x3390
jmp 0x147f5
movb $0x0, -0x392(%rbp)
leaq -0x388(%rbp), %rax
movq %rax, -0x368(%rbp)
movq $0x1, -0x360(%rbp)
leaq -0x393(%rbp), %rdi
movq %rdi, -0x4b8(%rbp)
callq 0x15730
movq -0x4b0(%rbp), %rdi
movq -0x4b8(%rbp), %rcx
movq -0x368(%rbp), %rsi
movq -0x360(%rbp), %rdx
callq 0x15750
jmp 0x1484b
movq -0x498(%rbp), %rdi
movb $0x0, -0x394(%rbp)
leaq -0x350(%rbp), %rsi
callq 0x15700
jmp 0x14867
leaq -0x350(%rbp), %rdi
callq 0x87c0
leaq -0x393(%rbp), %rdi
callq 0x8a20
leaq -0x388(%rbp), %rax
movq %rax, -0x4c8(%rbp)
addq $0x20, %rax
movq %rax, -0x4c0(%rbp)
movq -0x4c0(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x4d0(%rbp)
callq 0x34f8
movq -0x4c8(%rbp), %rcx
movq -0x4d0(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x4c0(%rbp)
jne 0x14898
leaq -0x391(%rbp), %rdi
callq 0x3300
leaq -0x351(%rbp), %rdi
callq 0x3300
movq -0x3e8(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x4e0(%rbp)
leaq -0x3d9(%rbp), %rdi
movq %rdi, -0x4d8(%rbp)
callq 0x3480
movq -0x4d8(%rbp), %rdx
leaq 0x6704(%rip), %rsi      # 0x1b018
leaq -0x3d8(%rbp), %rdi
callq 0x3390
jmp 0x14922
movl $0x0, -0x3b8(%rbp)
leaq -0x3b0(%rbp), %rdi
xorps %xmm0, %xmm0
movups %xmm0, -0x3b0(%rbp)
movq $0x0, -0x3a0(%rbp)
callq 0x157d0
movq -0x4e0(%rbp), %rdi
leaq -0x3d8(%rbp), %rsi
callq 0x15700
jmp 0x14962
leaq -0x3d8(%rbp), %rdi
callq 0x87c0
leaq -0x3d9(%rbp), %rdi
callq 0x3300
movb $0x1, -0x1(%rbp)
movl $0x1, -0x22c(%rbp)
jmp 0x14b10
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x14ac2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x14a45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x149ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x87c0
leaq -0x393(%rbp), %rdi
callq 0x8a20
leaq -0x388(%rbp), %rax
movq %rax, -0x4f0(%rbp)
addq $0x20, %rax
movq %rax, -0x4e8(%rbp)
movq -0x4e8(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x4f8(%rbp)
callq 0x34f8
movq -0x4f0(%rbp), %rcx
movq -0x4f8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x4e8(%rbp)
jne 0x14a12
jmp 0x14a45
leaq -0x391(%rbp), %rdi
callq 0x3300
testb $0x1, -0x392(%rbp)
jne 0x14a5c
jmp 0x14aa9
movq -0x390(%rbp), %rax
leaq -0x388(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x500(%rbp)
je 0x14aa7
movq -0x500(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x508(%rbp)
callq 0x34f8
movq -0x508(%rbp), %rax
leaq -0x388(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x500(%rbp)
jne 0x14a76
jmp 0x14aa9
testb $0x1, -0x394(%rbp)
jne 0x14ab4
jmp 0x14ac0
movq -0x490(%rbp), %rdi
callq 0x34f8
jmp 0x14ac2
leaq -0x351(%rbp), %rdi
callq 0x3300
jmp 0x14b36
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
jmp 0x14b02
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b8(%rbp)
movl %eax, -0x1bc(%rbp)
leaq -0x3d8(%rbp), %rdi
callq 0x87c0
leaq -0x3d9(%rbp), %rdi
callq 0x3300
jmp 0x14b36
leaq -0x1b0(%rbp), %rdi
callq 0x34f8
leaq -0x190(%rbp), %rdi
callq 0x3150
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x510, %rsp            # imm = 0x510
popq %rbp
retq
leaq -0x1b0(%rbp), %rdi
callq 0x34f8
leaq -0x190(%rbp), %rdi
callq 0x3150
movq -0x1b8(%rbp), %rdi
callq 0x3470
nopw (%rax,%rax)