Line data Source code
1 : #include <assert.h>
2 :
3 : #include "libstephen/lisp.h"
4 :
5 0 : void lisp_init(lisp_runtime *rt)
6 : {
7 0 : rt->nil = type_list->new();
8 0 : rt->nil->mark = 0;
9 0 : rt->nil->type = type_list;
10 0 : rt->nil->next = NULL;
11 0 : rt->head = rt->nil;
12 0 : rt->tail = rt->nil;
13 0 : rb_init(&rt->rb, sizeof(lisp_value*), 16);
14 0 : }
15 :
16 0 : void lisp_destroy(lisp_runtime *rt)
17 : {
18 0 : lisp_sweep(rt);
19 0 : rb_destroy(&rt->rb);
20 0 : lisp_free(rt->nil);
21 0 : }
22 :
23 0 : void lisp_mark(lisp_runtime *rt, lisp_value *v)
24 : {
25 0 : smb_status status = SMB_SUCCESS;
26 0 : rb_push_back(&rt->rb, &v);
27 :
28 0 : while (rt->rb.count > 0) {
29 0 : rb_pop_front(&rt->rb, &v);
30 0 : v->mark = GC_MARKED;
31 0 : smb_iter it = v->type->expand(v);
32 0 : while (it.has_next(&it)) {
33 0 : v = it.next(&it, &status).data_ptr;
34 0 : if (v->mark == GC_NOMARK) {
35 0 : v->mark = GC_QUEUED;
36 0 : rb_push_back(&rt->rb, &v);
37 : }
38 : }
39 0 : it.destroy(&it);
40 : }
41 0 : }
42 :
43 0 : void lisp_sweep(lisp_runtime *rt)
44 : {
45 0 : lisp_value *curr = rt->head;
46 :
47 0 : while (curr->next) {
48 0 : if (curr->next->mark != GC_MARKED) {
49 0 : lisp_value *tmp = curr->next->next;
50 0 : lisp_free(curr->next);
51 0 : curr->next = tmp;
52 : } else {
53 0 : curr->mark = GC_NOMARK;
54 0 : curr = curr->next;
55 : }
56 : }
57 :
58 0 : curr->mark = GC_NOMARK;
59 0 : rt->tail = curr;
60 0 : }
|