diff options
author | Marvin Borner | 2023-10-21 20:05:57 +0200 |
---|---|---|
committer | Marvin Borner | 2023-10-21 20:15:42 +0200 |
commit | 71c067a345f4884e7c9bc916c47b749f2768a871 (patch) | |
tree | 4a15073d8f92fb180ae0709e4f7d7ab06bac9c55 | |
parent | e8e99e934c3c7ac0861adf0ac59c08f15e42f450 (diff) |
Fixed inc and added open
-rw-r--r-- | src/reduce.c | 29 | ||||
-rw-r--r-- | src/term.c | 2 | ||||
-rw-r--r-- | test/open.blc | 1 |
3 files changed, 13 insertions, 19 deletions
diff --git a/src/reduce.c b/src/reduce.c index 07d1bfa..e3a785d 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -9,25 +9,22 @@ #include <log.h> #include <assert.h> +// parent rehashing done by caller static struct term *shift(struct term *term, size_t level, size_t amount) { debug("shifting %lx\n", term->hash & HASH_MASK); if (term->type == VAR) { if (level > term->u.var.index) return term; - struct term *rehashed = - term_rehash_var(term, term->u.var.index + amount); - return rehashed; + term->refs += 1; // TODO: Kinda hacky + return term_rehash_var(term, term->u.var.index + amount); } else if (term->type == ABS) { struct term *previous = term->u.abs.term; struct term *new = shift(term->u.abs.term, level + 1, amount); if (previous->hash == new->hash) return term; // nothing changed - struct term *rehashed = term_rehash_abs(term, new); - /* term_rehash_parents(rehashed); */ - /* if (rehashed->u.abs.term->hash == (*substitution)->hash) */ - /* term_deref_head(previous, 1); */ - return rehashed; + term->refs += 1; + return term_rehash_abs(term, new); } else if (term->type == APP) { hash_t previous_lhs = term->u.app.lhs->hash; hash_t previous_rhs = term->u.app.rhs->hash; @@ -35,9 +32,8 @@ static struct term *shift(struct term *term, size_t level, size_t amount) struct term *rhs = shift(term->u.app.rhs, level, amount); if (previous_lhs == lhs->hash && previous_rhs == rhs->hash) return term; // nothing changed - struct term *rehashed = term_rehash_app(term, lhs, rhs); - /* term_rehash_parents(rehashed); */ - return rehashed; + term->refs += 1; + return term_rehash_app(term, lhs, rhs); } fatal("invalid type %d\n", term->type); } @@ -49,16 +45,13 @@ static struct term *substitute(struct term *term, struct term *substitution, debug("substituting %lx with %lx\n", term->hash & HASH_MASK, substitution->hash & HASH_MASK); if (term->type == VAR) { - if (term->u.var.index == level) { - substitution->refs += 1; // TODO: Kinda hacky - shift(substitution, 0, level); - substitution->refs -= 1; - return substitution; - } else if (term->u.var.index < level) { + if (level == term->u.var.index) { + return shift(substitution, 0, level); + } else if (level > term->u.var.index) { term_deref(substitution, 1); return term; } else { - fatal("implement\n"); + return shift(term, 0, -1); } } else if (term->type == ABS) { struct term *previous = term->u.abs.term; @@ -250,7 +250,7 @@ char term_deref_head(struct term *term, char destroy_parents) { debug("dereferring head of %lx\n", term->hash & HASH_MASK); - assert(term->refs); + assert(term->refs > 0); term->refs--; if (!term->refs) { term_destroy_head(term, destroy_parents); diff --git a/test/open.blc b/test/open.blc new file mode 100644 index 0000000..1540526 --- /dev/null +++ b/test/open.blc @@ -0,0 +1 @@ +0001001111100000110 |