#include "ast.h" #include static void expr_destroy(struct expr_node* node); static void stmt_destroy(struct stmt_node* node); static void type_destroy(struct type_node* node) { free(node->type); } static void var_decl_destroy(struct var_decl_node* node) { type_destroy(&node->type); free(node->ident); } static void group_destroy(struct group_node* node) { struct stmt_node* body_node = node->body_head; while (body_node != NULL) { struct stmt_node* next = body_node->next; stmt_destroy(body_node); free(body_node); body_node = next; } } static void fn_decl_destroy(struct fn_decl_node* node) { type_destroy(&node->return_type); free(node->name); struct var_decl_node* args_node = node->args_head; while (args_node != NULL) { struct var_decl_node* next = args_node->next; var_decl_destroy(args_node); free(args_node); args_node = next; } group_destroy(&node->body); } static void return_destroy(struct return_node* node) { if (node->ret_val != NULL) { expr_destroy(node->ret_val); free(node->ret_val); } } static void expr_destroy(struct expr_node* node) { switch (node->type) { case EXPR_EMPTY: case EXPR_INT_LIT: break; case EXPR_VAR_DECL: var_decl_destroy(&node->as._var_decl); break; case EXPR_RETURN: return_destroy(&node->as._return); break; } } static void stmt_destroy(struct stmt_node* node) { switch (node->type) { case STMT_EXPR: expr_destroy(&node->as._expr); break; case STMT_GROUP: group_destroy(&node->as._group); } } static void root_node_destroy(struct root_node* node) { switch (node->type) { case ROOT_FN_DECL: fn_decl_destroy(&node->as._fn_decl); break; } } void ast_destroy(struct root_node* head) { struct root_node* node = head; while (node != NULL) { struct root_node* next = node->next; root_node_destroy(node); free(node); node = next; } }