aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2023-10-21 20:05:57 +0200
committerMarvin Borner2023-10-21 20:15:42 +0200
commit71c067a345f4884e7c9bc916c47b749f2768a871 (patch)
tree4a15073d8f92fb180ae0709e4f7d7ab06bac9c55
parente8e99e934c3c7ac0861adf0ac59c08f15e42f450 (diff)
Fixed inc and added open
-rw-r--r--src/reduce.c29
-rw-r--r--src/term.c2
-rw-r--r--test/open.blc1
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;
diff --git a/src/term.c b/src/term.c
index 7756bdc..aa7736b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -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