// File: /workspace/github_cpp_makefile_star2_O3/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 $0x258, %rsp            # imm = 0x258
movq %rdi, %r14
leaq -0x280(%rbp), %rdi
movq %r14, %rsi
movl $0x8, %edx
callq 0x3310
leaq -0xa8(%rbp), %rax
movq %rax, -0x10(%rax)
movq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x40(%r14), %rax
movq %rax, -0x100(%rbp)
leaq 0x48(%r14), %rax
movq %rax, -0xf8(%rbp)
leaq -0x68(%rbp), %r13
leaq 0x70(%r14), %rax
movq %rax, -0x98(%rbp)
leaq 0xc0(%r14), %rax
movq %rax, -0xe8(%rbp)
leaq 0xf0(%r14), %rax
movq %rax, -0xe0(%rbp)
leaq 0x90(%r14), %rax
movq %rax, -0xf0(%rbp)
leaq -0xd8(%rbp), %r12
leaq -0x280(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x3260
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x20(%rax,%rcx), %r15d
testb $0x5, %r15b
jne 0xbc8a
movq -0x100(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xc44e
movq %rax, %rbx
cmpq -0xf8(%rbp), %rax
je 0xbbc5
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
xorl %eax, %eax
movq %rax, -0x88(%rbp)
movb $0x0, -0x80(%rbp)
movq %rax, 0x10(%r13)
xorps %xmm0, %xmm0
movups %xmm0, (%r13)
leaq -0x90(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x3130
movl 0x40(%rbx), %eax
movl %eax, -0x70(%rbp)
leaq -0xc8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq $0x0, -0xd0(%rbp)
movb $0x0, -0xc8(%rbp)
cmpl $0x0, 0x44(%rbx)
je 0xbac7
xorl %r15d, %r15d
leaq -0x280(%rbp), %rdi
movq %r12, %rsi
callq 0x3260
movq %r13, %rdi
movq %r12, %rsi
callq 0xc35c
incl 0x88(%r14)
incl %r15d
cmpl 0x44(%rbx), %r15d
jne 0xba9d
movq -0x98(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xc3a8
incl 0x88(%r14)
movl -0x70(%rbp), %eax
cmpl $0x18, %eax
jne 0xbb39
movq -0x68(%rbp), %rax
leaq -0x40(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq -0x50(%rbp), %rbx
movq %rbx, %rdi
callq 0x42b0
movl 0x88(%r14), %eax
movl %eax, -0x30(%rbp)
movq -0xe8(%rbp), %rdi
movq %rbx, %rsi
callq 0xc4ec
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbb36
callq 0x31c0
movl -0x70(%rbp), %eax
cmpl $0x14, %eax
jne 0xbb95
movq -0x68(%rbp), %rax
movl 0x8c(%r14), %ebx
leal 0x1(%rbx), %ecx
movl %ecx, 0x8c(%r14)
leaq -0x40(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq -0x50(%rbp), %r15
movq %r15, %rdi
callq 0x42b0
movl %ebx, -0x30(%rbp)
movq -0xe0(%rbp), %rdi
movq %r15, %rsi
callq 0xc4ec
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbb95
callq 0x31c0
movq -0xd8(%rbp), %rdi
leaq -0xc8(%rbp), %rax
cmpq %rax, %rdi
je 0xbbad
callq 0x31c0
movq %r13, %rdi
callq 0x4dcc
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
jmp 0xbc77
movq -0xb8(%rbp), %rax
movq -0xb0(%rbp), %rcx
cmpb $0x3a, -0x1(%rax,%rcx)
jne 0xbd94
decq %rcx
leaq -0x50(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
xorl %edx, %edx
callq 0x3200
leaq -0x80(%rbp), %rcx
movq %rcx, -0x90(%rbp)
movq -0x50(%rbp), %rax
leaq -0x40(%rbp), %rdx
cmpq %rdx, %rax
je 0xbc1c
movq %rax, -0x90(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0xbc22
movups (%rdx), %xmm0
movups %xmm0, (%rcx)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
movq %rdx, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movb $0x0, -0x40(%rbp)
movl 0x88(%r14), %eax
movl %eax, -0x70(%rbp)
movq -0xf0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xc4ec
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0xbc6f
callq 0x31c0
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xb9eb
callq 0x31c0
jmp 0xb9eb
leaq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
movq %rax, (%rdi)
leaq 0x33fd(%rip), %rsi      # 0xf09c
leaq 0x33fa(%rip), %rdx      # 0xf0a0
callq 0x47d0
movl $0x17, -0x70(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
movq %rax, (%rdi)
leaq 0x368f(%rip), %rsi      # 0xf353
leaq 0x368c(%rip), %rdx      # 0xf357
callq 0x47d0
leaq -0x68(%rbp), %rbx
leaq -0x50(%rbp), %rsi
leaq -0xd8(%rbp), %rcx
movl $0x1, %edx
movq %rbx, %rdi
callq 0xc40c
leaq -0x90(%rbp), %rsi
movq -0x98(%rbp), %rdi
callq 0xce3c
movq %rbx, %rdi
callq 0x4dcc
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0xbd1c
callq 0x31c0
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbd2e
callq 0x31c0
leaq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
movq %rax, (%rdi)
leaq 0x32ff(%rip), %rsi      # 0xf042
leaq 0x32fc(%rip), %rdx      # 0xf046
callq 0x47d0
leaq -0x90(%rbp), %rsi
movl $0x0, 0x20(%rsi)
xorps %xmm0, %xmm0
movups %xmm0, 0x28(%rsi)
movq $0x0, 0x38(%rsi)
movq -0x98(%rbp), %rdi
callq 0xce3c
movq %rbx, %rdi
callq 0x4dcc
movq -0x28(%rbx), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0xbdf0
callq 0x31c0
jmp 0xbdf0
movq 0x8235(%rip), %rdi      # 0x13fd0
leaq 0x359e(%rip), %rsi      # 0xf340
movl $0x12, %edx
callq 0x3230
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rdx
movq 0x820f(%rip), %rdi      # 0x13fd0
callq 0x3230
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x31d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3150
movq -0xb8(%rbp), %rdi
leaq -0xa8(%rbp), %rax
cmpq %rax, %rdi
je 0xbe08
callq 0x31c0
testb $0x5, %r15b
setne %bl
movq 0x81aa(%rip), %rsi      # 0x13fc0
leaq -0x280(%rbp), %rdi
callq 0x3290
leaq -0x208(%rbp), %rdi
callq 0x30c0
movl %ebx, %eax
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xbee3
jmp 0xbeea
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0xc3e0
xorl %r14d, %r14d
jmp 0xbe66
movq %rax, %rbx
movb $0x1, %r14b
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbe78
callq 0x31c0
testb %r14b, %r14b
jne 0xbe85
jmp 0xbf16
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
jmp 0xbed3
jmp 0xbeea
jmp 0xbeea
jmp 0xbe9a
jmp 0xbeef
movq %rax, %rbx
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbef2
callq 0x31c0
jmp 0xbef2
jmp 0xbeef
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0xbecb
callq 0x31c0
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rax
cmpq %rax, %rdi
je 0xbf16
callq 0x31c0
jmp 0xbf16
jmp 0xbeea
jmp 0xbeef
movq %rax, %rbx
jmp 0xbf0a
jmp 0xbeea
movq %rax, %rbx
jmp 0xbf16
movq %rax, %rbx
movq -0xd8(%rbp), %rdi
leaq -0xc8(%rbp), %rax
cmpq %rax, %rdi
je 0xbf0a
callq 0x31c0
leaq -0x90(%rbp), %rdi
callq 0xc3e0
movq -0xb8(%rbp), %rdi
leaq -0xa8(%rbp), %rax
cmpq %rax, %rdi
je 0xbf2e
callq 0x31c0
movq 0x808b(%rip), %rsi      # 0x13fc0
leaq -0x280(%rbp), %rdi
callq 0x3290
leaq -0x208(%rbp), %rdi
callq 0x30c0
movq %rbx, %rdi
callq 0x3330
nop