2018-02-17 12:55:50 -08:00
|
|
|
#include "tree.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2018-02-25 22:57:45 -08:00
|
|
|
int libab_tree_has_vector(libab_tree_variant variant) {
|
2018-03-08 21:13:25 -08:00
|
|
|
return variant == TREE_BASE || variant == TREE_OP ||
|
2018-04-21 14:09:01 -07:00
|
|
|
variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP ||
|
|
|
|
variant == TREE_BLOCK || variant == TREE_IF ||
|
|
|
|
variant == TREE_CALL || variant == TREE_WHILE ||
|
|
|
|
variant == TREE_DOWHILE || variant == TREE_FUN ||
|
|
|
|
variant == TREE_RETURN || variant == TREE_RESERVED_OP;
|
2018-02-25 22:57:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
int libab_tree_has_string(libab_tree_variant variant) {
|
2018-04-21 14:09:01 -07:00
|
|
|
return variant == TREE_ID || variant == TREE_NUM || variant == TREE_OP ||
|
|
|
|
variant == TREE_PREFIX_OP || variant == TREE_POSTFIX_OP ||
|
|
|
|
variant == TREE_FUN || variant == TREE_FUN_PARAM ||
|
|
|
|
variant == TREE_RESERVED_OP;
|
2018-03-08 21:10:05 -08:00
|
|
|
}
|
|
|
|
|
2018-03-24 00:36:10 -07:00
|
|
|
int libab_tree_has_scope(libab_tree_variant variant) {
|
|
|
|
return variant == TREE_BASE || variant == TREE_BLOCK ||
|
2018-04-21 14:09:01 -07:00
|
|
|
variant == TREE_IF || variant == TREE_WHILE ||
|
2018-06-15 22:56:56 -07:00
|
|
|
variant == TREE_DOWHILE;
|
2018-03-24 00:36:10 -07:00
|
|
|
}
|
|
|
|
|
2018-03-08 21:10:05 -08:00
|
|
|
int libab_tree_has_type(libab_tree_variant variant) {
|
2018-03-08 21:13:25 -08:00
|
|
|
return variant == TREE_FUN_PARAM || variant == TREE_FUN;
|
2018-02-17 19:20:10 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void libab_tree_free(libab_tree* tree) {
|
|
|
|
int free_string = 0;
|
|
|
|
int free_vector = 0;
|
2018-03-08 21:10:05 -08:00
|
|
|
int free_type = 0;
|
2018-02-25 22:57:45 -08:00
|
|
|
free_vector = libab_tree_has_vector(tree->variant);
|
|
|
|
free_string = libab_tree_has_string(tree->variant);
|
2018-03-08 21:10:05 -08:00
|
|
|
free_type = libab_tree_has_type(tree->variant);
|
2018-04-21 14:09:01 -07:00
|
|
|
if (free_string)
|
|
|
|
free(tree->string_value);
|
|
|
|
if (free_vector)
|
|
|
|
vec_free(&tree->children);
|
|
|
|
if (free_type)
|
2018-04-17 22:14:07 -07:00
|
|
|
libab_ref_free(&tree->type);
|
2018-02-17 12:55:50 -08:00
|
|
|
}
|
2018-02-17 19:20:10 -08:00
|
|
|
|
|
|
|
int _tree_foreach_free(void* data, va_list args) {
|
|
|
|
libab_tree_free_recursive(data);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-06-12 23:34:18 -07:00
|
|
|
int _tree_needs_free(libab_tree* tree) {
|
2018-06-13 23:28:42 -07:00
|
|
|
return ((tree->variant == TREE_FUN && --(tree->int_value) == 0) |
|
|
|
|
(tree->variant != TREE_FUN));
|
2018-06-12 23:34:18 -07:00
|
|
|
}
|
|
|
|
|
2018-02-17 19:20:10 -08:00
|
|
|
void libab_tree_free_recursive(libab_tree* tree) {
|
2018-06-12 23:34:18 -07:00
|
|
|
if(_tree_needs_free(tree)) {
|
|
|
|
if (libab_tree_has_vector(tree->variant)) {
|
|
|
|
vec_foreach(&tree->children, NULL, compare_always, _tree_foreach_free);
|
|
|
|
}
|
|
|
|
libab_tree_free(tree);
|
|
|
|
free(tree);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void libab_tree_refcount_free(libab_tree* tree) {
|
|
|
|
if(_tree_needs_free(tree)) {
|
|
|
|
libab_tree_free(tree);
|
|
|
|
free(tree);
|
2018-02-17 19:20:10 -08:00
|
|
|
}
|
|
|
|
}
|