// File: JameyWoo[P]csmile/assembly.cpp
// Function: genCalc(TreeNode*, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>)
void genCalc(TreeNode* calc, map<string, string> var2stack) {
    // TODO: 出了一个bug, 要注意, 相同优先级是要先左后右来计算的
    // TODO: 有 bug, 多重计算的时候, 寄存器会混淆
    // * 将计算结果保存到 %edx 中
    // * 递归地先将左值计算, 存储到%edx中, 将右值计算, 存储到%ecx中. %eax做暂时的中介.

    // debug("calc->nodekind: " + calc->nodekind);
    // debug("calc->op: " + calc->op);
    // 计算
    // debug("calc->child[1]->nodekind: " + calc->child[1]->nodekind);

    string left_loc;
    string right_loc;
    // 是否有左值也是表达式的情况?
    // 将左值放入 %eax
    if (calc->child[0]->nodekind == "MDOp" || calc->child[0]->nodekind == "PMOp") {
        genCalc(calc->child[0], var2stack);
        assout << "\tmovl\t%edx, %eax" << endl;
    } else if (calc->child[0]->nodekind == "Id") {
        left_loc = var2stack[calc->child[0]->name];
        assout << "\tmovl\t" << left_loc << ", %eax" << endl;
    } else if (calc->child[0]->nodekind == "Const") {
        left_loc = "$" + to_string(calc->child[1]->val);
        assout << "\tmovl\t" << left_loc << ", %eax" << endl;
    }
    left_loc = "%eax";

    // 如果是计算结点, 那么递归地调用, 得到的数放入寄存器 %ecx
    // 如果是 Id, 那么得到栈地址
    // 如果是 Const, 那么生成 $num
    if (calc->child[1]->nodekind == "MDOp" || calc->child[1]->nodekind == "PMOp") {
        genCalc(calc->child[1], var2stack);
        assout << "\tmovl\t%edx, %ecx" << endl;
        right_loc = "%ecx";
    } else if (calc->child[1]->nodekind == "Id") {
        right_loc = var2stack[calc->child[1]->name];
    } else if (calc->child[1]->nodekind == "Const") {
        right_loc = "$" + to_string(calc->child[1]->val);
    }
    if (calc->op == "/") {
        assout << "\tmovl\t" << left_loc << ", %eax" << endl
               << "\tmovl\t%eax, %edx" << endl
               << "\tsarl\t$31, %edx" << endl
               << "\tidivl\t" << right_loc << endl
               << "\tmovl\t%eax, %edx" << endl;
    } else {
        assout << "\tmovl\t" << left_loc << ", %edx" << endl;

        if (calc->op == "+") {
            assout << "\taddl\t" << right_loc << ", %edx" << endl;
        } else if (calc->op == "-") {
            assout << "\tsubl\t" << right_loc << ", %edx" << endl;
        } else if (calc->op == "*") {
            assout << "\timull\t" << right_loc << ", %edx" << endl;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rsi, -0x150(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x33b0
leaq -0x50(%rbp), %rdi
callq 0x33b0
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x30, %rdi
leaq 0x6911(%rip), %rsi      # 0x211ef
callq 0x5e70
movb %al, -0x141(%rbp)
jmp 0x1a8eb
movb -0x141(%rbp), %al
testb $0x1, %al
jne 0x1a925
jmp 0x1a8f7
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x30, %rdi
leaq 0x68eb(%rip), %rsi      # 0x211f4
callq 0x5e70
movb %al, -0x151(%rbp)
jmp 0x1a916
movb -0x151(%rbp), %al
testb $0x1, %al
jne 0x1a925
jmp 0x1a9cd
movq -0x150(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x160(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x1c040
jmp 0x1a948
movq -0x160(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x1a8a0
jmp 0x1a95d
leaq -0x90(%rbp), %rdi
callq 0xee40
leaq 0x14338(%rip), %rdi     # 0x2eca8
leaq 0x6e23(%rip), %rsi      # 0x2179a
callq 0x3270
movq %rax, -0x168(%rbp)
jmp 0x1a985
movq -0x168(%rbp), %rdi
movq 0x1361d(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1a99a
jmp 0x1abb9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x1b1be
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0xee40
jmp 0x1b1be
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x30, %rdi
leaq 0x67cd(%rip), %rsi      # 0x211ac
callq 0x5e70
movb %al, -0x169(%rbp)
jmp 0x1a9ec
movb -0x169(%rbp), %al
testb $0x1, %al
jne 0x1a9fb
jmp 0x1aa9b
movq -0x150(%rbp), %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rsi
addq $0xc0, %rsi
callq 0xf2e0
movq %rax, -0x178(%rbp)
jmp 0x1aa1e
movq -0x178(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x3050
jmp 0x1aa30
leaq 0x14271(%rip), %rdi     # 0x2eca8
leaq 0x6c58(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x180(%rbp)
jmp 0x1aa4c
movq -0x180(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3240
movq %rax, -0x188(%rbp)
jmp 0x1aa65
movq -0x188(%rbp), %rdi
leaq 0x6c49(%rip), %rsi      # 0x216bc
callq 0x3270
movq %rax, -0x190(%rbp)
jmp 0x1aa81
movq -0x190(%rbp), %rdi
movq 0x13521(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1aa96
jmp 0x1abb7
movq -0x8(%rbp), %rax
movq (%rax), %rdi
addq $0x30, %rdi
leaq 0x673c(%rip), %rsi      # 0x211e9
callq 0x5e70
movb %al, -0x191(%rbp)
jmp 0x1aaba
movb -0x191(%rbp), %al
testb $0x1, %al
jne 0x1aac9
jmp 0x1abb5
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0xb8(%rax), %esi
leaq -0xd0(%rbp), %rdi
callq 0xf460
jmp 0x1aae5
leaq 0x6c6b(%rip), %rsi      # 0x21757
leaq -0xb0(%rbp), %rdi
leaq -0xd0(%rbp), %rdx
callq 0xf410
jmp 0x1ab01
leaq -0x30(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
movq %rsi, -0x1a8(%rbp)
callq 0x3350
movq -0x1a8(%rbp), %rdi
callq 0x34e8
leaq -0xd0(%rbp), %rdi
callq 0x34e8
leaq 0x14171(%rip), %rdi     # 0x2eca8
leaq 0x6b58(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x1a0(%rbp)
jmp 0x1ab4c
movq -0x1a0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3240
movq %rax, -0x1b0(%rbp)
jmp 0x1ab65
movq -0x1b0(%rbp), %rdi
leaq 0x6b49(%rip), %rsi      # 0x216bc
callq 0x3270
movq %rax, -0x1b8(%rbp)
jmp 0x1ab81
movq -0x1b8(%rbp), %rdi
movq 0x13421(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1ab96
jmp 0x1abb5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x34e8
jmp 0x1b1be
jmp 0x1abb7
jmp 0x1abb9
leaq 0x6afe(%rip), %rsi      # 0x216be
leaq -0x30(%rbp), %rdi
callq 0x33a0
jmp 0x1abcb
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x30, %rdi
leaq 0x6611(%rip), %rsi      # 0x211ef
callq 0x5e70
movb %al, -0x1b9(%rbp)
jmp 0x1abeb
movb -0x1b9(%rbp), %al
testb $0x1, %al
jne 0x1ac26
jmp 0x1abf7
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x30, %rdi
leaq 0x65ea(%rip), %rsi      # 0x211f4
callq 0x5e70
movb %al, -0x1ba(%rbp)
jmp 0x1ac17
movb -0x1ba(%rbp), %al
testb $0x1, %al
jne 0x1ac26
jmp 0x1acd0
movq -0x150(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x1c8(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x1c040
jmp 0x1ac4a
movq -0x1c8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x1a8a0
jmp 0x1ac5f
leaq -0x100(%rbp), %rdi
callq 0xee40
leaq 0x14036(%rip), %rdi     # 0x2eca8
leaq 0x6b32(%rip), %rsi      # 0x217ab
callq 0x3270
movq %rax, -0x1d0(%rbp)
jmp 0x1ac87
movq -0x1d0(%rbp), %rdi
movq 0x1331b(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1ac9c
leaq 0x6b14(%rip), %rsi      # 0x217b7
leaq -0x50(%rbp), %rdi
callq 0x33a0
jmp 0x1acae
jmp 0x1ade6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0xee40
jmp 0x1b1be
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x30, %rdi
leaq 0x64c9(%rip), %rsi      # 0x211ac
callq 0x5e70
movb %al, -0x1d1(%rbp)
jmp 0x1acf0
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0x1acfc
jmp 0x1ad37
movq -0x150(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0xc0, %rsi
callq 0xf2e0
movq %rax, -0x1e0(%rbp)
jmp 0x1ad20
movq -0x1e0(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x3050
jmp 0x1ad32
jmp 0x1ade4
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x30, %rdi
leaq 0x649f(%rip), %rsi      # 0x211e9
callq 0x5e70
movb %al, -0x1e1(%rbp)
jmp 0x1ad57
movb -0x1e1(%rbp), %al
testb $0x1, %al
jne 0x1ad63
jmp 0x1ade2
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movl 0xb8(%rax), %esi
leaq -0x140(%rbp), %rdi
callq 0xf460
jmp 0x1ad7f
leaq 0x69d1(%rip), %rsi      # 0x21757
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rdx
callq 0xf410
jmp 0x1ad9b
leaq -0x50(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x3350
leaq -0x120(%rbp), %rdi
callq 0x34e8
leaq -0x140(%rbp), %rdi
callq 0x34e8
jmp 0x1ade2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x34e8
jmp 0x1b1be
jmp 0x1ade4
jmp 0x1ade6
movq -0x8(%rbp), %rdi
addq $0x98, %rdi
leaq 0x69c4(%rip), %rsi      # 0x217bc
callq 0x5e70
movb %al, -0x1e2(%rbp)
jmp 0x1ae05
movb -0x1e2(%rbp), %al
testb $0x1, %al
jne 0x1ae14
jmp 0x1af78
leaq 0x13e8d(%rip), %rdi     # 0x2eca8
leaq 0x6874(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x1f0(%rbp)
jmp 0x1ae30
movq -0x1f0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3240
movq %rax, -0x1f8(%rbp)
jmp 0x1ae49
movq -0x1f8(%rbp), %rdi
leaq 0x6865(%rip), %rsi      # 0x216bc
callq 0x3270
movq %rax, -0x200(%rbp)
jmp 0x1ae65
movq -0x200(%rbp), %rdi
movq 0x1313d(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq %rax, -0x208(%rbp)
jmp 0x1ae81
movq -0x208(%rbp), %rdi
leaq 0x692f(%rip), %rsi      # 0x217be
callq 0x3270
movq %rax, -0x210(%rbp)
jmp 0x1ae9d
movq -0x210(%rbp), %rdi
movq 0x13105(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq %rax, -0x218(%rbp)
jmp 0x1aeb9
movq -0x218(%rbp), %rdi
leaq 0x6908(%rip), %rsi      # 0x217cf
callq 0x3270
movq %rax, -0x220(%rbp)
jmp 0x1aed5
movq -0x220(%rbp), %rdi
movq 0x130cd(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq %rax, -0x228(%rbp)
jmp 0x1aef1
movq -0x228(%rbp), %rdi
leaq 0x68e0(%rip), %rsi      # 0x217df
callq 0x3270
movq %rax, -0x230(%rbp)
jmp 0x1af0d
movq -0x230(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3240
movq %rax, -0x238(%rbp)
jmp 0x1af26
movq -0x238(%rbp), %rdi
movq 0x1307c(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq %rax, -0x240(%rbp)
jmp 0x1af42
movq -0x240(%rbp), %rdi
leaq 0x686e(%rip), %rsi      # 0x217be
callq 0x3270
movq %rax, -0x248(%rbp)
jmp 0x1af5e
movq -0x248(%rbp), %rdi
movq 0x13044(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1af73
jmp 0x1b1a3
leaq 0x13d29(%rip), %rdi     # 0x2eca8
leaq 0x6710(%rip), %rsi      # 0x21696
callq 0x3270
movq %rax, -0x250(%rbp)
jmp 0x1af94
movq -0x250(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3240
movq %rax, -0x258(%rbp)
jmp 0x1afad
movq -0x258(%rbp), %rdi
leaq 0x681d(%rip), %rsi      # 0x217d8
callq 0x3270
movq %rax, -0x260(%rbp)
jmp 0x1afc9
movq -0x260(%rbp), %rdi
movq 0x12fd9(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1afde
movq -0x8(%rbp), %rdi
addq $0x98, %rdi
leaq 0x67f7(%rip), %rsi      # 0x217e7
callq 0x5e70
movb %al, -0x261(%rbp)
jmp 0x1affd
movb -0x261(%rbp), %al
testb $0x1, %al
jne 0x1b009
jmp 0x1b074
leaq 0x13c98(%rip), %rdi     # 0x2eca8
leaq 0x67d2(%rip), %rsi      # 0x217e9
callq 0x3270
movq %rax, -0x270(%rbp)
jmp 0x1b025
movq -0x270(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3240
movq %rax, -0x278(%rbp)
jmp 0x1b03e
movq -0x278(%rbp), %rdi
leaq 0x678c(%rip), %rsi      # 0x217d8
callq 0x3270
movq %rax, -0x280(%rbp)
jmp 0x1b05a
movq -0x280(%rbp), %rdi
movq 0x12f48(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1b06f
jmp 0x1b1a1
movq -0x8(%rbp), %rdi
addq $0x98, %rdi
leaq 0x6555(%rip), %rsi      # 0x215db
callq 0x5e70
movb %al, -0x281(%rbp)
jmp 0x1b093
movb -0x281(%rbp), %al
testb $0x1, %al
jne 0x1b09f
jmp 0x1b10a
leaq 0x13c02(%rip), %rdi     # 0x2eca8
leaq 0x6743(%rip), %rsi      # 0x217f0
callq 0x3270
movq %rax, -0x290(%rbp)
jmp 0x1b0bb
movq -0x290(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3240
movq %rax, -0x298(%rbp)
jmp 0x1b0d4
movq -0x298(%rbp), %rdi
leaq 0x66f6(%rip), %rsi      # 0x217d8
callq 0x3270
movq %rax, -0x2a0(%rbp)
jmp 0x1b0f0
movq -0x2a0(%rbp), %rdi
movq 0x12eb2(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1b105
jmp 0x1b19f
movq -0x8(%rbp), %rdi
addq $0x98, %rdi
leaq 0x66db(%rip), %rsi      # 0x217f7
callq 0x5e70
movb %al, -0x2a1(%rbp)
jmp 0x1b129
movb -0x2a1(%rbp), %al
testb $0x1, %al
jne 0x1b135
jmp 0x1b19d
leaq 0x13b6c(%rip), %rdi     # 0x2eca8
leaq 0x66b6(%rip), %rsi      # 0x217f9
callq 0x3270
movq %rax, -0x2b0(%rbp)
jmp 0x1b151
movq -0x2b0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x3240
movq %rax, -0x2b8(%rbp)
jmp 0x1b16a
movq -0x2b8(%rbp), %rdi
leaq 0x6660(%rip), %rsi      # 0x217d8
callq 0x3270
movq %rax, -0x2c0(%rbp)
jmp 0x1b186
movq -0x2c0(%rbp), %rdi
movq 0x12e1c(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0x1b19b
jmp 0x1b19d
jmp 0x1b19f
jmp 0x1b1a1
jmp 0x1b1a3
leaq -0x50(%rbp), %rdi
callq 0x34e8
leaq -0x30(%rbp), %rdi
callq 0x34e8
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
leaq -0x50(%rbp), %rdi
callq 0x34e8
leaq -0x30(%rbp), %rdi
callq 0x34e8
movq -0x58(%rbp), %rdi
callq 0x3470
nopl (%rax)