85 lines
2.0 KiB
C
85 lines
2.0 KiB
C
#pragma once
|
|
#include <stdlib.h>
|
|
|
|
struct gmachine;
|
|
|
|
enum node_tag {
|
|
NODE_APP,
|
|
NODE_NUM,
|
|
NODE_GLOBAL,
|
|
NODE_IND,
|
|
NODE_DATA
|
|
};
|
|
|
|
struct node_base {
|
|
enum node_tag tag;
|
|
int8_t gc_reachable;
|
|
struct node_base* gc_next;
|
|
};
|
|
|
|
struct node_app {
|
|
struct node_base base;
|
|
struct node_base* left;
|
|
struct node_base* right;
|
|
};
|
|
|
|
struct node_num {
|
|
struct node_base base;
|
|
int32_t value;
|
|
};
|
|
|
|
struct node_global {
|
|
struct node_base base;
|
|
int32_t arity;
|
|
void (*function)(struct gmachine*);
|
|
};
|
|
|
|
struct node_ind {
|
|
struct node_base base;
|
|
struct node_base* next;
|
|
};
|
|
|
|
struct node_data {
|
|
struct node_base base;
|
|
int8_t tag;
|
|
struct node_base** array;
|
|
};
|
|
|
|
struct node_base* alloc_node();
|
|
struct node_app* alloc_app(struct node_base* l, struct node_base* r);
|
|
struct node_num* alloc_num(int32_t n);
|
|
struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a);
|
|
struct node_ind* alloc_ind(struct node_base* n);
|
|
void free_node_direct(struct node_base*);
|
|
void gc_visit_node(struct node_base*);
|
|
|
|
struct stack {
|
|
size_t size;
|
|
size_t count;
|
|
struct node_base** data;
|
|
};
|
|
|
|
void stack_init(struct stack* s);
|
|
void stack_free(struct stack* s);
|
|
void stack_push(struct stack* s, struct node_base* n);
|
|
struct node_base* stack_pop(struct stack* s);
|
|
struct node_base* stack_peek(struct stack* s, size_t o);
|
|
void stack_popn(struct stack* s, size_t n);
|
|
|
|
struct gmachine {
|
|
struct stack stack;
|
|
struct node_base* gc_nodes;
|
|
int64_t gc_node_count;
|
|
int64_t gc_node_threshold;
|
|
};
|
|
|
|
void gmachine_init(struct gmachine* g);
|
|
void gmachine_free(struct gmachine* g);
|
|
void gmachine_slide(struct gmachine* g, size_t n);
|
|
void gmachine_update(struct gmachine* g, size_t o);
|
|
void gmachine_alloc(struct gmachine* g, size_t o);
|
|
void gmachine_pack(struct gmachine* g, size_t n, int8_t t);
|
|
void gmachine_split(struct gmachine* g, size_t n);
|
|
struct node_base* gmachine_track(struct gmachine* g, struct node_base* b);
|
|
void gmachine_gc(struct gmachine* g);
|