// File: /workspace/github_c_makefile_star2_O1/yangtau[P]hedgehog/src/ast.c
// Function: node_to_str
static void _node_to_str(const struct hg_ast_node* _node, uint32_t indent, uint32_t depth, struct hg_strbuf* buf) {
#define __add_indent hg_strbuf_append(buf, _get_indent_str(indent, depth))
#define __add_nl     hg_strbuf_append(buf, "\n")
#define __add_space  hg_strbuf_append(buf, " ")
#define __add_block(block, end)                                        \
    do {                                                               \
        if (__hg_ast_raw(block, struct hg_ast_node_array)->len == 0) { \
            hg_strbuf_append(buf, "{}%s", end);                        \
        } else {                                                       \
            hg_strbuf_append(buf, "{\n");                              \
            _node_to_str(block, indent, depth + 1, buf);               \
            __add_indent;                                              \
            hg_strbuf_append(buf, "}%s", end);                         \
        }                                                              \
    } while (0)

    switch (_node->type) {
    case HG_AST_NODE_ASSIGNMENT: {
        __hg_ast_raw_to(_node, struct hg_ast_assignment_stat, node);

        __add_indent;
        _node_to_str(node->vars, indent, depth, buf);
        hg_strbuf_append(buf, " = ");
        _node_to_str(node->exprs, indent, depth, buf);
        __add_nl;
    } break;
    case HG_AST_NODE_FOR: {
        __hg_ast_raw_to(_node, struct hg_ast_for_stat, node);

        __add_indent;
        hg_strbuf_append(buf, "for ");
        _node_to_str(node->params, indent, depth, buf);
        hg_strbuf_append(buf, " in ");
        _node_to_str(node->iterator, indent, depth, buf);

        __add_space;
        __add_block(node->block, "\n");
    } break;
    case HG_AST_NODE_IF: {
        __hg_ast_raw_to(_node, struct hg_ast_if_stat, node);

        __add_indent;
        hg_strbuf_append(buf, "if ");
        _node_to_str(node->condition, indent, depth, buf);
        __add_space;

        // if block
        __add_block(node->block, node->else_block ? " " : "\n");

        // else block
        if (node->else_block) {
            hg_strbuf_append(buf, "else ");
            // TODO: do not inline this
            __add_block(node->else_block, "\n");
        }
    } break;
    case HG_AST_NODE_FUNC: {
        __hg_ast_raw_to(_node, struct hg_ast_func_stat, node);

        __add_indent;
        hg_strbuf_append(buf, "fn ");
        _node_to_str(node->id, indent, depth, buf);

        hg_strbuf_append(buf, "(");
        if (node->params) {
            _node_to_str(node->params, indent, depth, buf);
        }
        hg_strbuf_append(buf, ") ");

        __add_block(node->block, "\n");
    } break;
    case HG_AST_NODE_BREAK: {
        __add_indent;
        hg_strbuf_append(buf, "break\n");
    } break;
    case HG_AST_NODE_CONTINUE: {
        __add_indent;
        hg_strbuf_append(buf, "continue\n");
    } break;
    case HG_AST_NODE_RETURN: {
        __hg_ast_raw_to(_node, struct hg_ast_return_stat, node);

        __add_indent;
        hg_strbuf_append(buf, "return");

        if (node->exprs) {
            __add_space;
            _node_to_str(node->exprs, indent, depth, buf);
        }
        __add_nl;
    } break;
    case HG_AST_NODE_EXPR_STAT: {
        __hg_ast_raw_to(_node, struct hg_ast_expr_stat, node);
        __add_indent;
        _node_to_str(node->expr, indent, depth, buf);
        __add_nl;
    } break;
    // exprs (no indent and no new line by default):
    case HG_AST_NODE_CALL: {
        __hg_ast_raw_to(_node, struct hg_ast_call_expr, node);

        _node_to_str(node->callable, indent, depth, buf);

        hg_strbuf_append(buf, "(");
        if (node->exprs) {
            _node_to_str(node->exprs, indent, depth, buf);
        }
        hg_strbuf_append(buf, ")");
    } break;
    case HG_AST_NODE_FIELD: {
        __hg_ast_raw_to(_node, struct hg_ast_field_expr, node);

        _node_to_str(node->prefix, indent, depth, buf);
        hg_strbuf_append(buf, ".");
        _node_to_str(node->field, indent, depth, buf);
    } break;
    case HG_AST_NODE_INDEX: {
        __hg_ast_raw_to(_node, struct hg_ast_index_expr, node);

        _node_to_str(node->prefix, indent, depth, buf);

        hg_strbuf_append(buf, "[");
        _node_to_str(node->index, indent, depth, buf);
        hg_strbuf_append(buf, "]");
    } break;
    case HG_AST_NODE_FUNC_DEF: {
        __hg_ast_raw_to(_node, struct hg_ast_func_def_expr, node);

        hg_strbuf_append(buf, "fn ");

        hg_strbuf_append(buf, "(");
        if (node->params) {
            _node_to_str(node->params, indent, depth, buf);
        }
        hg_strbuf_append(buf, ") ");

        __add_block(node->block, "");
    } break;
    case HG_AST_NODE_BINARY_EXPR: {
        __hg_ast_raw_to(_node, struct hg_ast_binary_expr, node);
        _node_to_str(node->left, indent, depth, buf);
        hg_strbuf_append(buf, " %s ", _op_to_str(node->op));
        _node_to_str(node->right, indent, depth, buf);
    } break;
    case HG_AST_NODE_UNARY_EXPR: {
        __hg_ast_raw_to(_node, struct hg_ast_unary_expr, node);
        hg_strbuf_append(buf, "%s%s", _op_to_str(node->op), node->op == HG_AST_NODE_OP_SUB ? "" : " ");
        _node_to_str(node->expr, indent, depth, buf);
    } break;
    case HG_AST_NODE_TABLE: {
        __hg_ast_raw_to(_node, struct hg_ast_table_expr, node);
        hg_strbuf_append(buf, "{");
        if (node->entries) {
            _node_to_str(node->entries, indent, depth, buf);
        }
        hg_strbuf_append(buf, "}");
    } break;
    case HG_AST_NODE_TABLE_ENTRY: {
        __hg_ast_raw_to(_node, struct hg_ast_table_entry, node);
        _node_to_str(node->key, indent, depth, buf);
        hg_strbuf_append(buf, ": ");
        _node_to_str(node->value, indent, depth, buf);
    } break;
    case HG_AST_NODE_BRACK_EXPR: {
        __hg_ast_raw_to(_node, struct hg_ast_brack_expr, node);
        hg_strbuf_append(buf, "(");
        _node_to_str(node->expr, indent, depth, buf);
        hg_strbuf_append(buf, ")");
    } break;
    case HG_AST_NODE_LITERAL_STR: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, "\"%s\"", node->as_str);
    } break;
    case HG_AST_NODE_LITERAL_SYMBOL: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, ".%s", node->as_str);
    } break;
    case HG_AST_NODE_LITERAL_ID: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, "%s", node->as_id);
    } break;
    case HG_AST_NODE_LITERAL_BOOL: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, "%s", node->as_bool ? "true" : "false");
    } break;
    case HG_AST_NODE_LITERAL_INT: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, "%" HGFormatInt, node->as_int);
    } break;
    case HG_AST_NODE_LITERAL_FLOAT: {
        __hg_ast_raw_to(_node, struct hg_ast_literal, node);
        hg_strbuf_append(buf, "%" HGFormatFloat, node->as_float);
    } break;
    case HG_AST_NODE_ARRAY_STATS: {
        __hg_ast_raw_to(_node, struct hg_ast_node_array, node);
        for (size_t i = 0; i < node->len; i++) {
            _node_to_str(node->arr[i], indent, depth, buf);
            // __add_nl;
        }
    } break;
    case HG_AST_NODE_ARRAY_EXPRS:
    case HG_AST_NODE_ARRAY_VARS:
    case HG_AST_NODE_ARRAY_PARAMS:
    case HG_AST_NODE_ARRAY_TABLE_ENTRIES: {
        __hg_ast_raw_to(_node, struct hg_ast_node_array, node);
        for (size_t i = 0; i < node->len; i++) {
            _node_to_str(node->arr[i], indent, depth, buf);
            if (i != node->len - 1) {
                hg_strbuf_append(buf, ", ");
            }
        }
    } break;
    default:
        unreachable_();
    }
#undef __add_indent
#undef __add_nl
#undef __add_space
#undef __add_block
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movl %edx, %r14d
movl %esi, %ebp
movq %rdi, %r15
leaq 0x427b(%rip), %r12      # 0x7168
movl (%r15), %eax
decl %eax
cmpl $0x21, %eax
ja 0x35b1
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4ae8(%rip), %rsi      # 0x7a04
jmp 0x2f36
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4ae2(%rip), %rsi      # 0x7a18
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %r15
jmp 0x2eed
movl 0x8(%r15), %eax
leal -0x1(%rax), %ecx
cmpl $0xe, %ecx
jae 0x3592
leaq 0x9bb3(%rip), %rcx      # 0xcb10
movq (%rcx,%rax,8), %rdx
cmpq $0xb, %rax
leaq 0x4133(%rip), %rax      # 0x709f
leaq 0x4ad8(%rip), %rcx      # 0x7a4b
cmoveq %rax, %rcx
leaq 0x4a91(%rip), %rsi      # 0x7a0f
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %r15
jmp 0x2eed
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
movl 0x8(%r15), %eax
leal -0x1(%rax), %ecx
cmpl $0xe, %ecx
jae 0x3592
leaq 0x9b57(%rip), %rcx      # 0xcb10
movq (%rcx,%rax,8), %rdx
leaq 0x4a46(%rip), %rsi      # 0x7a0a
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x18(%r15), %r15
jmp 0x2eed
cmpq $0x0, 0x8(%r15)
je 0x301c
leaq 0x4a47(%rip), %r12      # 0x7a2c
xorl %r13d, %r13d
movq 0x18(%r15,%r13,8), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
movq 0x8(%r15), %rax
decq %rax
cmpq %rax, %r13
je 0x3013
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x3b18
incq %r13
cmpq 0x8(%r15), %r13
jb 0x2fe8
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%r15), %rdx
leaq 0x49ee(%rip), %rsi      # 0x7a24
jmp 0x357a
leaq 0x49ac(%rip), %rsi      # 0x79ee
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
jmp 0x3456
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4999(%rip), %rsi      # 0x7a06
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4979(%rip), %rsi      # 0x7a08
jmp 0x346a
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x69b8(%rip), %rsi      # 0x9a6a
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
cmpq $0x0, 0x8(%r15)
je 0x338a
leaq 0x497d(%rip), %rsi      # 0x7a4b
movq %rbx, %rdi
jmp 0x32c5
leaq 0x490d(%rip), %rsi      # 0x79ea
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
leaq 0x4900(%rip), %rsi      # 0x79ee
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
testq %rdi, %rdi
je 0x310e
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x48db(%rip), %rsi      # 0x79f0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x34cb
leaq 0x48a8(%rip), %rsi      # 0x79dd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2ed0
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x486a(%rip), %rsi      # 0x79d9
jmp 0x34d2
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x484e(%rip), %rsi      # 0x79e0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4897(%rip), %r12      # 0x7a4b
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x34de
leaq 0x4806(%rip), %rsi      # 0x79dd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2ed0
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x47c8(%rip), %rsi      # 0x79d9
jmp 0x34e5
leaq 0x47f7(%rip), %rsi      # 0x7a14
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
testq %rdi, %rdi
je 0x323d
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x47d2(%rip), %rsi      # 0x7a16
jmp 0x346a
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x4783(%rip), %rsi      # 0x79ea
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4765(%rip), %rsi      # 0x79ee
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
testq %rdi, %rdi
je 0x32a9
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4740(%rip), %rsi      # 0x79f0
jmp 0x3514
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
jmp 0x337d
movsd 0x8(%r15), %xmm0
leaq 0x4746(%rip), %rsi      # 0x7a28
movq %rbx, %rdi
movb $0x1, %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b18
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x46db(%rip), %rsi      # 0x79f3
jmp 0x346a
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x46bf(%rip), %rsi      # 0x79fa
jmp 0x346a
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x465b(%rip), %rsi      # 0x79ca
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x3d0d(%rip), %rsi      # 0x709e
jmp 0x346a
cmpq $0x0, 0x8(%r15)
je 0x301c
xorl %r12d, %r12d
movq 0x18(%r15,%r12,8), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
incq %r12
cmpq 0x8(%r15), %r12
jb 0x33a4
jmp 0x301c
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x45ec(%rip), %rsi      # 0x79ce
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x45cf(%rip), %rsi      # 0x79d3
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4625(%rip), %rsi      # 0x7a4b
jmp 0x3514
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x45ab(%rip), %rsi      # 0x79ee
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x10(%r15), %rdi
testq %rdi, %rdi
je 0x3463
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2ed0
leaq 0x4604(%rip), %rsi      # 0x7a6e
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b18
movq 0x8(%r15), %rdx
jmp 0x34bf
movq 0x8(%r15), %rdx
leaq 0x458d(%rip), %rsi      # 0x7a20
jmp 0x357a
movq 0x8(%r15), %rdx
leaq 0x4578(%rip), %rsi      # 0x7a1b
jmp 0x357a
leaq 0x65d9(%rip), %rax      # 0x9a88
cmpb $0x0, 0x8(%r15)
leaq 0x65d6(%rip), %rdx      # 0x9a91
cmovneq %rax, %rdx
leaq 0x63d5(%rip), %rsi      # 0x989b
jmp 0x357a
leaq 0x4506(%rip), %rsi      # 0x79d8
leaq 0x3bc6(%rip), %rdx      # 0x709f
jmp 0x357a
leaq 0x44f3(%rip), %rsi      # 0x79d8
cmpq $0x0, 0x18(%r15)
leaq 0x3bad(%rip), %rax      # 0x709e
cmoveq %rax, %r12
movq %rbx, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x3b18
cmpq $0x0, 0x18(%r15)
je 0x301c
leaq 0x44d0(%rip), %rsi      # 0x79e4
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x18(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x356c
leaq 0x44ad(%rip), %rsi      # 0x79dd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b18
movq 0x18(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2ed0
movl %ebp, %edi
movl %r14d, %esi
callq 0x35b6
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b18
leaq 0x446f(%rip), %rsi      # 0x79d9
jmp 0x3573
leaq 0x4465(%rip), %rsi      # 0x79d8
leaq 0x3b24(%rip), %rdx      # 0x709e
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b18
leaq 0x4502(%rip), %rdi      # 0x7a9b
leaq 0x3cd5(%rip), %rsi      # 0x7275
leaq 0x452b(%rip), %rcx      # 0x7ad2
movl $0x21f, %edx            # imm = 0x21F
callq 0x20f0
callq 0x2277