// File: cphinton42[P]hinton-language/src/main.cpp
// Function: check_for_untyped(AST*)
void check_for_untyped(AST *ast)
{
    if(ast)
    {
        switch(ast->type)
        {
            case AST_Type::decl_ast: {
                Decl_AST *decl_ast = static_cast<Decl_AST*>(ast);
                check_for_untyped(&decl_ast->ident);
                check_for_untyped(decl_ast->decl_type);
                check_for_untyped(decl_ast->expr);
            } break;
            case AST_Type::block_ast: {
                Block_AST *block_ast = static_cast<Block_AST*>(ast);
                for(u64 i = 0; i < block_ast->statements.count; ++i)
                {
                    check_for_untyped(block_ast->statements[i]);
                }
            } break;
            case AST_Type::while_ast: {
                While_AST *while_ast = static_cast<While_AST*>(ast);
                check_for_untyped(while_ast->guard);
                check_for_untyped(while_ast->body);
            } break;
            case AST_Type::for_ast: {
                For_AST *for_ast = static_cast<For_AST*>(ast);
                check_for_untyped(for_ast->induction_var);
                if(for_ast->flags & FOR_FLAG_OVER_ARRAY)
                {
                    check_for_untyped(for_ast->index_var);
                    check_for_untyped(for_ast->array_expr);
                }
                else
                {
                    check_for_untyped(for_ast->low_expr);
                    check_for_untyped(for_ast->high_expr);
                }
                check_for_untyped(for_ast->body);
            } break;
            case AST_Type::if_ast: {
                If_AST *if_ast = static_cast<If_AST*>(ast);
                check_for_untyped(if_ast->guard);
                check_for_untyped(if_ast->then_block);
                check_for_untyped(if_ast->else_block);
            } break;
            case AST_Type::assign_ast: {
                Assign_AST *assign_ast = static_cast<Assign_AST*>(ast);
                check_for_untyped(assign_ast->lhs);
                check_for_untyped(assign_ast->rhs);
            } break;
            case AST_Type::return_ast: {
                Return_AST *return_ast = static_cast<Return_AST*>(ast);
                check_for_untyped(return_ast->expr);
            } break;
            case AST_Type::ident_ast: {
                Ident_AST *ident_ast = static_cast<Ident_AST*>(ast);
                report_if_expr_untyped(ident_ast);
            } break;
            case AST_Type::function_type_ast: {
                Function_Type_AST *function_type_ast = static_cast<Function_Type_AST*>(ast);
                report_if_expr_untyped(function_type_ast);
                for(u64 i = 0; i < function_type_ast->parameter_types.count; ++i)
                {
                    check_for_untyped(function_type_ast->parameter_types[i]);
                }
                for(u64 i = 0; i < function_type_ast->return_types.count; ++i)
                {
                    check_for_untyped(function_type_ast->return_types[i]);
                }
            } break;
            case AST_Type::function_ast: {
                Function_AST *function_ast = static_cast<Function_AST*>(ast);
                report_if_expr_untyped(function_ast);
                check_for_untyped(function_ast->prototype);
                for(u64 i = 0; i < function_ast->param_names.count; ++i)
                {
                    check_for_untyped(function_ast->param_names[i]);
                    check_for_untyped(function_ast->default_values[i]);
                }
                check_for_untyped(function_ast->block);
            } break;
            case AST_Type::function_call_ast: {
                Function_Call_AST *function_call_ast = static_cast<Function_Call_AST*>(ast);
                report_if_expr_untyped(function_call_ast);
                check_for_untyped(function_call_ast->function);
                for(u64 i = 0; i < function_call_ast->args.count; ++i)
                {
                    check_for_untyped(function_call_ast->args[i]);
                }
            } break;
            case AST_Type::access_ast: {
                Access_AST *access_ast = static_cast<Access_AST*>(ast);
                report_if_expr_untyped(access_ast);
                check_for_untyped(access_ast->lhs);
            } break;
            case AST_Type::binary_operator_ast: {
                Binary_Operator_AST *binop_ast = static_cast<Binary_Operator_AST*>(ast);
                report_if_expr_untyped(binop_ast);
                check_for_untyped(binop_ast->lhs);
                check_for_untyped(binop_ast->rhs);
            } break;
            case AST_Type::number_ast: {
                Number_AST *number_ast = static_cast<Number_AST*>(ast);
                report_if_expr_untyped(number_ast);
            } break;
            case AST_Type::enum_ast: {
                Enum_AST *enum_ast = static_cast<Enum_AST*>(ast);
                report_if_expr_untyped(enum_ast);
                for(u64 i = 0; i < enum_ast->values.count; ++i)
                {
                    check_for_untyped(enum_ast->values[i]);
                }
            } break;
            case AST_Type::struct_ast: {
                Struct_AST *struct_ast = static_cast<Struct_AST*>(ast);
                report_if_expr_untyped(struct_ast);
                for(u64 i = 0; i < struct_ast->constants.count; ++i)
                {
                    check_for_untyped(struct_ast->constants[i]);
                }
                for(u64 i = 0; i < struct_ast->fields.count; ++i)
                {
                    check_for_untyped(struct_ast->fields[i]);
                }
            } break;
            case AST_Type::unary_ast: {
                Unary_Operator_AST *unop_ast = static_cast<Unary_Operator_AST*>(ast);
                report_if_expr_untyped(unop_ast);
                check_for_untyped(unop_ast->operand);
            } break;
            case AST_Type::primitive_ast: {
                Primitive_AST *prim_ast = static_cast<Primitive_AST*>(ast);
                report_if_expr_untyped(prim_ast);
            } break;
            case AST_Type::string_ast: {
                String_AST *string_ast = static_cast<String_AST*>(ast);
                report_if_expr_untyped(string_ast);
            } break;
            case AST_Type::bool_ast: {
                Bool_AST *bool_ast = static_cast<Bool_AST*>(ast);
                report_if_expr_untyped(bool_ast);
            } break;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0xc0ce
movq -0x8(%rbp), %rax
movzwl (%rax), %eax
movq %rax, -0xf0(%rbp)
subq $0x13, %rax
ja 0xc0cc
movq -0xf0(%rbp), %rax
leaq 0xd868(%rip), %rcx      # 0x193e8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
addq $0x10, %rdi
callq 0xbb40
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rdi
callq 0xbb40
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0xbc02
movq -0x18(%rbp), %rdi
addq $0x10, %rdi
movq -0x20(%rbp), %rsi
callq 0x16fe0
movq (%rax), %rdi
callq 0xbb40
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0xbbcd
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xbb40
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xbb40
movq -0x30(%rbp), %rax
movzwl 0x2(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0xbc6f
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
jmp 0xbc89
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
movq -0x30(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xbb40
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
movq -0x40(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0xbb10
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdi
callq 0xbb10
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xbd74
movq -0x58(%rbp), %rdi
addq $0x20, %rdi
movq -0x60(%rbp), %rsi
callq 0x17050
movq (%rax), %rdi
callq 0xbb40
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0xbd3f
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0xbdb1
movq -0x58(%rbp), %rdi
addq $0x30, %rdi
movq -0x68(%rbp), %rsi
callq 0x17050
movq (%rax), %rdi
callq 0xbb40
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0xbd7c
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0xbb10
movq -0x70(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
movq $0x0, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq -0x70(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jae 0xbe2a
movq -0x70(%rbp), %rdi
addq $0x28, %rdi
movq -0x78(%rbp), %rsi
callq 0x172d0
movq (%rax), %rdi
callq 0xbb40
movq -0x70(%rbp), %rdi
addq $0x38, %rdi
movq -0x78(%rbp), %rsi
callq 0x17050
movq (%rax), %rdi
callq 0xbb40
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0xbddc
movq -0x70(%rbp), %rax
movq 0x48(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
callq 0xbb10
movq -0x80(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq -0x80(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jae 0xbea6
movq -0x80(%rbp), %rdi
addq $0x28, %rdi
movq -0x88(%rbp), %rsi
callq 0x17050
movq (%rax), %rdi
callq 0xbb40
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0xbe65
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0xbb10
movq -0x90(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rdi
callq 0xbb10
movq -0x98(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0xbb40
movq -0x98(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
callq 0xbb10
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
callq 0xbb10
movq $0x0, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq -0xa8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xbf98
movq -0xa8(%rbp), %rdi
addq $0x20, %rdi
movq -0xb0(%rbp), %rsi
callq 0x16fb0
movq (%rax), %rdi
callq 0xbb40
movq -0xb0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
jmp 0xbf51
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
callq 0xbb10
movq $0x0, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movq -0xb8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xc006
movq -0xb8(%rbp), %rdi
addq $0x20, %rdi
movq -0xc0(%rbp), %rsi
callq 0x16fb0
movq (%rax), %rdi
callq 0xbb40
movq -0xc0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xc0(%rbp)
jmp 0xbfbf
movq $0x0, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq -0xb8(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0xc058
movq -0xb8(%rbp), %rdi
addq $0x30, %rdi
movq -0xc8(%rbp), %rsi
callq 0x16fb0
movq (%rax), %rdi
callq 0xbb40
movq -0xc8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xc8(%rbp)
jmp 0xc011
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0xbb10
movq -0xd0(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0xbb40
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rdi
callq 0xbb10
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
callq 0xbb10
jmp 0xc0cc
movq -0x8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rdi
callq 0xbb10
jmp 0xc0ce
addq $0xf0, %rsp
popq %rbp
retq
nopw (%rax,%rax)