// File: /workspace/github_cpp_makefile_star2_O1/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 0x84f7
movq %rdi, %r14
movq 0x18(%rdi), %rbx
testq %rbx, %rbx
je 0x8031
movq %rbx, %rdi
callq 0x8000
movq 0x20(%rbx), %rbx
jmp 0x801e
movq 0xaf88(%rip), %rbx      # 0x12fc0
leaq 0x5669(%rip), %rsi      # 0xd6a8
movl $0x6, %edx
movq %rbx, %rdi
callq 0x3260
movl 0xc(%r14), %esi
movq %rbx, %rdi
callq 0x33a0
movq %rax, %r15
leaq 0x564d(%rip), %rsi      # 0xd6af
movl $0x2, %edx
movq %rax, %rdi
callq 0x3260
movl 0x8(%r14), %esi
movq %r15, %rdi
callq 0x33a0
leaq 0x56f1(%rip), %rsi      # 0xd773
movl $0x2, %edx
movq %rax, %rdi
callq 0x3260
movl 0x10(%r14), %eax
cmpq $0x5, %rax
ja 0x8460
leaq 0x55b8(%rip), %rcx      # 0xd65c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xaf0c(%rip), %rdi      # 0x12fc0
leaq 0x55f7(%rip), %rsi      # 0xd6b2
movl $0xa, %edx
jmp 0x845b
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 0x52c9(%rip), %rdx      # 0xd3b6
leaq 0x28(%rsp), %rdi
movq %rdx, %rsi
callq 0x7948
leaq 0x28(%rsp), %rdx
movq %r15, %rdi
movl %ebp, %esi
callq 0xc0d4
movq %r15, 0x28(%r14)
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x8124
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xae95(%rip), %r12      # 0x12fc0
leaq 0x5611(%rip), %rsi      # 0xd743
movl $0xa, %edx
movq %r12, %rdi
callq 0x3260
movl 0x30(%r14), %esi
leaq 0x8(%rsp), %r13
movq %r13, %rdi
callq 0xc440
movq (%r13), %rsi
movq 0x8(%r13), %rdx
movq %r12, %rdi
callq 0x3260
leaq 0x18(%rsp), %rbp
movq -0x10(%rbp), %rdi
cmpq %rbp, %rdi
je 0x817b
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xae3e(%rip), %r12      # 0x12fc0
leaq 0x55c5(%rip), %rsi      # 0xd74e
movl $0x2, %edx
movq %r12, %rdi
callq 0x3260
leaq 0x8(%rsp), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0xbe2c
movq (%r13), %rsi
movq 0x8(%r13), %rdx
movq %r12, %rdi
callq 0x3260
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x81cd
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xadec(%rip), %rdi      # 0x12fc0
leaq 0x5576(%rip), %rsi      # 0xd751
movl $0x2, %edx
jmp 0x845b
movq 0xadd4(%rip), %rdi      # 0x12fc0
leaq 0x5535(%rip), %rsi      # 0xd728
movl $0xd, %edx
callq 0x3260
cmpl $0x3, 0x10(%r14)
jne 0x821c
movq 0xadb5(%rip), %rdi      # 0x12fc0
leaq 0x5524(%rip), %rsi      # 0xd736
movl $0xc, %edx
callq 0x3260
movq 0x28(%r14), %rsi
leaq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0xbe2c
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq 0xad85(%rip), %rdi      # 0x12fc0
callq 0x3260
jmp 0x82cb
movq 0xad74(%rip), %rdi      # 0x12fc0
leaq 0x546a(%rip), %rsi      # 0xd6bd
movl $0xb, %edx
callq 0x3260
movl 0x30(%r14), %eax
cmpq $0xc, %rax
ja 0x8448
leaq 0x5402(%rip), %rcx      # 0xd674
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xad3e(%rip), %rdi      # 0x12fc0
leaq 0x5440(%rip), %rsi      # 0xd6c9
jmp 0x843e
movq 0xad2b(%rip), %r15      # 0x12fc0
leaq 0x547e(%rip), %rsi      # 0xd71a
movl $0xa, %edx
movq %r15, %rdi
callq 0x3260
movq 0x28(%r14), %rsi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
callq 0xbe2c
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %r15, %rdi
callq 0x3260
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x82e6
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq 0xacd3(%rip), %r15      # 0x12fc0
leaq 0x5431(%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 0x539e(%rip), %rsi      # 0xd6ba
movl $0x2, %edx
movq %rax, %rdi
jmp 0x845b
movq 0xac90(%rip), %rdi      # 0x12fc0
leaq 0x53de(%rip), %rsi      # 0xd715
movl $0x4, %edx
jmp 0x8443
movq 0xac78(%rip), %rdi      # 0x12fc0
leaq 0x5395(%rip), %rsi      # 0xd6e4
jmp 0x8429
movq 0xac65(%rip), %r15      # 0x12fc0
leaq 0x538f(%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 0x715b(%rip), %rsi      # 0xf4e5
movl $0x1, %edx
movq %rax, %rdi
jmp 0x8443
movq 0xac22(%rip), %rdi      # 0x12fc0
leaq 0x5361(%rip), %rsi      # 0xd706
jmp 0x83ff
movq 0xac12(%rip), %rdi      # 0x12fc0
leaq 0x5322(%rip), %rsi      # 0xd6d7
jmp 0x83ff
movq 0xac02(%rip), %rdi      # 0x12fc0
leaq 0x5318(%rip), %rsi      # 0xd6dd
movl $0x6, %edx
jmp 0x8443
movq 0xabed(%rip), %rdi      # 0x12fc0
leaq 0x5321(%rip), %rsi      # 0xd6fb
movl $0x2, %edx
jmp 0x8443
movq 0xabd8(%rip), %rdi      # 0x12fc0
leaq 0x52e2(%rip), %rsi      # 0xd6d1
jmp 0x83ff
movq 0xabc8(%rip), %rdi      # 0x12fc0
leaq 0x52e8(%rip), %rsi      # 0xd6e7
movl $0x5, %edx
jmp 0x8443
movq 0xabb3(%rip), %rdi      # 0x12fc0
leaq 0x52d9(%rip), %rsi      # 0xd6ed
movl $0x3, %edx
jmp 0x8443
movq 0xab9e(%rip), %rdi      # 0x12fc0
leaq 0x52e3(%rip), %rsi      # 0xd70c
movl $0x8, %edx
jmp 0x8443
movq 0xab89(%rip), %rdi      # 0x12fc0
leaq 0x52c0(%rip), %rsi      # 0xd6fe
movl $0x7, %edx
callq 0x3260
movq 0xab71(%rip), %rdi      # 0x12fc0
leaq 0x52fc(%rip), %rsi      # 0xd752
movl $0x1, %edx
callq 0x3260
movq 0x18(%r14), %r15
testq %r15, %r15
je 0x84d0
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 0x52bd(%rip), %rsi      # 0xd754
movl $0xb, %edx
movq %rax, %rdi
callq 0x3260
leaq 0x5205(%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 0x84ab
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 0x8553
jmp 0x8560
jmp 0x8542
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x8538
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3200
jmp 0x8538
jmp 0x8542
movq %rax, %rbx
movl $0x30, %esi
movq %r15, %rdi
jmp 0x855b
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8560
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3200
movq %rbx, %rdi
callq 0x33d0