aboutsummaryrefslogtreecommitdiff
path: root/src/reducer.c
diff options
context:
space:
mode:
authorMarvin Borner2023-02-20 16:17:31 +0100
committerMarvin Borner2023-02-20 16:17:31 +0100
commita162fdc74abf0686ec06e65e06d67a8ce5c13b30 (patch)
treeb844718a0befa9853c8c12255933f0ed9308f69d /src/reducer.c
parentc741632fbe41c8fcb0b2ea0c2a5b08e778768a7d (diff)
Kinda working but slow
Diffstat (limited to 'src/reducer.c')
-rw-r--r--src/reducer.c87
1 files changed, 37 insertions, 50 deletions
diff --git a/src/reducer.c b/src/reducer.c
index 1d4f5e6..1372a50 100644
--- a/src/reducer.c
+++ b/src/reducer.c
@@ -10,6 +10,7 @@
#include <murmur3.h>
#include <store.h>
#include <term.h>
+#include <gc.h>
struct tracked {
void *stuff;
@@ -59,7 +60,7 @@ static int name_generator(void)
static struct stack *stack_push(struct stack *stack, void *data)
{
- struct stack *new = malloc(sizeof(*new));
+ struct stack *new = gc_malloc(&gc, sizeof(*new));
new->data = data;
new->next = stack;
return new;
@@ -90,9 +91,7 @@ static void cconf(struct conf *conf, struct stack *stack, struct term *term)
static int transition_1(struct term **term, struct store **store,
struct stack **stack)
{
- struct term *orig = *term;
-
- struct closure *closure = malloc(sizeof(*closure));
+ struct closure *closure = gc_malloc(&gc, sizeof(*closure));
closure->term = (*term)->u.app.rhs;
closure->store = *store;
@@ -111,15 +110,15 @@ static int transition_1(struct term **term, struct store **store,
static int transition_2(struct stack **stack, struct term **term,
struct store *store)
{
- struct box *box = malloc(sizeof(*box));
+ struct box *box = gc_malloc(&gc, sizeof(*box));
box->state = TODO;
box->term = 0;
- struct closure *closure = malloc(sizeof(*closure));
+ struct closure *closure = gc_malloc(&gc, sizeof(*closure));
closure->term = *term;
closure->store = store;
- struct cache *cache = malloc(sizeof(*cache));
+ struct cache *cache = gc_malloc(&gc, sizeof(*cache));
cache->box = box;
cache->term = new_term(CLOSURE);
cache->term->u.other = closure;
@@ -134,11 +133,9 @@ static int transition_2(struct stack **stack, struct term **term,
static int transition_3(struct term **term, struct store **store,
struct stack **stack, struct box *box)
{
- struct term *orig_term = *term;
- struct store *orig_store = *store;
assert(box->term->type == CLOSURE);
- struct cache *cache = malloc(sizeof(*cache));
+ struct cache *cache = gc_malloc(&gc, sizeof(*cache));
cache->box = box;
cache->term = new_term(VAR);
@@ -154,9 +151,8 @@ static int transition_3(struct term **term, struct store **store,
}
static int transition_4(struct stack **stack, struct term **term,
- struct store *store, struct box *box)
+ struct box *box)
{
- struct term *orig = *term;
*stack = *stack;
*term = box->term;
@@ -169,7 +165,6 @@ static int transition_5(struct stack **stack, struct term **term,
struct cache *cache = peek_term->u.other;
struct box *box = cache->box;
- struct term **orig = &box->term;
box->state = DONE;
box->term = *term;
@@ -183,9 +178,7 @@ static int transition_6(struct term **term, struct store **store,
struct stack **stack, struct term *peek_term,
struct closure *closure)
{
- struct term *orig = *term;
-
- struct box *box = malloc(sizeof(*box));
+ struct box *box = gc_malloc(&gc, sizeof(*box));
box->state = TODO;
box->term = peek_term->u.app.rhs;
@@ -200,15 +193,14 @@ static int transition_7(struct term **term, struct store **store,
struct stack **stack, struct box *box,
struct closure *closure)
{
- struct term *orig = *term;
int x = name_generator();
- struct box *var_box = malloc(sizeof(*var_box));
+ struct box *var_box = gc_malloc(&gc, sizeof(*var_box));
var_box->state = DONE;
var_box->term = new_term(VAR);
var_box->term->u.var.name = x;
- struct cache *cache = malloc(sizeof(*cache));
+ struct cache *cache = gc_malloc(&gc, sizeof(*cache));
cache->box = box;
cache->term = new_term(VAR);
@@ -231,8 +223,6 @@ static int transition_7(struct term **term, struct store **store,
static int transition_8(struct stack **stack, struct term **term,
struct box *box)
{
- struct term *orig = *term;
-
*stack = *stack;
*term = box->term;
@@ -242,8 +232,6 @@ static int transition_8(struct stack **stack, struct term **term,
static int transition_9(struct term **term, struct store **store,
struct stack **stack, struct term *peek_term)
{
- struct term *orig = *term;
-
struct closure *closure = peek_term->u.app.rhs->u.other;
struct term *app = new_term(APP);
@@ -260,8 +248,6 @@ static int transition_9(struct term **term, struct store **store,
static int transition_10(struct stack **stack, struct term **term,
struct term *peek_term)
{
- struct term *orig = *term;
-
struct term *app = new_term(APP);
app->u.app.lhs = peek_term->u.app.lhs;
app->u.app.rhs = *term;
@@ -275,8 +261,6 @@ static int transition_10(struct stack **stack, struct term **term,
static int transition_11(struct stack **stack, struct term **term,
struct term *peek_term)
{
- struct term *orig = *term;
-
struct term *abs = new_term(ABS);
abs->u.abs.name = peek_term->u.abs.name;
abs->u.abs.term = *term;
@@ -288,7 +272,7 @@ static int transition_11(struct stack **stack, struct term **term,
}
static int transition_closure(struct conf *conf, int i,
- void (*callback)(int, char))
+ void (*callback)(int, char, void *), void *data)
{
struct term *term = conf->u.econf.term;
struct store *store = conf->u.econf.store;
@@ -297,31 +281,30 @@ static int transition_closure(struct conf *conf, int i,
int ret = 1;
switch (term->type) {
case APP: // (1)
- callback(i, '1');
+ callback(i, '1', data);
ret = transition_1(&term, &store, &stack);
econf(conf, term, store, stack);
return ret;
case ABS: // (2)
- callback(i, '2');
+ callback(i, '2', data);
ret = transition_2(&stack, &term, store);
cconf(conf, stack, term);
return ret;
case VAR:;
struct box *box = store_get(store, &term->u.var.name, 0);
- int unbound = 0;
if (!box) {
- box = malloc(sizeof(*box));
+ box = gc_malloc(&gc, sizeof(*box));
box->state = DONE;
box->term = term;
}
if (box->state == TODO) { // (3)
- callback(i, '3');
+ callback(i, '3', data);
ret = transition_3(&term, &store, &stack, box);
econf(conf, term, store, stack);
return ret;
} else if (box->state == DONE) { // (4)
- callback(i, '4');
- ret = transition_4(&stack, &term, store, box);
+ callback(i, '4', data);
+ ret = transition_4(&stack, &term, box);
cconf(conf, stack, term);
return ret;
}
@@ -334,7 +317,7 @@ static int transition_closure(struct conf *conf, int i,
}
static int transition_computed(struct conf *conf, int i,
- void (*callback)(int, char))
+ void (*callback)(int, char, void *), void *data)
{
struct stack *stack = conf->u.cconf.stack;
struct term *term = conf->u.cconf.term;
@@ -348,7 +331,7 @@ static int transition_computed(struct conf *conf, int i,
struct cache *cache = peek_term->u.other;
struct term *cache_term = cache->term;
if (cache_term->type == VAR && !cache_term->u.var.name) {
- callback(i, '5');
+ callback(i, '5', data);
ret = transition_5(&stack, &term, peek_term);
cconf(conf, stack, term);
return ret;
@@ -361,7 +344,7 @@ static int transition_computed(struct conf *conf, int i,
struct closure *closure =
((struct cache *)term->u.other)->term->u.other;
if (closure->term->type == ABS) {
- callback(i, '6');
+ callback(i, '6', data);
struct store *store;
ret = transition_6(&term, &store, &stack, peek_term,
closure);
@@ -376,14 +359,14 @@ static int transition_computed(struct conf *conf, int i,
((struct cache *)term->u.other)->term->u.other;
if (closure->term->type == ABS && box->state == TODO &&
!box->term) { // (7)
- callback(i, '7');
+ callback(i, '7', data);
struct store *store;
ret = transition_7(&term, &store, &stack, box, closure);
econf(conf, term, store, stack);
return ret;
}
if (closure->term->type == ABS && box->state == DONE) { // (8)
- callback(i, '8');
+ callback(i, '8', data);
ret = transition_8(&stack, &term, box);
cconf(conf, stack, term);
return ret;
@@ -393,7 +376,7 @@ static int transition_computed(struct conf *conf, int i,
peek_term->u.app.lhs->type == VAR &&
!peek_term->u.app.lhs->u.var.name &&
peek_term->u.app.rhs->type == CLOSURE) { // (9)
- callback(i, '9');
+ callback(i, '9', data);
struct store *store;
ret = transition_9(&term, &store, &stack, peek_term);
econf(conf, term, store, stack);
@@ -402,7 +385,7 @@ static int transition_computed(struct conf *conf, int i,
if (peek_term && peek_term->type == APP &&
peek_term->u.app.rhs->type == VAR &&
!peek_term->u.app.rhs->u.var.name) { // (10)
- callback(i, 'A');
+ callback(i, 'A', data);
ret = transition_10(&stack, &term, peek_term);
cconf(conf, stack, term);
return ret;
@@ -410,7 +393,7 @@ static int transition_computed(struct conf *conf, int i,
if (peek_term && peek_term->type == ABS &&
peek_term->u.abs.term->type == VAR &&
!peek_term->u.abs.term->u.var.name) { // (11)
- callback(i, 'B');
+ callback(i, 'B', data);
ret = transition_11(&stack, &term, peek_term);
cconf(conf, stack, term);
return ret;
@@ -423,23 +406,25 @@ static int transition_computed(struct conf *conf, int i,
return 1;
}
-static int transition(struct conf *conf, int i, void (*callback)(int, char))
+static int transition(struct conf *conf, int i,
+ void (*callback)(int, char, void *), void *data)
{
if (conf->type == ECONF) {
- return transition_closure(conf, i, callback);
+ return transition_closure(conf, i, callback, data);
} else if (conf->type == CCONF) {
- return transition_computed(conf, i, callback);
+ return transition_computed(conf, i, callback, data);
}
fprintf(stderr, "Invalid transition state %x\n", conf->type);
return 1;
}
static struct conf *for_each_state(struct conf *conf, int i,
- void (*callback)(int, char))
+ void (*callback)(int, char, void *),
+ void *data)
{
int ret = 0;
while (!ret)
- ret = transition(conf, i++, callback);
+ ret = transition(conf, i++, callback, data);
return conf;
}
@@ -454,7 +439,8 @@ static uint32_t hash_var(void *key)
return murmur3_32((uint8_t *)key, sizeof(int), 0);
}
-struct term *reduce(struct term *term, void (*callback)(int, char))
+struct term *reduce(struct term *term, void (*callback)(int, char, void *),
+ void *data)
{
struct stack stack = { 0 };
struct store *store = store_new(hash_var, hash_var_equal);
@@ -464,9 +450,10 @@ struct term *reduce(struct term *term, void (*callback)(int, char))
.u.econf.store = store,
.u.econf.stack = &stack,
};
- for_each_state(&conf, 0, callback);
+ for_each_state(&conf, 0, callback, data);
assert(conf.type == CCONF);
struct term *ret = duplicate_term(conf.u.cconf.term);
+
return ret;
}