// File: /workspace/github_c_makefile_star2_O3/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 0x42b0(%rip), %r12      # 0x7168
movl (%r15), %eax
decl %eax
cmpl $0x21, %eax
ja 0x357f
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4afd(%rip), %rsi      # 0x79e4
jmp 0x2f01
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4af7(%rip), %rsi      # 0x79f8
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
jmp 0x2f4f
movl 0x8(%r15), %eax
leal -0x1(%rax), %ecx
cmpl $0xe, %ecx
jae 0x3560
leaq 0x9bec(%rip), %rcx      # 0xcb10
movq (%rcx,%rax,8), %rdx
cmpq $0xb, %rax
leaq 0x4169(%rip), %rax      # 0x709c
leaq 0x4af1(%rip), %rcx      # 0x7a2b
cmoveq %rax, %rcx
leaq 0x4aaa(%rip), %rsi      # 0x79ef
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movl $0x10, %eax
jmp 0x2f98
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
movl 0x8(%r15), %eax
leal -0x1(%rax), %ecx
cmpl $0xe, %ecx
jae 0x3560
leaq 0x9b92(%rip), %rcx      # 0xcb10
movq (%rcx,%rax,8), %rdx
leaq 0x4a61(%rip), %rsi      # 0x79ea
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movl $0x18, %eax
movq (%r15,%rax), %r15
jmp 0x2eb8
cmpq $0x0, 0x8(%r15)
je 0x2fea
leaq 0x4a5d(%rip), %r12      # 0x7a0c
xorl %r13d, %r13d
movq 0x18(%r15,%r13,8), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
movq 0x8(%r15), %rax
leaq -0x1(%rax), %rcx
cmpq %rcx, %r13
je 0x2fe2
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rax
incq %r13
cmpq %rax, %r13
jb 0x2fb2
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x8(%r15), %rdx
leaq 0x4a00(%rip), %rsi      # 0x7a04
jmp 0x3548
leaq 0x49be(%rip), %rsi      # 0x79ce
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
jmp 0x3424
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x49ab(%rip), %rsi      # 0x79e6
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x498b(%rip), %rsi      # 0x79e8
jmp 0x3438
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x6a3a(%rip), %rsi      # 0x9aba
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
cmpq $0x0, 0x8(%r15)
je 0x3358
leaq 0x498f(%rip), %rsi      # 0x7a2b
movq %rbx, %rdi
jmp 0x3293
leaq 0x491f(%rip), %rsi      # 0x79ca
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
leaq 0x4912(%rip), %rsi      # 0x79ce
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
testq %rdi, %rdi
je 0x30dc
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x48ed(%rip), %rsi      # 0x79d0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x3499
leaq 0x48ba(%rip), %rsi      # 0x79bd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2e9b
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x487c(%rip), %rsi      # 0x79b9
jmp 0x34a0
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x4860(%rip), %rsi      # 0x79c0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x48a9(%rip), %r12      # 0x7a2b
movq %rbx, %rdi
movq %r12, %rsi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x34ac
leaq 0x4818(%rip), %rsi      # 0x79bd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2e9b
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x47da(%rip), %rsi      # 0x79b9
jmp 0x34b3
leaq 0x4809(%rip), %rsi      # 0x79f4
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
testq %rdi, %rdi
je 0x320b
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x47e4(%rip), %rsi      # 0x79f6
jmp 0x3438
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x4795(%rip), %rsi      # 0x79ca
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4777(%rip), %rsi      # 0x79ce
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
testq %rdi, %rdi
je 0x3277
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4752(%rip), %rsi      # 0x79d0
jmp 0x34e2
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
jmp 0x334b
movsd 0x8(%r15), %xmm0
leaq 0x4758(%rip), %rsi      # 0x7a08
movq %rbx, %rdi
movb $0x1, %al
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b8e
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x46ed(%rip), %rsi      # 0x79d3
jmp 0x3438
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x46d1(%rip), %rsi      # 0x79da
jmp 0x3438
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x466d(%rip), %rsi      # 0x79aa
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x3d3c(%rip), %rsi      # 0x709b
jmp 0x3438
cmpq $0x0, 0x8(%r15)
je 0x2fea
xorl %r12d, %r12d
movq 0x18(%r15,%r12,8), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
incq %r12
cmpq 0x8(%r15), %r12
jb 0x3372
jmp 0x2fea
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x45fe(%rip), %rsi      # 0x79ae
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x45e1(%rip), %rsi      # 0x79b3
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4637(%rip), %rsi      # 0x7a2b
jmp 0x34e2
movq 0x8(%r15), %rdi
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x45bd(%rip), %rsi      # 0x79ce
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x10(%r15), %rdi
testq %rdi, %rdi
je 0x3431
movl %ebp, %esi
movl %r14d, %edx
movq %rbx, %rcx
callq 0x2e9b
leaq 0x4616(%rip), %rsi      # 0x7a4e
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b8e
movq 0x8(%r15), %rdx
jmp 0x348d
movq 0x8(%r15), %rdx
leaq 0x459f(%rip), %rsi      # 0x7a00
jmp 0x3548
movq 0x8(%r15), %rdx
leaq 0x458a(%rip), %rsi      # 0x79fb
jmp 0x3548
leaq 0x665b(%rip), %rax      # 0x9ad8
cmpb $0x0, 0x8(%r15)
leaq 0x6658(%rip), %rdx      # 0x9ae1
cmovneq %rax, %rdx
leaq 0x6457(%rip), %rsi      # 0x98eb
jmp 0x3548
leaq 0x4518(%rip), %rsi      # 0x79b8
leaq 0x3bf5(%rip), %rdx      # 0x709c
jmp 0x3548
leaq 0x4505(%rip), %rsi      # 0x79b8
cmpq $0x0, 0x18(%r15)
leaq 0x3bdc(%rip), %rax      # 0x709b
cmoveq %rax, %r12
movq %rbx, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x3b8e
cmpq $0x0, 0x18(%r15)
je 0x2fea
leaq 0x44e2(%rip), %rsi      # 0x79c4
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x18(%r15), %rax
cmpq $0x0, 0x8(%rax)
je 0x353a
leaq 0x44bf(%rip), %rsi      # 0x79bd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x3b8e
movq 0x18(%r15), %rdi
leal 0x1(%r14), %edx
movl %ebp, %esi
movq %rbx, %rcx
callq 0x2e9b
movl %ebp, %edi
movl %r14d, %esi
callq 0x3584
movq %rbx, %rdi
movq %rax, %rsi
xorl %eax, %eax
callq 0x3b8e
leaq 0x4481(%rip), %rsi      # 0x79b9
jmp 0x3541
leaq 0x4477(%rip), %rsi      # 0x79b8
leaq 0x3b53(%rip), %rdx      # 0x709b
movq %rbx, %rdi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b8e
leaq 0x4514(%rip), %rdi      # 0x7a7b
leaq 0x3d07(%rip), %rsi      # 0x7275
leaq 0x453d(%rip), %rcx      # 0x7ab2
movl $0x21f, %edx            # imm = 0x21F
callq 0x20f0
callq 0x2267