117 lines
1.6 KiB
C
117 lines
1.6 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
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);
|
|
}
|