@@ -1,88 +1,107 @@
11#ifndef _CLOSURE_H
22#define _CLOSURE_H
33
4+#include <stdlib.h>
5+#include <stdio.h>
6+#include <string.h>
7+#include <unistd.h>
8+#include <stdarg.h>
49
510// Closures
6−typedef void* VAL;
11+
12+typedef enum {
13+ CON, INT, FLOAT, STRING, UNIT, PTR
14+} ClosureType;
15+
16+typedef struct {
17+ int tag;
18+ int arity;
19+ void* args;
20+} con;
21+
22+typedef struct {
23+ ClosureType ty;
24+ union {
25+ con c;
26+ int i;
27+ double f;
28+ char* str;
29+ void* ptr;
30+ } info;
31+} Closure;
32+
33+typedef Closure* VAL;
734
835typedef struct {
936 VAL* valstack;
1037 int* intstack;
1138 double* floatstack;
12− VAL* valstack_ptr;
39+ VAL* valstack_top;
40+ VAL* valstack_base;
1341 int* intstack_ptr;
1442 double* floatstack_ptr;
1543 void* heap;
44+ void* heap_next;
1645 int stack_max;
1746 VAL ret;
1847} VM;
1948
2049VM* init_vm(int stack_size, size_t heap_size);
2150
22−// Functions all take a pointer to their VM, and return nothing.
23−typedef void(*func)(VM*);
51+// Functions all take a pointer to their VM, and previous stack base,
52+// and return nothing.
53+typedef void(*func)(VM*, VAL*);
2454
25−#define EXTEND(n) if (vm->valstack_ptr-vm->valstack + n < vm -> stack_max) \
26− { vm->valstack_ptr+=(n) } else { stackOverflow(vm); }
27−#define CLEAR(n) vm->valstack_ptr-=(n)
28−#define SLIDE(drop, keep) \
29− for (i=1; i<=keep; ++i) { \
30− *(vm->valstack_ptr-i-drop) = *(vm->valstack_ptr-i); \
31− } \
32− vm->valstack_ptr-=(drop)
55+// Register access
3356
34−typedef enum {
35− THUNK, CON, INT, FLOAT, STRING, UNIT, PTR
36−} ClosureType;
57+#define RVAL (vm->ret)
58+#define LOC(x) (*(vm->valstack_base + (x)))
59+#define TOP(x) (*(vm->valstack_top + (x)))
3760
38−typedef struct {
39− VAL fn;
40− int arity;
41− int numargs;
42− VAL* args;
43−} thunk;
61+// Retrieving values
4462
45−typedef struct {
46− int tag;
47− VAL* args;
48−} con;
63+#define GETSTR(x) (((VAL)(x))->info.str)
64+#define GETPTR(x) (((void*)(x))->info.ptr)
65+#define GETFLOAT(x) (((double)(x))->info.f)
4966
50−typedef struct {
51− ClosureType ty;
52− union {
53− thunk t;
54− con c;
55− int i;
56− double f;
57− char* str;
58− void* ptr;
59− } info;
60−} Closure;
67+#define TAG(x) ((x)->info.c.tag)
68+
69+// Integers, floats and operators
6170
62−// Stack manipulation instructions
71+typedef intptr_t i_int;
6372
64−#define PUSH(i) *(vm->valstack_ptr++) = i;
65−#define POP --vm->valstack_ptr;
73+#define MKINT(x) ((void*)((x)<<1)+1)
74+#define GETINT(x) ((i_int)(x)>>1)
75+#define ISINT(x) ((((i_int)x)&1) == 1)
6676
67−#define PUSHINT(i) *(vm->intstack_ptr++) = i;
68−#define POPINT --vm->intstack_ptr;
77+#define INTOP(op,x,y) MKINT((i_int)((((i_int)x)>>1) op (((i_int)y)>>1)))
78+#define FLOATOP(op,x,y) MKFLOAT(((GETFLOAT(x)) op (GETFLOAT(y))))
79+#define FLOATBOP(op,x,y) MKINT((i_int)(((GETFLOAT(x)) op (GETFLOAT(y)))))
80+#define ADD(x,y) (void*)(((i_int)x)+(((i_int)y)-1))
81+#define MULT(x,y) (MKINT((((i_int)x)>>1) * (((i_int)y)>>1)))
6982
70−#define PUSHFLOAT(i) *(vm->floatstack_ptr++) = i;
71−#define POPFLOAT --vm->floatstack_ptr;
83+// Stack management
7284
73−#define DISCARD(n) vm->valstack_ptr-=n;
74−#define DISCARDINT(n) vm->intstack_ptr-=n;
75−#define DISCARDFLOAT(n) vm->floatstack_ptr-=n;
85+#define INITFRAME VAL* myoldbase
86+#define REBASE vm->valstack_base = oldbase
87+#define RESERVE(x)
88+#define ADDTOP(x) vm->valstack_top += (x)
89+#define TOPBASE(x) vm->valstack_top = vm->valstack_base + (x)
90+#define BASETOP(x) vm->valstack_base = vm->valstack_top + (x)
91+#define STOREOLD myoldbase = vm->valstack_base
92+
93+#define CALL(f) f(vm, myoldbase);
94+#define TAILCALL(f) f(vm, oldbase);
7695
7796// Creating new values (each value placed at the top of the stack)
78−VAL mkInt(VM* vm, int val);
79−VAL mkFloat(VM* vm, double val);
80−VAL mkStr(VM* vm, char* str);
97+VAL MKFLOAT(VM* vm, double val);
98+VAL MKSTR(VM* vm, char* str);
99+
100+VAL MKCON(VM* vm, int tag, int arity, ...);
81101
82−VAL mkThunk(VM* vm, func fn, int args, int arity);
83−VAL mkCon(VM* vm, int tag, int arity);
102+void PROJECT(VM* vm, VAL r, int loc, int arity);
84103
85−void EVAL(int update);
104+void dumpVal(VAL r);
86105
87106// Handle stack overflow.
88107// Just reports an error and exits.