Track allocated nodes using a G-machine struct in compiler series.

This commit is contained in:
2020-02-06 10:05:17 -08:00
parent 153349f3d5
commit 281dbbd174
5 changed files with 163 additions and 93 deletions

View File

@@ -25,7 +25,7 @@ struct node_num* alloc_num(int32_t n) {
return node;
}
struct node_global* alloc_global(void (*f)(struct stack*), int32_t a) {
struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) {
struct node_global* node = (struct node_global*) alloc_node();
node->base.tag = NODE_GLOBAL;
node->arity = a;
@@ -40,6 +40,12 @@ struct node_ind* alloc_ind(struct node_base* n) {
return node;
}
void free_node_direct(struct node_base* n) {
if(n->tag == NODE_DATA) {
free(((struct node_data*) n)->array);
}
}
void stack_init(struct stack* s) {
s->size = 4;
s->count = 0;
@@ -74,49 +80,81 @@ void stack_popn(struct stack* s, size_t n) {
s->count -= n;
}
void stack_slide(struct stack* s, size_t n) {
assert(s->count > n);
s->data[s->count - n - 1] = s->data[s->count - 1];
s->count -= n;
void gmachine_init(struct gmachine* g) {
stack_init(&g->stack);
g->nodes = NULL;
}
void stack_update(struct stack* s, size_t o) {
assert(s->count > o + 1);
struct node_ind* ind = (struct node_ind*) s->data[s->count - o - 2];
ind->base.tag = NODE_IND;
ind->next = s->data[s->count -= 1];
}
void gmachine_free(struct gmachine* g) {
stack_free(&g->stack);
struct node_base* to_free = g->nodes;
struct node_base* next;
void stack_alloc(struct stack* s, size_t o) {
while(o--) {
stack_push(s, (struct node_base*) alloc_ind(NULL));
while(to_free) {
next = to_free->gc_next;
free_node_direct(to_free);
free(to_free);
to_free = next;
}
}
void stack_pack(struct stack* s, size_t n, int8_t t) {
assert(s->count >= n);
void gmachine_slide(struct gmachine* g, size_t n) {
assert(g->stack.count > n);
g->stack.data[g->stack.count - n - 1] = g->stack.data[g->stack.count - 1];
g->stack.count -= n;
}
void gmachine_update(struct gmachine* g, size_t o) {
assert(g->stack.count > o + 1);
struct node_ind* ind =
(struct node_ind*) g->stack.data[g->stack.count - o - 2];
ind->base.tag = NODE_IND;
ind->next = g->stack.data[g->stack.count -= 1];
}
void gmachine_alloc(struct gmachine* g, size_t o) {
while(o--) {
stack_push(&g->stack,
gmachine_track(g, (struct node_base*) alloc_ind(NULL)));
}
}
void gmachine_pack(struct gmachine* g, size_t n, int8_t t) {
assert(g->stack.count >= n);
struct node_base** data = malloc(sizeof(*data) * n);
assert(data != NULL);
memcpy(data, &s->data[s->count - n], n * sizeof(*data));
memcpy(data, &g->stack.data[g->stack.count - n], n * sizeof(*data));
struct node_data* new_node = (struct node_data*) alloc_node();
new_node->array = data;
new_node->base.tag = NODE_DATA;
new_node->tag = t;
stack_popn(s, n);
stack_push(s, (struct node_base*) new_node);
stack_popn(&g->stack, n);
stack_push(&g->stack, gmachine_track(g, (struct node_base*) new_node));
}
void stack_split(struct stack* s, size_t n) {
struct node_data* node = (struct node_data*) stack_pop(s);
void gmachine_split(struct gmachine* g, size_t n) {
struct node_data* node = (struct node_data*) stack_pop(&g->stack);
for(size_t i = 0; i < n; i++) {
stack_push(s, node->array[i]);
stack_push(&g->stack, node->array[i]);
}
}
void unwind(struct stack* s) {
struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) {
b->gc_next = g->nodes;
g->nodes = b;
return b;
}
void gmachine_gc(struct gmachine* g) {
}
void unwind(struct gmachine* g) {
struct stack* s = &g->stack;
while(1) {
struct node_base* peek = stack_peek(s, 0);
if(peek->tag == NODE_APP) {
@@ -131,7 +169,7 @@ void unwind(struct stack* s) {
= ((struct node_app*) s->data[s->count - i - 1])->right;
}
n->function(s);
n->function(g);
} else if(peek->tag == NODE_IND) {
struct node_ind* n = (struct node_ind*) peek;
stack_pop(s);
@@ -142,17 +180,7 @@ void unwind(struct stack* s) {
}
}
struct node_base* eval(struct node_base* n) {
struct stack program_stack;
stack_init(&program_stack);
stack_push(&program_stack, n);
unwind(&program_stack);
struct node_base* result = stack_pop(&program_stack);
stack_free(&program_stack);
return result;
}
extern void f_main(struct stack* s);
extern void f_main(struct gmachine* s);
void print_node(struct node_base* n) {
if(n->tag == NODE_APP) {
@@ -174,10 +202,17 @@ void print_node(struct node_base* n) {
}
int main(int argc, char** argv) {
struct gmachine gmachine;
struct node_global* first_node = alloc_global(f_main, 0);
struct node_base* result = eval((struct node_base*) first_node);
struct node_base* result;
gmachine_init(&gmachine);
gmachine_track(&gmachine, (struct node_base*) first_node);
stack_push(&gmachine.stack, (struct node_base*) first_node);
unwind(&gmachine);
result = stack_pop(&gmachine.stack);
printf("Result: ");
print_node(result);
putchar('\n');
gmachine_free(&gmachine);
}