// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
movq %rdi, %r14
leaq -0x290(%rbp), %rdi
pushq $0x8
popq %rdx
movq %r14, %rsi
callq 0x3330
leaq -0x88(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x40(%r14), %rax
movq %rax, -0xf0(%rbp)
leaq 0x48(%r14), %rax
movq %rax, -0xe8(%rbp)
leaq -0x50(%rbp), %r13
leaq 0x88(%r14), %rbx
leaq 0x70(%r14), %rax
movq %rax, -0x38(%rbp)
leaq 0xc0(%r14), %rax
movq %rax, -0xd0(%rbp)
leaq 0xf0(%r14), %rax
movq %rax, -0xc8(%rbp)
movq %r14, -0xd8(%rbp)
leaq 0x90(%r14), %rax
movq %rax, -0xe0(%rbp)
leaq -0x110(%rbp), %r12
leaq -0x290(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x3250
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x20(%rax,%rcx), %r15d
testb $0x5, %r15b
jne 0x921e
movq -0xf0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x9836
movq %rax, %r14
cmpq -0xe8(%rbp), %rax
je 0x91b4
leaq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
andq $0x0, -0x70(%rbp)
movb $0x0, -0x68(%rbp)
xorps %xmm0, %xmm0
movups %xmm0, (%r13)
andq $0x0, 0x10(%r13)
leaq -0x78(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x3140
movl 0x40(%r14), %eax
leaq -0x100(%rbp), %rcx
movq %rcx, -0x110(%rbp)
andq $0x0, -0x108(%rbp)
movl %eax, -0x58(%rbp)
movb $0x0, -0x100(%rbp)
xorl %r15d, %r15d
cmpl 0x44(%r14), %r15d
je 0x9109
leaq -0x290(%rbp), %rdi
movq %r12, %rsi
callq 0x3250
movq %r13, %rdi
movq %r12, %rsi
callq 0x9748
incl (%rbx)
incl %r15d
jmp 0x90e2
movq -0x38(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x9784
incl (%rbx)
movl -0x58(%rbp), %eax
cmpl $0x18, %eax
jne 0x9150
movq -0x50(%rbp), %rsi
leaq -0xc0(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rdx
callq 0x9818
movq -0xd0(%rbp), %rdi
movq %r14, %rsi
callq 0x98c0
movq %r14, %rdi
callq 0x33a8
movl -0x58(%rbp), %eax
cmpl $0x14, %eax
jne 0x919e
movq -0x50(%rbp), %rsi
movq -0xd8(%rbp), %rcx
movl 0x8c(%rcx), %r14d
leal 0x1(%r14), %eax
movl %eax, 0x8c(%rcx)
leaq -0xc0(%rbp), %r15
movq %r15, %rdi
callq 0x3290
movl %r14d, -0xa0(%rbp)
movq -0xc8(%rbp), %rdi
movq %r15, %rsi
callq 0x98c0
movq %r15, %rdi
callq 0x33a8
movq %r12, %rdi
callq 0x33a8
leaq -0x78(%rbp), %rdi
callq 0x4b50
jmp 0x9041
movq -0x98(%rbp), %rax
movq -0x90(%rbp), %rcx
cmpb $0x3a, -0x1(%rax,%rcx)
jne 0x92cb
decq %rcx
leaq -0xc0(%rbp), %r14
movq %r14, %rdi
leaq -0x98(%rbp), %rsi
xorl %edx, %edx
callq 0x3200
leaq -0x78(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x97fa
movq -0xe0(%rbp), %rdi
movq %r15, %rsi
callq 0x98c0
movq %r15, %rdi
callq 0x33a8
movq %r14, %rdi
callq 0x33a8
jmp 0x9041
leaq 0x2e4d(%rip), %rsi      # 0xc072
leaq -0x78(%rbp), %rdi
leaq -0x110(%rbp), %rdx
callq 0x30d0
movl $0x17, -0x58(%rbp)
leaq 0x30f0(%rip), %rsi      # 0xc333
leaq -0xc0(%rbp), %rdi
leaq -0x2a(%rbp), %rdx
callq 0x30d0
leaq -0x50(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
pushq $0x1
popq %rdx
leaq -0x29(%rbp), %rcx
callq 0x97c0
leaq -0x78(%rbp), %rsi
movq -0x38(%rbp), %rdi
callq 0xa0ee
leaq -0x78(%rbp), %rdi
callq 0x4b50
leaq -0xc0(%rbp), %rdi
callq 0x33a8
leaq 0x2d85(%rip), %rsi      # 0xc018
leaq -0x78(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x30d0
leaq -0x78(%rbp), %rsi
andl $0x0, 0x20(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x28(%rsi)
andq $0x0, 0x38(%rsi)
movq -0x38(%rbp), %rdi
callq 0xa0ee
leaq -0x78(%rbp), %rdi
callq 0x4b50
jmp 0x92f5
movq 0x8cfe(%rip), %rdi      # 0x11fd0
leaq 0x3047(%rip), %rsi      # 0xc320
callq 0x31d0
leaq -0x98(%rbp), %rsi
movq %rax, %rdi
callq 0x31b0
movq %rax, %rdi
callq 0x3110
testb $0x5, %r15b
setne %bl
leaq -0x98(%rbp), %rdi
callq 0x33a8
leaq -0x290(%rbp), %rdi
callq 0x3100
movl %ebx, %eax
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x9398
jmp 0x939f
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x4b50
xorl %r14d, %r14d
jmp 0x9343
movq %rax, %rbx
movb $0x1, %r14b
leaq -0xc0(%rbp), %rdi
callq 0x33a8
testb %r14b, %r14b
jne 0x9359
jmp 0x93bc
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
jmp 0x938d
jmp 0x939f
jmp 0x939f
jmp 0x9367
jmp 0x93a4
movq %rax, %rbx
leaq -0xc0(%rbp), %rdi
callq 0x33a8
jmp 0x93a7
jmp 0x93a4
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x33a8
leaq -0xc0(%rbp), %rdi
callq 0x33a8
jmp 0x93bc
jmp 0x939f
jmp 0x93a4
movq %rax, %rbx
jmp 0x93b3
jmp 0x939f
movq %rax, %rbx
jmp 0x93bc
movq %rax, %rbx
leaq -0x110(%rbp), %rdi
callq 0x33a8
leaq -0x78(%rbp), %rdi
callq 0x4b50
leaq -0x98(%rbp), %rdi
callq 0x33a8
leaq -0x290(%rbp), %rdi
callq 0x3100
movq %rbx, %rdi
callq 0x3350