diff options
Diffstat (limited to 'interpreter/graphs.c')
-rw-r--r-- | interpreter/graphs.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/interpreter/graphs.c b/interpreter/graphs.c index ad70abb..d793efb 100644 --- a/interpreter/graphs.c +++ b/interpreter/graphs.c @@ -10,11 +10,20 @@ void use_node(struct node* node, unsigned int count) { node->used_count += count; - if (node->kind == NODE_LIST || - node->kind == NODE_TUPLE || - node->kind == NODE_APP) { - use_node(node->var1, count); - use_node(node->var2, count); + switch (node->kind) { + case NODE_INT: + case NODE_NAME: + case NODE_CODE: + break; + + case NODE_LIST: + case NODE_TUPLE: + case NODE_APP: + use_node(node->var2, count); + + case NODE_REDIRECT: + use_node(node->var1, count); + break; } } @@ -24,11 +33,20 @@ void free_node(struct node* node, unsigned int count, unsigned free_first) { node->used_count -= count; - if (node->kind == NODE_LIST || - node->kind == NODE_TUPLE || - node->kind == NODE_APP) { - free_node((struct node*) node->var1, count, 1); - free_node((struct node*) node->var2, count, 1); + switch (node->kind) { + case NODE_INT: + case NODE_NAME: + case NODE_CODE: + break; + + case NODE_LIST: + case NODE_TUPLE: + case NODE_APP: + free_node(node->var2, count, 1); + + case NODE_REDIRECT: + free_node(node->var1, count, 1); + break; } if (node->used_count == 0) { @@ -38,11 +56,25 @@ void free_node(struct node* node, unsigned int count, unsigned free_first) { if (node->kind == NODE_CODE) my_free(node->var2); + node->var1 = node->var2 = NULL; + if (free_first) my_free(node); } } +void remove_redirects(struct node *node) { + while (node->kind == NODE_REDIRECT) { + struct node *child = (struct node*) node->var1; + node->kind = child->kind; + node->var1 = child->var1; + node->var2 = child->var2; + child->used_count -= node->used_count; + if (child->used_count == 0) + my_free(child); + } +} + void cpy_expression_to_node(struct node* dst, expression* src) { if (!dst || !src) return; @@ -120,5 +152,9 @@ void cpy_node_to_expression(expression* dst, struct node* src) { cpy_node_to_expression(dst->var2, src->var2); } break; + + case NODE_REDIRECT: + cpy_node_to_expression(dst, src->var1); + break; } } |