Add a recursive tree freeing function.
This commit is contained in:
parent
a52735f0b3
commit
811704be25
|
@ -80,5 +80,12 @@ typedef struct libab_tree_s libab_tree;
|
||||||
* @param tree the tree to free.
|
* @param tree the tree to free.
|
||||||
*/
|
*/
|
||||||
void libab_tree_free(libab_tree* tree);
|
void libab_tree_free(libab_tree* tree);
|
||||||
|
/**
|
||||||
|
* Frees the given tree recursively,
|
||||||
|
* deleting the children first and the moving on
|
||||||
|
* to the parents.
|
||||||
|
* @param tree the tree to free.
|
||||||
|
*/
|
||||||
|
void libab_tree_free_recursive(libab_tree* tree);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
12
src/parser.c
12
src/parser.c
|
@ -105,7 +105,7 @@ libab_result _parser_construct_op_node(struct parser_state* state, libab_lexer_m
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
result = libab_convert_ds_result(vec_init(&(*into)->children));
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
(*into)->variant = OP;
|
(*into)->variant = (match->type == TOKEN_OP_INFIX) ? OP : UNARY_OP;
|
||||||
} else {
|
} else {
|
||||||
free((*into)->string_value);
|
free((*into)->string_value);
|
||||||
free(*into);
|
free(*into);
|
||||||
|
@ -188,7 +188,7 @@ libab_result _parser_append_atom(struct parser_state* state, ll* append_to) {
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
result = libab_convert_ds_result(ll_append(append_to, tree));
|
result = libab_convert_ds_result(ll_append(append_to, tree));
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
libab_tree_free(tree);
|
libab_tree_free_recursive(tree);
|
||||||
free(tree);
|
free(tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,8 +219,8 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
if(left) libab_tree_free(left);
|
if(left) libab_tree_free_recursive(left);
|
||||||
if(right) libab_tree_free(right);
|
if(right) libab_tree_free_recursive(right);
|
||||||
libab_tree_free(top);
|
libab_tree_free(top);
|
||||||
free(left);
|
free(left);
|
||||||
free(right);
|
free(right);
|
||||||
|
@ -241,7 +241,7 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result != LIBAB_SUCCESS) {
|
if(result != LIBAB_SUCCESS) {
|
||||||
if(child) libab_tree_free(child);
|
if(child) libab_tree_free_recursive(child);
|
||||||
libab_tree_free(top);
|
libab_tree_free(top);
|
||||||
free(child);
|
free(child);
|
||||||
free(top);
|
free(top);
|
||||||
|
@ -339,7 +339,7 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result == LIBAB_SUCCESS && out_stack.tail) {
|
if(result == LIBAB_SUCCESS && out_stack.tail) {
|
||||||
libab_tree_free(*store_into);
|
libab_tree_free_recursive(*store_into);
|
||||||
free(*store_into);
|
free(*store_into);
|
||||||
*store_into = NULL;
|
*store_into = NULL;
|
||||||
result = LIBAB_UNEXPECTED;
|
result = LIBAB_UNEXPECTED;
|
||||||
|
|
27
src/tree.c
27
src/tree.c
|
@ -1,15 +1,19 @@
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void libab_tree_free(libab_tree* tree) {
|
int _tree_has_vector(libab_tree* tree) {
|
||||||
int free_string = 0;
|
return tree->variant == BASE || tree->variant == OP ||
|
||||||
int free_vector = 0;
|
|
||||||
if(tree->variant == BASE || tree->variant == OP ||
|
|
||||||
tree->variant == UNARY_OP || tree->variant == BLOCK ||
|
tree->variant == UNARY_OP || tree->variant == BLOCK ||
|
||||||
tree->variant == FUN || tree->variant == IF ||
|
tree->variant == FUN || tree->variant == IF ||
|
||||||
tree->variant == WHILE || tree->variant == DOWHILE ||
|
tree->variant == WHILE || tree->variant == DOWHILE ||
|
||||||
tree->variant == FOR || tree->variant == CALL ||
|
tree->variant == FOR || tree->variant == CALL ||
|
||||||
tree->variant == RETURN) {
|
tree->variant == RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void libab_tree_free(libab_tree* tree) {
|
||||||
|
int free_string = 0;
|
||||||
|
int free_vector = 0;
|
||||||
|
if(_tree_has_vector(tree)) {
|
||||||
free_vector = 1;
|
free_vector = 1;
|
||||||
}
|
}
|
||||||
if(tree->variant == ID || tree->variant == STR || tree->variant == NUM ||
|
if(tree->variant == ID || tree->variant == STR || tree->variant == NUM ||
|
||||||
|
@ -20,3 +24,16 @@ void libab_tree_free(libab_tree* tree) {
|
||||||
if(free_string) free(tree->string_value);
|
if(free_string) free(tree->string_value);
|
||||||
if(free_vector) vec_free(&tree->children);
|
if(free_vector) vec_free(&tree->children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _tree_foreach_free(void* data, va_list args) {
|
||||||
|
libab_tree_free_recursive(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void libab_tree_free_recursive(libab_tree* tree) {
|
||||||
|
if(_tree_has_vector(tree)) {
|
||||||
|
vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free);
|
||||||
|
}
|
||||||
|
libab_tree_free(tree);
|
||||||
|
free(tree);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user