// File: /workspace/github_c_makefile_star2_O3/neosploit[P]compiler/ast_free.c
// Function: ast_definition_free
static void ast_definition_free(Definition* definition) {

    if (definition->next) ast_definition_free(definition->next);

    switch (definition->tag) {
        case DEFINITION_PROGRAM:
            ast_id_free(definition->program.id);

            break;
        case DEFINITION_CONSTANT:
            ast_id_free(definition->constant.id);
            ast_expression_free(definition->constant.expression);

            break;
        case DEFINITION_TYPE:
            ast_id_free(definition->type.id);
            ast_type_free(definition->type.type);

            break;
        case DEFINITION_FIELD:
            ast_id_free(definition->field.identifiers);
            ast_type_free(definition->field.type);

            break;
        case DEFINITION_VARIABLE:
            ast_id_free(definition->variable.identifiers);
            ast_type_free(definition->variable.type);

            break;
        case DEFINITION_SUBPROGRAM_FORWARD:
            ast_definition_free(definition->subprogram_forward.sub_header);

            break;
        case DEFINITION_SUBPROGRAM:
            ast_definition_free(definition->subprogram.sub_header);
            ast_declaration_free(definition->subprogram.declarations);
            if (definition->subprogram.subprograms) ast_definition_free(definition->subprogram.subprograms);
            if (definition->subprogram.comp_statement) ast_statement_free(definition->subprogram.comp_statement);

            break;
        case DEFINITION_FUNCTION:
            ast_id_free(definition->function.id);
            if (definition->function.formal_parameters) ast_definition_free(definition->function.formal_parameters);
            if (definition->function.type) ast_type_free(definition->function.type);

            break;
        case DEFINITION_PROCEDURE:
            ast_id_free(definition->procedure.id);
            if (definition->procedure.formal_parameters) ast_definition_free(definition->procedure.formal_parameters);

            break;
        case DEFINITION_PARAMETER:
            ast_id_free(definition->parameter.identifiers);
            ast_type_free(definition->parameter.type);
    }

    free(definition);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0xcef7
callq 0xcee0
movl 0x4(%rbx), %eax
cmpq $0x9, %rax
ja 0xcfc8
leaq 0xc45d(%rip), %rcx      # 0x19368
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%rbx), %rdi
callq 0xd0e3
movq 0x18(%rbx), %rdi
jmp 0xcf74
movq 0x18(%rbx), %rdi
callq 0xd0e3
movq 0x20(%rbx), %rdi
jmp 0xcf74
movq 0x10(%rbx), %rdi
callq 0xd0e3
jmp 0xcfc8
movq 0x10(%rbx), %rdi
callq 0xd0e3
movq 0x18(%rbx), %rdi
callq 0xd110
jmp 0xcfc8
movq 0x10(%rbx), %rdi
callq 0xd0e3
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0xcf6b
callq 0xcee0
movq 0x20(%rbx), %rdi
testq %rdi, %rdi
je 0xcfc8
callq 0xd1b0
jmp 0xcfc8
movq 0x10(%rbx), %rdi
jmp 0xcfc3
movq 0x10(%rbx), %rdi
callq 0xcee0
movq 0x18(%rbx), %rdi
callq 0xcfd6
movq 0x20(%rbx), %rdi
testq %rdi, %rdi
je 0xcfa1
callq 0xcee0
movq 0x28(%rbx), %rdi
testq %rdi, %rdi
je 0xcfc8
callq 0xd016
jmp 0xcfc8
movq 0x10(%rbx), %rdi
callq 0xd0e3
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0xcfc8
callq 0xcee0
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x72b0