-
Notifications
You must be signed in to change notification settings - Fork 0
/
PrimFun.c
96 lines (82 loc) · 2.97 KB
/
PrimFun.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <gc.h>
#include "Error.h"
#include "PrimFun.h"
Struct* newPrimFun1(Struct* (*f) (Struct*)) {
return singleton_struct(PRIMFUN1_SYMBOL, (void*)f);
}
Struct* newPrimFun2(Struct* (*f) (Struct*, Struct*)) {
return singleton_struct(PRIMFUN2_SYMBOL, (void*)f);
}
static Struct* newCloHalf(Struct* (*f) (Struct*, Struct*), Struct* x) {
void** s = (void**)GC_MALLOC(sizeof(void*)*2);
s[0] = (void*)f;
s[1] = (void*)x;
return new_struct(CLOHALF_SYMBOL, 2, s);
}
Struct* newPrimFun3(Struct* (*f) (Struct*, Struct*, Struct*)) {
return singleton_struct(PRIMFUN3_SYMBOL, (void*)f);
}
static Struct* newCloOneThird(Struct* (*f) (Struct*, Struct*, Struct*), Struct* x) {
void** s = (void**)GC_MALLOC(sizeof(void*)*2);
s[0] = (void*)f;
s[1] = (void*)x;
return new_struct(CLOTHIRD_SYMBOL, 2, s);
}
static Struct* newCloTwoThird(Struct* (*f) (Struct*, Struct*, Struct*), Struct* x, Struct* y) {
void** s = (void**)GC_MALLOC(sizeof(void*)*3);
s[0] = (void*)f;
s[1] = (void*)x;
s[2] = (void*)y;
return new_struct(TWOTHIRD_SYMBOL, 3, s);
}
static Struct* apPrimFun1(Struct* closure, Struct* x) {
Struct* (*f) (Struct*) = (Struct* (*) (Struct*))singleton_payload(closure);
return f(x);
}
static Struct* apPrimFun2(Struct* closure, Struct* x) {
Struct* (*f) (Struct*, Struct*);
f = (Struct* (*) (Struct*, Struct*))singleton_payload(closure);
return newCloHalf(f, x);
}
static Struct* apPrimFun3(Struct* closure, Struct* x) {
Struct* (*f) (Struct*, Struct*, Struct*);
f = (Struct* (*) (Struct*, Struct*, Struct*))singleton_payload(closure);
return newCloOneThird(f, x);
}
static Struct* apCloHalf(Struct* closure, Struct* y) {
Struct* (*f) (Struct*, Struct*);
f = (Struct* (*) (Struct*, Struct*))get_field(closure, 0);
Struct* x = (Struct*)get_field(closure, 1);
return f(x, y);
}
static Struct* apOneThird(Struct* closure, Struct* y) {
Struct* (*f) (Struct*, Struct*, Struct*);
f = (Struct* (*) (Struct*, Struct*, Struct*))get_field(closure, 0);
Struct* x = (Struct*)get_field(closure, 1);
return newCloTwoThird(f, x, y);
}
static Struct* apTwoThird(Struct* closure, Struct* z) {
Struct* (*f) (Struct*, Struct*, Struct*);
f = (Struct* (*) (Struct*, Struct*, Struct*))get_field(closure, 0);
Struct* x = (Struct*)get_field(closure, 1);
Struct* y = (Struct*)get_field(closure, 2);
return f(x, y, z);
}
Struct* apply(Struct* f, Struct* arg) {
Struct* x = NULL;
Symbol tag = get_tag(f);
switch (tag) {
case PRIMFUN1_SYMBOL: x = apPrimFun1(f, arg); break;
case PRIMFUN2_SYMBOL: x = apPrimFun2(f, arg); break;
case CLOHALF_SYMBOL : x = apCloHalf(f, arg) ; break;
case PRIMFUN3_SYMBOL: x = apPrimFun3(f, arg); break;
case CLOTHIRD_SYMBOL: x = apOneThird(f, arg); break;
case TWOTHIRD_SYMBOL: x = apTwoThird(f, arg); break;
case ERROR_SYMBOL : x = f ; break;
default : x = inapplicable(tag) ; break;
}
return x;
}
void printPrimFun(FILE* stream, Struct* f) {
fprintf(stream, "<#%s>", decompressSymbol(get_tag(f)));
}