// File: vssense[P]Compiler/src/front-end/dot_dump.h
// Function: PrintNodes(Tree*, Node*, _IO_FILE*)
void PrintNodes(Tree* tree, Node* node, FILE* dump_file)
{
    assert(tree);
    assert(dump_file);

    switch (node->type)
    {
        case D_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#EBF7F7\", label=\"D_TYPE | %s",
                    node, "fict");
    
            if (node->value.is_void)
            {
                fprintf(dump_file, " | void");
            }

            fprintf(dump_file, "\"]");

            break;
        }
        case DECL_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"DECL_TYPE | %s\"]",
                    node, "=");
            break;
        }
        case ADECL_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#BC8E27\", label=\"ADECL_TYPE | %s\"]",
                    node, "[]");
            break;
        }
        case ID_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"ID_TYPE | %s\"]",
                    node, node->value.name);

            break;
        }
        case ARG_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#F0F5F1\", label=\"ARG_TYPE | %s\"]",
                    node, "arg");
            break;
        }
        case COMP_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"COMP_TYPE | %s\"]",
                    node, "comp");
            break;
        }
        case STAT_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#A2F39D\", label=\"STAT_TYPE | %s\"]",
                    node, "S");
            break;
        }
        case COND_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#F3DF9D\", label=\"COND_TYPE | %s\"]",
                    node, "if");
            break;
        }
        case IFEL_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#F3DF9D\", label=\"IFEL_TYPE | %s\"]",
                    node, "if-else");
            break;
        }
        case LOOP_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#AEDEE8\", label=\"LOOP_TYPE | %s\"]",
                    node, "while");
            break;
        }
        case ASSG_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"ASSG_TYPE | %s\"]",
                    node, "=");
            break;
        }
        case CALL_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#AEE8C5\", label=\"CALL_TYPE | %s\"]",
                    node, "call");
            break;
        }
        case JUMP_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#BC8ED7\", label=\"JUMP_TYPE | %s\"]",
                    node, "return");
            break;
        }
        case MATH_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"MATH_TYPE | %s\"]",
                    node, MathToString(node->value.op));
            break;
        }
        case NUMB_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#C0F5F1\", label=\"NUMB_TYPE | %d\"]",
                    node, node->value.number);
            break;
        }
        case MEM_ACCESS_TYPE :
        {
            fprintf(dump_file, "\"%p\"[style=\"filled\", fillcolor=\"#BC8E27\", label=\"MEM_ACCESS_TYPE | %s\"]",
                    node, "[]");
            break;
        }
        default : 
        {
            printf("Unknown type = %d\n", node->type);
            break;
        }
    }

    if (node->left != nullptr)
    {
        fprintf(dump_file, "\"%p\":sw->\"%p\";\n", node, node->left);
        PrintNodes(tree, node->left, dump_file);
    }
    
    if (node->right != nullptr)
    {
        fprintf(dump_file, "\"%p\":se->\"%p\";\n", node, node->right);
        PrintNodes(tree, node->right, dump_file);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x741d
jmp 0x743c
leaq 0x387f(%rip), %rdi      # 0xaca3
leaq 0x4627(%rip), %rsi      # 0xba52
movl $0x42, %edx
leaq 0x465f(%rip), %rcx      # 0xba96
callq 0x20a0
cmpq $0x0, -0x18(%rbp)
je 0x7445
jmp 0x7464
leaq 0x4672(%rip), %rdi      # 0xbabe
leaq 0x45ff(%rip), %rsi      # 0xba52
movl $0x43, %edx
leaq 0x4637(%rip), %rcx      # 0xba96
callq 0x20a0
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x20(%rbp)
subq $0xf, %rax
ja 0x76ea
movq -0x20(%rbp), %rax
leaq 0x4535(%rip), %rcx      # 0xb9b8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x462d(%rip), %rsi      # 0xbac8
leaq 0x4663(%rip), %rcx      # 0xbb05
movb $0x0, %al
callq 0x2160
movq -0x10(%rbp), %rax
testb $0x1, 0x8(%rax)
je 0x74c5
movq -0x18(%rbp), %rdi
leaq 0x464c(%rip), %rsi      # 0xbb0a
movb $0x0, %al
callq 0x2160
movq -0x18(%rbp), %rdi
leaq 0x4a04(%rip), %rsi      # 0xbed4
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4627(%rip), %rsi      # 0xbb12
leaq 0x4491(%rip), %rcx      # 0xb983
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4647(%rip), %rsi      # 0xbb54
leaq 0x4683(%rip), %rcx      # 0xbb97
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rcx
leaq 0x4663(%rip), %rsi      # 0xbb9a
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4688(%rip), %rsi      # 0xbbda
leaq 0x46c2(%rip), %rcx      # 0xbc1b
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x46ab(%rip), %rsi      # 0xbc1f
leaq 0x46e6(%rip), %rcx      # 0xbc61
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x46d0(%rip), %rsi      # 0xbc66
leaq 0x470b(%rip), %rcx      # 0xbca8
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x46f2(%rip), %rsi      # 0xbcaa
leaq 0x472d(%rip), %rcx      # 0xbcec
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4715(%rip), %rsi      # 0xbcef
leaq 0x4750(%rip), %rcx      # 0xbd31
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x473d(%rip), %rsi      # 0xbd39
leaq 0x4778(%rip), %rcx      # 0xbd7b
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4763(%rip), %rsi      # 0xbd81
leaq 0x435e(%rip), %rcx      # 0xb983
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x4783(%rip), %rsi      # 0xbdc3
leaq 0x47be(%rip), %rcx      # 0xbe05
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x47a8(%rip), %rsi      # 0xbe0a
leaq 0x47e3(%rip), %rcx      # 0xbe4c
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edi
callq 0x71b0
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rdx
movq %rax, %rcx
leaq 0x47b0(%rip), %rsi      # 0xbe53
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
leaq 0x47d3(%rip), %rsi      # 0xbe95
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x47fd(%rip), %rsi      # 0xbed7
leaq 0x44b6(%rip), %rcx      # 0xbb97
movb $0x0, %al
callq 0x2160
jmp 0x76fe
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq 0x4828(%rip), %rdi      # 0xbf1f
movb $0x0, %al
callq 0x2040
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x773c
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
leaq 0x4812(%rip), %rsi      # 0xbf32
movb $0x0, %al
callq 0x2160
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x7400
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x777a
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rcx
leaq 0x47e4(%rip), %rsi      # 0xbf42
movb $0x0, %al
callq 0x2160
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x18(%rbp), %rdx
callq 0x7400
addq $0x30, %rsp
popq %rbp
retq