#include #include #include struct stack; enum node_tag { NODE_APP, NODE_NUM, NODE_GLOBAL, NODE_IND, NODE_PACK }; struct node_base { enum node_tag tag; }; 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 stack*); }; 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_base* new_node = malloc(sizeof(struct node_app)); assert(new_node != NULL); return new_node; } struct stack { size_t size; size_t count; struct node_base** data; }; void stack_init(struct stack* s) { s->size = 0; s->count = 0; s->data = malloc(sizeof(*s->data) * s->size); assert(s->data != NULL); } void stack_free(struct stack* s) { free(s->data); } void stack_push(struct stack* s, struct node_base* n) { while(s->count >= s->size) { s->data = realloc(s->data, sizeof(*s->data) * (s->size *= 2)); assert(s->data != NULL); } s->data[s->count++] = n; } struct node_base* stack_pop(struct stack* s) { assert(s->count > 0); s->count--; } struct node_base* stack_peek(struct stack* s, size_t o) { assert(s->count > o); return s->data[s->count - o - 1]; } void stack_popn(struct stack* s, size_t n) { assert(s->count >= 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 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 stack_alloc(struct stack* s, size_t o) { while(o--) { struct node_ind* new_node = (struct node_ind*) alloc_node(); new_node->base.tag = NODE_IND; new_node->next = NULL; stack_push(s, (struct node_base*) new_node); } } void eval(struct node_base* n); extern void f_main(struct stack* s); int main(int argc, char** argv) { struct node_global* first_node = (struct node_global*) alloc_node(); first_node->base.tag = NODE_GLOBAL; first_node->arity = 0; first_node->function = f_main; eval((struct node_base*) first_node); }