-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathclosure.c
More file actions
81 lines (72 loc) · 1.41 KB
/
closure.c
File metadata and controls
81 lines (72 loc) · 1.41 KB
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
#include <stdlib.h>
#include <unistd.h>
#include "list.h"
#include "closure.h"
#include "gc.h"
envobj *
envitem(void *var, ssize_t size) {
envobj *env = malloc(sizeof(envobj));
env->val = var;
env->size = size;
gc_register((void *)env, ENVOBJ);
return env;
}
void *
unbox(list *l) {
envobj *env = (envobj *)l->val;
return env->val;
}
closure *
bind(closure *c, void *(*fn)(list *), envobj *env) {
closure *cl;
if (c == NULL) {
cl = malloc(sizeof(closure));
if (cl == NULL) {
exit(1);
}
cl->env = NULL;
cl->fn = fn;
gc_register((void *)cl, CLOSURE);
}
else {
cl = c;
}
cl->env = append(cl->env, (void *)env);
return cl;
}
void *
call(closure *c, envobj *env) {
list *copylist = copy(c->env);
copylist = append(copylist, (void *)env);
return c->fn(copylist);
}
//helper functions (syntactic sugar...erm...i guess...)
//these make using closures easier
envobj *
liftint(int a) {
int *v = malloc(sizeof(int));
*v = a;
gc_register((void *)v, STANDARD);
envobj *o = envitem((void *)v, sizeof(int));
return o;
}
void
envobj_free(void *_obj) {
envobj *obj = _obj;
free(obj);
}
list *
liftlist(list *l, ssize_t s) {
list *o = NULL;
list *curr;
for (curr = l; curr != NULL; curr = curr->next) {
envobj *lifted = envitem(curr->val, s);
o = append(o, (void *)lifted);
}
return o;
}
void
closure_free(void *_c) {
closure *c = _c;
free(c);
}