// File: /workspace/github_cpp_makefile_star2_O3/SunriseFox[P]very-simple-c-compiler/./src/main.cpp
// Function: showTree(TreeNode*)
void showTree(TreeNode* root) {

    if (root == nullptr) return;

    auto children = root -> child;
    while (children) {
        showTree(children);
        children = children -> sibling;
    }
    Symbol* ownSymbol = nullptr;

    cout << "(Line " << root -> lineno << ") " << root->nodeID << ": ";
    switch (root->nodeType) {
    case TreeNode::NODE_NONE:
        cout << "[Unknown] ";
        break;
    case TreeNode::NODE_STATMENT:
        cout << "[Statement ";
        switch (static_cast<StatementNode*>(root)->type) {
        case StatementNode::ST_NONE:
            cout << "Unknown";
            break;
        case StatementNode::ST_EMPTY:
            cout << "Empty";
            break;
        case StatementNode::ST_SCOPE:
            cout << "Scope";
            break;
        case StatementNode::ST_RET:
            cout << "Return";
            break;
        case StatementNode::ST_DO_WHILE:
            cout << "Do-While";
            break;
        case StatementNode::ST_WHILE:
            cout << "While";
            break;
        case StatementNode::ST_FOR:
            cout << "For";
            break;
        case StatementNode::ST_FUNCTION:
            cout << "Function<";
            cout << static_cast<FuncStatementNode*>(root)->symbol->value << ">";
            break;
        case StatementNode::ST_IF:
            cout << "If";
            break;
        case StatementNode::ST_IF_ELSE:
            cout << "If-Else";
            break;
        case StatementNode::ST_BREAK:
            cout << "Break";
            break;
        case StatementNode::ST_CONTINUE:
            cout << "Continue";
            break;
        case StatementNode::ST_GOTO:
            cout << "Goto";
            break;
        }
        cout << "]";
        break;

    case TreeNode::NODE_FUNCCALL:
        cout << "[FuncCall<";
        ownSymbol = static_cast<DeclarationNode*>(root)->symbol;
        cout << Symbol::getSymbolName(ownSymbol);
        cout << "> " <<static_cast<DeclarationNode*>(root)->symbol->value << "] ";
        break;

    case TreeNode::NODE_DECLARATION:
        cout << "[Declaration<";
        // fall through
        [[clang::fallthrough]];
    case TreeNode::NODE_EXPRESSION:
        if(root->nodeType == TreeNode::NODE_EXPRESSION)
            cout << "[Expression<";

        ownSymbol = static_cast<DeclarationNode*>(root)->symbol;

        cout << Symbol::getSymbolName(ownSymbol);

        cout << "> " <<static_cast<DeclarationNode*>(root)->symbol->value << "] ";
        break;

    case TreeNode::NODE_OPERATOR:
        ownSymbol = root->symbol = new OpNode(root->child->symbol->type, "");
        cout << "[Operator ";
        cout << OperatorNode::getTypeStr(static_cast<OperatorNode*>(root)->type);
        cout << " <";
        cout << Symbol::getSymbolName(ownSymbol);
        cout << ">]";
        switch (static_cast<OperatorNode*>(root)->type) {
        case OperatorNode::OP_ASSIGN:
        case OperatorNode::OP_ADDAS:
        case OperatorNode::OP_SUBAS:
        case OperatorNode::OP_MULAS:
        case OperatorNode::OP_DIVAS:
        case OperatorNode::OP_BORAS:
        case OperatorNode::OP_BANDAS:
        case OperatorNode::OP_BXORAS:
        case OperatorNode::OP_LSHFTAS:
        case OperatorNode::OP_RSHFTAS:
        default: break;
        }
        break;
    }
    children = root -> child;
    if(children) {
        cout << endl << "\tChildren: ";
    }
    while (children) {
        cout << children->nodeID << " ";
        children = children -> sibling;
    }
    cout << endl;
    children = root -> child;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
testq %rdi, %rdi
je 0x84ff
movq %rdi, %r14
movq 0x18(%rdi), %rbx
testq %rbx, %rbx
je 0x8039
movq %rbx, %rdi
callq 0x8008
movq 0x20(%rbx), %rbx
jmp 0x8026
movq 0xaf80(%rip), %rbx      # 0x12fc0
leaq 0x5661(%rip), %rsi      # 0xd6a8
movl $0x6, %edx
movq %rbx, %rdi
callq 0x3260
movl 0xc(%r14), %esi
movq %rbx, %rdi
callq 0x33a0
movq %rax, %r15
leaq 0x5645(%rip), %rsi      # 0xd6af
movl $0x2, %edx
movq %rax, %rdi
callq 0x3260
movl 0x8(%r14), %esi
movq %r15, %rdi
callq 0x33a0
leaq 0x56e9(%rip), %rsi      # 0xd773
movl $0x2, %edx
movq %rax, %rdi
callq 0x3260
movl 0x10(%r14), %eax
cmpq $0x5, %rax
ja 0x8468
leaq 0x55b0(%rip), %rcx      # 0xd65c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xaf04(%rip), %rdi      # 0x12fc0
leaq 0x55ef(%rip), %rsi      # 0xd6b2
movl $0xa, %edx
jmp 0x8463
movl $0x30, %edi
callq 0x31f0
movq %rax, %r15
movq 0x18(%r14), %rax
movq 0x28(%rax), %rax
movl (%rax), %ebp
leaq 0x38(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x52c1(%rip), %rdx      # 0xd3b6
leaq 0x28(%rsp), %rdi
movq %rdx, %rsi
callq 0x7944
leaq 0x28(%rsp), %rdx
movq %r15, %rdi
movl %ebp, %esi
callq 0xbf60
movq %r15, 0x28(%r14)
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x812c
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xae8d(%rip), %r12      # 0x12fc0
leaq 0x5609(%rip), %rsi      # 0xd743
movl $0xa, %edx
movq %r12, %rdi
callq 0x3260
movl 0x30(%r14), %esi
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0xc2a4
movq (%r13), %rsi
movq 0x8(%r13), %rdx
movq %r12, %rdi
callq 0x3260
leaq 0x18(%rsp), %rbp
movq -0x10(%rbp), %rdi
cmpq %rbp, %rdi
je 0x8183
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xae36(%rip), %r12      # 0x12fc0
leaq 0x55bd(%rip), %rsi      # 0xd74e
movl $0x2, %edx
movq %r12, %rdi
callq 0x3260
leaq 0x8(%rsp), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0xbcb8
movq (%r13), %rsi
movq 0x8(%r13), %rdx
movq %r12, %rdi
callq 0x3260
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x81d5
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xade4(%rip), %rdi      # 0x12fc0
leaq 0x556e(%rip), %rsi      # 0xd751
movl $0x2, %edx
jmp 0x8463
movq 0xadcc(%rip), %rdi      # 0x12fc0
leaq 0x552d(%rip), %rsi      # 0xd728
movl $0xd, %edx
callq 0x3260
cmpl $0x3, 0x10(%r14)
jne 0x8224
movq 0xadad(%rip), %rdi      # 0x12fc0
leaq 0x551c(%rip), %rsi      # 0xd736
movl $0xc, %edx
callq 0x3260
movq 0x28(%r14), %rsi
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0xbcb8
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq 0xad7d(%rip), %rdi      # 0x12fc0
callq 0x3260
jmp 0x82d3
movq 0xad6c(%rip), %rdi      # 0x12fc0
leaq 0x5462(%rip), %rsi      # 0xd6bd
movl $0xb, %edx
callq 0x3260
movl 0x30(%r14), %eax
cmpq $0xc, %rax
ja 0x8450
leaq 0x53fa(%rip), %rcx      # 0xd674
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xad36(%rip), %rdi      # 0x12fc0
leaq 0x5438(%rip), %rsi      # 0xd6c9
jmp 0x8446
movq 0xad23(%rip), %r15      # 0x12fc0
leaq 0x5476(%rip), %rsi      # 0xd71a
movl $0xa, %edx
movq %r15, %rdi
callq 0x3260
movq 0x28(%r14), %rsi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
callq 0xbcb8
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %r15, %rdi
callq 0x3260
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x82ee
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xaccb(%rip), %r15      # 0x12fc0
leaq 0x5429(%rip), %rsi      # 0xd725
movl $0x2, %edx
movq %r15, %rdi
callq 0x3260
movq 0x28(%r14), %rax
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
movq %r15, %rdi
callq 0x3260
leaq 0x5396(%rip), %rsi      # 0xd6ba
movl $0x2, %edx
movq %rax, %rdi
jmp 0x8463
movq 0xac88(%rip), %rdi      # 0x12fc0
leaq 0x53d6(%rip), %rsi      # 0xd715
movl $0x4, %edx
jmp 0x844b
movq 0xac70(%rip), %rdi      # 0x12fc0
leaq 0x538d(%rip), %rsi      # 0xd6e4
jmp 0x8431
movq 0xac5d(%rip), %r15      # 0x12fc0
leaq 0x5387(%rip), %rsi      # 0xd6f1
movl $0x9, %edx
movq %r15, %rdi
callq 0x3260
movq 0x28(%r14), %rax
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
movq %r15, %rdi
callq 0x3260
leaq 0x7153(%rip), %rsi      # 0xf4e5
movl $0x1, %edx
movq %rax, %rdi
jmp 0x844b
movq 0xac1a(%rip), %rdi      # 0x12fc0
leaq 0x5359(%rip), %rsi      # 0xd706
jmp 0x8407
movq 0xac0a(%rip), %rdi      # 0x12fc0
leaq 0x531a(%rip), %rsi      # 0xd6d7
jmp 0x8407
movq 0xabfa(%rip), %rdi      # 0x12fc0
leaq 0x5310(%rip), %rsi      # 0xd6dd
movl $0x6, %edx
jmp 0x844b
movq 0xabe5(%rip), %rdi      # 0x12fc0
leaq 0x5319(%rip), %rsi      # 0xd6fb
movl $0x2, %edx
jmp 0x844b
movq 0xabd0(%rip), %rdi      # 0x12fc0
leaq 0x52da(%rip), %rsi      # 0xd6d1
jmp 0x8407
movq 0xabc0(%rip), %rdi      # 0x12fc0
leaq 0x52e0(%rip), %rsi      # 0xd6e7
movl $0x5, %edx
jmp 0x844b
movq 0xabab(%rip), %rdi      # 0x12fc0
leaq 0x52d1(%rip), %rsi      # 0xd6ed
movl $0x3, %edx
jmp 0x844b
movq 0xab96(%rip), %rdi      # 0x12fc0
leaq 0x52db(%rip), %rsi      # 0xd70c
movl $0x8, %edx
jmp 0x844b
movq 0xab81(%rip), %rdi      # 0x12fc0
leaq 0x52b8(%rip), %rsi      # 0xd6fe
movl $0x7, %edx
callq 0x3260
movq 0xab69(%rip), %rdi      # 0x12fc0
leaq 0x52f4(%rip), %rsi      # 0xd752
movl $0x1, %edx
callq 0x3260
movq 0x18(%r14), %r15
testq %r15, %r15
je 0x84d8
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x31d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3150
leaq 0x52b5(%rip), %rsi      # 0xd754
movl $0xb, %edx
movq %rax, %rdi
callq 0x3260
leaq 0x51fd(%rip), %r14      # 0xd6b0
movl 0x8(%r15), %esi
movq %rbx, %rdi
callq 0x33a0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3260
movq 0x20(%r15), %r15
testq %r15, %r15
jne 0x84b3
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x31d0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3150
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
jne 0x855b
jmp 0x8568
jmp 0x854a
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x8540
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3200
jmp 0x8540
jmp 0x854a
movq %rax, %rbx
movl $0x30, %esi
movq %r15, %rdi
jmp 0x8563
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8568
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq %rbx, %rdi
callq 0x33d0