// File: JameyWoo[P]csmile/parse.cpp
// Function: preOrder(TreeNode*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void preOrder(TreeNode* t, string indent) {
    // if (t != NULL)
    //     out << "t->nodekind = " << t->nodekind << endl;
    if (t == NULL) {
        out << "NULL!" << endl;
        return;
    }
    if (t->nodekind == "FunDecl") {
        out << indent << "FunctionDeclaration {\n"
            << indent << "  type: FunctionDeclaration\n"
            << indent << "  id: " << t->child[1]->name << endl
            << indent << "  params: [\n";
        TreeNode* param = t->child[2]->child[0];
        while (param != NULL) {
            if (param->nodekind == "void") {
                out << indent << "    " << param->nodekind << endl;
            } else {
                out << indent << "    " << param->child[0]->nodekind << ": " << param->child[1]->name << endl;
            }
            param = param->sibling;
        }
        out << indent << "  ]\n"
            << indent << "  body: BlockStatement {\n"
            << indent << "    type: BlockStatement\n"
            << indent << "    body: [\n";
        preOrder(t->child[3], indent + "      ");
        out << indent << "    ]\n"
            << indent << "  }\n"
            << indent << "}\n";
        if (t->sibling != NULL) preOrder(t->sibling, indent);
        return;
    }
    if (t->nodekind == "Compound") {
        if (t->child[1] != NULL) {
            TreeNode* loc = t->child[0];
            out << indent << loc->nodekind << ":{\n";
            while (loc != NULL) {
                out << indent << "  " << loc->child[0]->nodekind << ": " << loc->child[1]->name << endl;
                loc = loc->sibling;
            }
            out << indent << "}\n";
        }
        TreeNode* stmt = NULL;
        if (t->child[1] == NULL) {
            stmt = t->child[0];
        } else
            stmt = t->child[1];
        while (stmt != NULL) {
            preOrder(stmt, indent);
            stmt = stmt->sibling;
        }
        return;
    }
    if (t->nodekind == "ReturnStmt") {
        out << indent << t->nodekind << ": {\n";
        preOrder(t->child[0], indent + "  ");
        out << indent << "}\n";
        return;
    }
    if (t->nodekind == "Id") {
        out << indent << t->nodekind << ": " << t->name << endl;
    } else if (t->nodekind == "Const") {
        out << indent << t->nodekind << ": " << t->val << endl;
    } else if (t->nodekind != "Input") {
        out << indent << t->nodekind << ": {\n";
    } else {  // ReturnStmt 会出现在这里输出
        out << indent << t->nodekind << endl;
    }

    for (int i = 0; i < MAX_CHILDREN; ++i) {
        // out << "i = " << i << endl;
        if (t->child[i] == NULL) break;
        blank += 2;
        if (i == 2 && t->nodekind == "Selection") {
            if (t->child[2] != NULL) {
                out << indent << "Else:\n";
            }
        }
        preOrder(t->child[i], indent + "  ");
        blank -= 2;
    }
    if (t->nodekind != "Id" && t->nodekind != "Input" && t->nodekind != "Const") {
        out << indent << "}\n";
    }
    // Assign 的sibling会重复
    // out << "t->nodekind = " << t->nodekind << endl;
    if (t->sibling != NULL) {
        if (t->nodekind != "Assign") {
            preOrder(t->sibling, indent);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rsi, -0x108(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0xcf28
leaq 0x216c8(%rip), %rdi     # 0x2e5d0
leaq 0x1432e(%rip), %rsi     # 0x2123d
callq 0x3270
movq %rax, %rdi
movq 0x21092(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0xd8b1
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x142fe(%rip), %rsi     # 0x21235
callq 0x5e70
testb $0x1, %al
jne 0xcf45
jmp 0xd288
movq -0x108(%rbp), %rsi
leaq 0x2167d(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x142e1(%rip), %rsi     # 0x21243
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x142da(%rip), %rsi     # 0x2125a
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x142d9(%rip), %rsi     # 0x21277
callq 0x3270
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20fec(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x1429c(%rip), %rsi     # 0x2127e
callq 0x3270
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0xd0d9
movq -0x18(%rbp), %rdi
addq $0x30, %rdi
leaq 0x140ec(%rip), %rsi     # 0x210fc
callq 0x5e70
testb $0x1, %al
jne 0xd01b
jmp 0xd05e
movq -0x108(%rbp), %rsi
leaq 0x215a7(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x14296(%rip), %rsi     # 0x212ce
callq 0x3270
movq %rax, %rdi
movq -0x18(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20f59(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0xd0c8
movq -0x108(%rbp), %rsi
leaq 0x21564(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x14253(%rip), %rsi     # 0x212ce
callq 0x3270
movq %rax, %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x141de(%rip), %rsi     # 0x2127b
callq 0x3270
movq %rax, %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20eed(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0xcff6
movq -0x108(%rbp), %rsi
leaq 0x214e9(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x141df(%rip), %rsi     # 0x212d5
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x14177(%rip), %rsi     # 0x2128b
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x14173(%rip), %rsi     # 0x212a5
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x1416f(%rip), %rsi     # 0x212bf
callq 0x3270
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x118(%rbp)
leaq 0x1415a(%rip), %rdx     # 0x212cc
leaq -0x38(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0xdc30
movq -0x118(%rbp), %rdi
movq -0x110(%rbp), %rsi
callq 0xcee0
jmp 0xd197
leaq -0x38(%rbp), %rdi
callq 0x34e8
movq -0x108(%rbp), %rsi
leaq 0x21422(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x14116(%rip), %rsi     # 0x212d3
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x140ff(%rip), %rsi     # 0x212da
callq 0x3270
movq -0x108(%rbp), %rsi
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
leaq 0x140e3(%rip), %rsi     # 0x212dc
callq 0x3270
movq -0x8(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0xd283
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x128(%rbp)
leaq -0x68(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x3120
movq -0x128(%rbp), %rdi
movq -0x120(%rbp), %rsi
callq 0xcee0
jmp 0xd244
leaq -0x68(%rbp), %rdi
callq 0x34e8
jmp 0xd283
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
jmp 0xd8b1
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13f8b(%rip), %rsi     # 0x21222
callq 0x5e70
testb $0x1, %al
jne 0xd2a5
jmp 0xd43d
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0xd392
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x70(%rbp)
leaq 0x21303(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x70(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x14006(%rip), %rsi     # 0x212f2
callq 0x3270
cmpq $0x0, -0x70(%rbp)
je 0xd370
movq -0x108(%rbp), %rsi
leaq 0x212ca(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x13fbb(%rip), %rsi     # 0x212d0
callq 0x3270
movq %rax, %rdi
movq -0x70(%rbp), %rax
movq (%rax), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x13f44(%rip), %rsi     # 0x2127b
callq 0x3270
movq %rax, %rdi
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20c53(%rip), %rsi     # 0x2dfb0
callq 0x32b0
movq -0x70(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x70(%rbp)
jmp 0xd2f1
movq -0x108(%rbp), %rsi
leaq 0x21252(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x13f4f(%rip), %rsi     # 0x212dc
callq 0x3270
movq $0x0, -0x78(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0xd3b2
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0xd3be
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0xd3c0
cmpq $0x0, -0x78(%rbp)
je 0xd438
movq -0x108(%rbp), %rsi
movq -0x78(%rbp), %rax
movq %rax, -0x138(%rbp)
leaq -0x98(%rbp), %rdi
movq %rdi, -0x130(%rbp)
callq 0x3120
movq -0x138(%rbp), %rdi
movq -0x130(%rbp), %rsi
callq 0xcee0
jmp 0xd401
leaq -0x98(%rbp), %rdi
callq 0x34e8
movq -0x78(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x78(%rbp)
jmp 0xd3c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
jmp 0xd8b1
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13dba(%rip), %rsi     # 0x21206
callq 0x5e70
testb $0x1, %al
jne 0xd45a
jmp 0xd520
movq -0x108(%rbp), %rsi
leaq 0x21168(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x13e58(%rip), %rsi     # 0x212df
callq 0x3270
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x148(%rbp)
leaq 0x13e28(%rip), %rdx     # 0x212d0
leaq -0xb8(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0xdc30
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rsi
callq 0xcee0
jmp 0xd4d0
leaq -0xb8(%rbp), %rdi
callq 0x34e8
movq -0x108(%rbp), %rsi
leaq 0x210e6(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x13de3(%rip), %rsi     # 0x212dc
callq 0x3270
jmp 0xd8b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13c7d(%rip), %rsi     # 0x211ac
callq 0x5e70
testb $0x1, %al
jne 0xd53a
jmp 0xd593
movq -0x108(%rbp), %rsi
leaq 0x21088(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x13d14(%rip), %rsi     # 0x2127b
callq 0x3270
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0xc0, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20a27(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0xd689
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13c47(%rip), %rsi     # 0x211e9
callq 0x5e70
testb $0x1, %al
jne 0xd5ad
jmp 0xd605
movq -0x108(%rbp), %rsi
leaq 0x21015(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x13ca1(%rip), %rsi     # 0x2127b
callq 0x3270
movq %rax, %rdi
movq -0x8(%rbp), %rax
movl 0xb8(%rax), %esi
callq 0x3460
movq %rax, %rdi
movq 0x209b5(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0xd687
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13be5(%rip), %rsi     # 0x211f9
callq 0xdad0
testb $0x1, %al
jne 0xd61f
jmp 0xd653
movq -0x108(%rbp), %rsi
leaq 0x20fa3(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
leaq 0x13c93(%rip), %rsi     # 0x212df
callq 0x3270
jmp 0xd685
movq -0x108(%rbp), %rsi
leaq 0x20f6f(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
movq -0x8(%rbp), %rsi
addq $0x30, %rsi
callq 0x3240
movq %rax, %rdi
movq 0x20930(%rip), %rsi     # 0x2dfb0
callq 0x32b0
jmp 0xd687
jmp 0xd689
movl $0x0, -0xbc(%rbp)
cmpl $0x4, -0xbc(%rbp)
jge 0xd7b0
movq -0x8(%rbp), %rax
movslq -0xbc(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0xd6b7
jmp 0xd7b0
movl 0x21117(%rip), %eax     # 0x2e7d4
addl $0x2, %eax
movl %eax, 0x2110e(%rip)     # 0x2e7d4
cmpl $0x2, -0xbc(%rbp)
jne 0xd718
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13ae3(%rip), %rsi     # 0x211c1
callq 0x5e70
testb $0x1, %al
jne 0xd6e9
jmp 0xd718
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0xd716
movq -0x108(%rbp), %rsi
leaq 0x20ece(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x13bd3(%rip), %rsi     # 0x212e4
callq 0x3270
jmp 0xd718
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movslq -0xbc(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x158(%rbp)
leaq 0x13b94(%rip), %rdx     # 0x212d0
leaq -0xe0(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0xdc30
movq -0x158(%rbp), %rdi
movq -0x150(%rbp), %rsi
callq 0xcee0
jmp 0xd764
leaq -0xe0(%rbp), %rdi
callq 0x34e8
movl 0x2105e(%rip), %eax     # 0x2e7d4
subl $0x2, %eax
movl %eax, 0x21055(%rip)     # 0x2e7d4
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0xd693
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x139ed(%rip), %rsi     # 0x211ac
callq 0xdad0
testb $0x1, %al
jne 0xd7ca
jmp 0xd820
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x13a20(%rip), %rsi     # 0x211f9
callq 0xdad0
testb $0x1, %al
jne 0xd7e4
jmp 0xd820
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x139f6(%rip), %rsi     # 0x211e9
callq 0xdad0
testb $0x1, %al
jne 0xd7fe
jmp 0xd820
movq -0x108(%rbp), %rsi
leaq 0x20dc4(%rip), %rdi     # 0x2e5d0
callq 0x3240
movq %rax, %rdi
leaq 0x13ac1(%rip), %rsi     # 0x212dc
callq 0x3270
movq -0x8(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0xd8b1
movq -0x8(%rbp), %rdi
addq $0x30, %rdi
leaq 0x139f0(%rip), %rsi     # 0x2122e
callq 0xdad0
testb $0x1, %al
jne 0xd849
jmp 0xd8af
movq -0x108(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x168(%rbp)
leaq -0x100(%rbp), %rdi
movq %rdi, -0x160(%rbp)
callq 0x3120
movq -0x168(%rbp), %rdi
movq -0x160(%rbp), %rsi
callq 0xcee0
jmp 0xd887
leaq -0x100(%rbp), %rdi
callq 0x34e8
jmp 0xd8af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x34e8
jmp 0xd8ba
jmp 0xd8b1
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x3470
nopw %cs:(%rax,%rax)