#include #include struct Int; struct String; struct Closure; union Value; enum Tag { VOID, INT, STRING, CLOSURE, CELL, ENV }; typedef union Value (*Lambda)() ; struct Int { enum Tag t; int value; }; struct String { enum Tag t; char* value; }; struct Closure { enum Tag t; Lambda lam; void* env; } ; struct Env { enum Tag t; void* env; }; struct Cell { enum Tag t; union Value* addr; } ; union Value { enum Tag t; struct Int z; struct String s; struct Closure clo; struct Env env; struct Cell cell; } ; typedef union Value Value; static Value MakeClosure(Lambda lam, Value env) { Value v; v.clo.t = CLOSURE; v.clo.lam = lam; v.clo.env = env.env.env; return v; } static Value MakeInt(int n) { Value v; v.z.t = INT; v.z.value = n; return v; } static Value MakeString(char* s) { Value v; v.s.t = STRING; v.s.value = s; return v; } static Value MakePrimitive(Lambda prim) { Value v; v.clo.t = CLOSURE; v.clo.lam = prim; v.clo.env = NULL; return v; } static Value MakeEnv(void* env) { Value v; v.env.t = ENV; v.env.env = env; return v; } static Value NewCell(Value initialValue) { Value v; v.cell.t = CELL; v.cell.addr = malloc(sizeof(Value)); *v.cell.addr = initialValue; return v; } Value sum(Value a, Value b) { return MakeInt(a.z.value + b.z.value); } Value product(Value a, Value b) { return MakeInt(a.z.value * b.z.value); } Value difference(Value a, Value b) { return MakeInt(a.z.value - b.z.value); } Value display(Value v) { printf("%i\n",v.z.value); return v; } Value equal(Value a, Value b) { return MakeInt(a.z.value == b.z.value); }