diff options
Diffstat (limited to 'src/term.c')
-rw-r--r-- | src/term.c | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -6,22 +6,35 @@ #include <assert.h> #include <log.h> +#include <schedule.h> #include <term.h> #include <map.h> // doesn't care about ref count +// this is needed to destroy possibly multiple parents static void term_destroy_head(struct term *term) { - term_print(term); - fprintf(stderr, "\n"); map_delete(map_all_terms(), term); + + // recursively destroy own parents map_destroy(term->parents); + + // remove term from child's parents + if (term->type == ABS) { + map_delete(term->u.abs.term->parents, term); + } else if (term->type == APP) { + map_delete(term->u.app.lhs->parents, term); + map_delete(term->u.app.rhs->parents, term); + } + + schedule_remove(term); free(term); } static void term_destroy_parent(void *item) { struct term *term = *(struct term **)item; + fprintf(stderr, "%p parent\n", term); term_destroy_head(term); } @@ -39,6 +52,11 @@ struct term *term_new(term_type_t type, hash_t hash, size_t depth) return term; } +char term_is_beta_redex(struct term *term) +{ + return term->type == APP && term->u.app.lhs->type == ABS; +} + void term_print(struct term *term) { switch (term->type) { @@ -73,14 +91,14 @@ struct term *term_rehash_abs(struct term *head, struct term *term) struct term *match = map_get(map_all_terms(), res); if (match) { // already exists term_refer_head(match, head->depth); - term_deref_head(head); + /* term_deref_head(head); */ return match; } else { // create new struct term *new = term_new(ABS, res, head->depth); new->u.abs.term = term; map_set(map_all_terms(), new); map_set(term->parents, new); - term_deref_head(head); + /* term_deref_head(head); */ return new; } } @@ -214,6 +232,7 @@ void term_refer(struct term *term, size_t depth) void term_deref_head(struct term *term) { + fprintf(stderr, "%p deref\n", term); assert(term->refs); term->refs--; if (!term->refs) |