// File: SunriseFox[P]very-simple-c-compiler/./src/asm.cpp
// Function: generateCode(TreeNode*)
void generateCode(TreeNode* node) {
    if (node == nullptr) return;

    Symbol* ownSymbol = nullptr;
    string reg;

    if (node->nodeType == TreeNode::NODE_STATMENT) {
        StatementNode* stnode = static_cast<StatementNode*>(node);
        if (stnode->type == StatementNode::ST_IF_ELSE
                || stnode->type == StatementNode::ST_IF) {
            handleIf(stnode);
        } else if (stnode->type == StatementNode::ST_WHILE) {
            handleWhile(stnode);
        } else if (stnode->type == StatementNode::ST_FOR) {
            handleFor(stnode);
        }  else if (stnode->type == StatementNode::ST_FUNCTION) {
            handleFunctionNode(node);
        } else if (stnode->type == StatementNode::ST_RET) {
            reg = handleExprNode(stnode->child);
            of << "\tmovl\t" << reg << ", %eax\n";
            of << "\tleave\n";
            of << "\tret\n";
        } else if (static_cast<StatementNode*>(node)->type == StatementNode::ST_SCOPE) {
            handleCodeBlock(node);
        }
    }

    else if (node->nodeType == TreeNode::NODE_DECLARATION) {
        ownSymbol = static_cast<DeclarationNode*>(node)->symbol;
        if (!node->child) return;
        switch (ownSymbol->type) {
        case Symbol::VALUE_INT:
        case Symbol::VALUE_CHAR:
            reg = handleExprNode(node->child);
            of << "\tmovl\t" << reg << ", " << getSymbolMemory(ownSymbol) << "\n";
            return;
        case Symbol::VALUE_STRING:
            varDeclare[static_cast<DeclarationNode*>(node)->symbol] = varDeclare[node->child->symbol];
            return;
        default:
            cerr << "could not handle type" << endl;
            return;
        }
    }

    else if (node->nodeType == TreeNode::NODE_FUNCCALL) {
        handleFuncCall(node);
    }

    else if (node->nodeType == TreeNode::NODE_OPERATOR
             || node->nodeType == TreeNode::NODE_EXPRESSION) {
        handleExprNode(node);
    }

    else {
        cerr << "+++++ ignoring node !" << endl;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x536b
jmp 0x578a
movq $0x0, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x3390
movq -0x8(%rbp), %rax
cmpl $0x1, 0x10(%rax)
jne 0x54f2
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpl $0x8, 0x30(%rax)
je 0x53a6
movq -0x38(%rbp), %rax
cmpl $0x7, 0x30(%rax)
jne 0x53c7
movq -0x38(%rbp), %rdi
callq 0x7fb0
jmp 0x53b1
jmp 0x54ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5793
movq -0x38(%rbp), %rax
cmpl $0x5, 0x30(%rax)
jne 0x53e1
movq -0x38(%rbp), %rdi
callq 0x7ac0
jmp 0x53dc
jmp 0x54eb
movq -0x38(%rbp), %rax
cmpl $0x6, 0x30(%rax)
jne 0x53fb
movq -0x38(%rbp), %rdi
callq 0x7cf0
jmp 0x53f6
jmp 0x54e9
movq -0x38(%rbp), %rax
cmpl $0xc, 0x30(%rax)
jne 0x5415
movq -0x8(%rbp), %rdi
callq 0x7900
jmp 0x5410
jmp 0x54e7
movq -0x38(%rbp), %rax
cmpl $0x3, 0x30(%rax)
jne 0x54cc
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rsi
leaq -0x68(%rbp), %rdi
callq 0x5fd0
jmp 0x5436
leaq -0x30(%rbp), %rdi
leaq -0x68(%rbp), %rsi
movq %rsi, -0xe0(%rbp)
callq 0x3340
movq -0xe0(%rbp), %rdi
callq 0x3180
leaq 0x1be93(%rip), %rdi     # 0x212f0
leaq 0x11e75(%rip), %rsi     # 0x172d9
callq 0x3240
movq %rax, -0xd8(%rbp)
jmp 0x5472
movq -0xd8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3230
movq %rax, -0xe8(%rbp)
jmp 0x548b
movq -0xe8(%rbp), %rdi
leaq 0x11f90(%rip), %rsi     # 0x17429
callq 0x3240
jmp 0x54a0
leaq 0x1be49(%rip), %rdi     # 0x212f0
leaq 0x11f83(%rip), %rsi     # 0x17431
callq 0x3240
jmp 0x54b5
leaq 0x1be34(%rip), %rdi     # 0x212f0
leaq 0x11f76(%rip), %rsi     # 0x17439
callq 0x3240
jmp 0x54ca
jmp 0x54e5
movq -0x8(%rbp), %rax
cmpl $0x2, 0x30(%rax)
jne 0x54e3
movq -0x8(%rbp), %rdi
callq 0x52f0
jmp 0x54e1
jmp 0x54e3
jmp 0x54e5
jmp 0x54e7
jmp 0x54e9
jmp 0x54eb
jmp 0x54ed
jmp 0x577a
movq -0x8(%rbp), %rax
cmpl $0x2, 0x10(%rax)
jne 0x56f6
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x5523
movl $0x1, -0x6c(%rbp)
jmp 0x5781
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xec(%rbp)
subl $0x2, %eax
je 0x5558
jmp 0x5536
movl -0xec(%rbp), %eax
subl $0x4, %eax
je 0x565a
jmp 0x5547
movl -0xec(%rbp), %eax
subl $0x5, %eax
jne 0x56b9
jmp 0x5558
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
leaq -0x90(%rbp), %rdi
callq 0x5fd0
jmp 0x556e
leaq -0x30(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movq %rsi, -0x100(%rbp)
callq 0x3340
movq -0x100(%rbp), %rdi
callq 0x3180
leaq 0x1bd58(%rip), %rdi     # 0x212f0
leaq 0x11d3a(%rip), %rsi     # 0x172d9
callq 0x3240
movq %rax, -0xf8(%rbp)
jmp 0x55ad
movq -0xf8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x3230
movq %rax, -0x108(%rbp)
jmp 0x55c6
movq -0x108(%rbp), %rdi
leaq 0x11dc3(%rip), %rsi     # 0x17397
callq 0x3240
movq %rax, -0x110(%rbp)
jmp 0x55e2
movq -0x10(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0x4c80
jmp 0x55f4
movq -0x110(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x3230
movq %rax, -0x118(%rbp)
jmp 0x5610
movq -0x118(%rbp), %rdi
leaq 0x11ec6(%rip), %rsi     # 0x174e4
callq 0x3240
jmp 0x5625
leaq -0xb0(%rbp), %rdi
callq 0x3180
movl $0x1, -0x6c(%rbp)
jmp 0x5781
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x3180
jmp 0x5793
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
addq $0x28, %rsi
leaq 0x1bc53(%rip), %rdi     # 0x212c0
callq 0x89c0
movq %rax, -0x120(%rbp)
jmp 0x567b
movq -0x8(%rbp), %rsi
addq $0x28, %rsi
leaq 0x1bc36(%rip), %rdi     # 0x212c0
callq 0x89c0
movq %rax, -0x128(%rbp)
jmp 0x5698
movq -0x120(%rbp), %rsi
movq -0x128(%rbp), %rdi
callq 0x3040
jmp 0x56ad
movl $0x1, -0x6c(%rbp)
jmp 0x5781
movq 0x1b930(%rip), %rdi     # 0x20ff0
leaq 0x11d85(%rip), %rsi     # 0x1744c
callq 0x3240
movq %rax, -0x130(%rbp)
jmp 0x56d5
movq -0x130(%rbp), %rdi
movq 0x1b8c5(%rip), %rsi     # 0x20fa8
callq 0x3290
jmp 0x56ea
movl $0x1, -0x6c(%rbp)
jmp 0x5781
movq -0x8(%rbp), %rax
cmpl $0x5, 0x10(%rax)
jne 0x570d
movq -0x8(%rbp), %rdi
callq 0x57b0
jmp 0x570b
jmp 0x5776
movq -0x8(%rbp), %rax
cmpl $0x4, 0x10(%rax)
je 0x5721
movq -0x8(%rbp), %rax
cmpl $0x3, 0x10(%rax)
jne 0x5741
movq -0x8(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x5fd0
jmp 0x5733
leaq -0xd0(%rbp), %rdi
callq 0x3180
jmp 0x5774
movq 0x1b8a8(%rip), %rdi     # 0x20ff0
leaq 0x11d13(%rip), %rsi     # 0x17462
callq 0x3240
movq %rax, -0x138(%rbp)
jmp 0x575d
movq -0x138(%rbp), %rdi
movq 0x1b83d(%rip), %rsi     # 0x20fa8
callq 0x3290
jmp 0x5772
jmp 0x5774
jmp 0x5776
jmp 0x5778
jmp 0x577a
movl $0x0, -0x6c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x3180
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x3180
movq -0x40(%rbp), %rdi
callq 0x3480
nopw %cs:(%rax,%rax)