aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-16 11:30:07 +0200
committerBad Diode <bd@badd10de.dev>2021-10-16 11:30:07 +0200
commit9a5fceac983db127de876c875a59307f8f2893ba (patch)
treeb39fa873c4f7b6a9604fca062e071506b8a10943
parent4948ce511d0e96d34f165ed8d0a00e1d5f1caba9 (diff)
downloadbdl-9a5fceac983db127de876c875a59307f8f2893ba.tar.gz
bdl-9a5fceac983db127de876c875a59307f8f2893ba.zip
Tag all objects as roots during parsing
-rwxr-xr-xsrc/bootstrap/main.c129
-rw-r--r--src/bootstrap/objects.c25
-rw-r--r--src/bootstrap/parser.c23
-rw-r--r--src/bootstrap/primitives.c1
4 files changed, 109 insertions, 69 deletions
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index 575a924..ce1fdfe 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -36,55 +36,61 @@ init(void) {
36 obj_true = alloc_object(OBJ_TYPE_BOOL); 36 obj_true = alloc_object(OBJ_TYPE_BOOL);
37 obj_false = alloc_object(OBJ_TYPE_BOOL); 37 obj_false = alloc_object(OBJ_TYPE_BOOL);
38 obj_err = alloc_object(OBJ_TYPE_ERR); 38 obj_err = alloc_object(OBJ_TYPE_ERR);
39 39 obj_quote = make_symbol((StringView){"quote", 5});
40 // Global environment. 40 push_root(obj_nil);
41 global_env = env_create(NULL); 41 push_root(obj_true);
42 42 push_root(obj_false);
43 // Primitive symbols. 43 push_root(obj_err);
44 MAKE_ENV_VAR(global_env, "else", obj_true); 44 push_root(obj_quote);
45 MAKE_ENV_VAR(global_env, "nil", obj_nil); 45
46 46// // Global environment.
47 // Primitive procedures. 47// global_env = env_create(NULL);
48 MAKE_ENV_PROC(global_env, "eval", proc_eval); 48
49 MAKE_ENV_PROC(global_env, "quote", proc_quote); 49// // Primitive symbols.
50 MAKE_ENV_PROC(global_env, "car", proc_car); 50// MAKE_ENV_VAR(global_env, "else", obj_true);
51 MAKE_ENV_PROC(global_env, "cdr", proc_cdr); 51// MAKE_ENV_VAR(global_env, "nil", obj_nil);
52 MAKE_ENV_PROC(global_env, "cons", proc_cons); 52
53 MAKE_ENV_PROC(global_env, "list", proc_list); 53// // Primitive procedures.
54 MAKE_ENV_PROC(global_env, "+", proc_sum); 54// MAKE_ENV_PROC(global_env, "eval", proc_eval);
55 MAKE_ENV_PROC(global_env, "-", proc_sub); 55// MAKE_ENV_PROC(global_env, "quote", proc_quote);
56 MAKE_ENV_PROC(global_env, "*", proc_mul); 56// MAKE_ENV_PROC(global_env, "car", proc_car);
57 MAKE_ENV_PROC(global_env, "/", proc_div); 57// MAKE_ENV_PROC(global_env, "cdr", proc_cdr);
58 MAKE_ENV_PROC(global_env, "%", proc_mod); 58// MAKE_ENV_PROC(global_env, "cons", proc_cons);
59 MAKE_ENV_PROC(global_env, "print", proc_print); 59// MAKE_ENV_PROC(global_env, "list", proc_list);
60 MAKE_ENV_PROC(global_env, "display", proc_display); 60// MAKE_ENV_PROC(global_env, "+", proc_sum);
61 MAKE_ENV_PROC(global_env, "newline", proc_newline); 61// MAKE_ENV_PROC(global_env, "-", proc_sub);
62 MAKE_ENV_PROC(global_env, "boolean?", proc_is_boolean); 62// MAKE_ENV_PROC(global_env, "*", proc_mul);
63 MAKE_ENV_PROC(global_env, "nil?", proc_is_nil); 63// MAKE_ENV_PROC(global_env, "/", proc_div);
64 MAKE_ENV_PROC(global_env, "symbol?", proc_is_symbol); 64// MAKE_ENV_PROC(global_env, "%", proc_mod);
65 MAKE_ENV_PROC(global_env, "string?", proc_is_string); 65// MAKE_ENV_PROC(global_env, "print", proc_print);
66 MAKE_ENV_PROC(global_env, "fixnum?", proc_is_fixnum); 66// MAKE_ENV_PROC(global_env, "display", proc_display);
67 MAKE_ENV_PROC(global_env, "pair?", proc_is_pair); 67// MAKE_ENV_PROC(global_env, "newline", proc_newline);
68 MAKE_ENV_PROC(global_env, "procedure?", proc_is_procedure); 68// MAKE_ENV_PROC(global_env, "boolean?", proc_is_boolean);
69 MAKE_ENV_PROC(global_env, "error?", proc_is_error); 69// MAKE_ENV_PROC(global_env, "nil?", proc_is_nil);
70 MAKE_ENV_PROC(global_env, "not", proc_not); 70// MAKE_ENV_PROC(global_env, "symbol?", proc_is_symbol);
71 MAKE_ENV_PROC(global_env, "and", proc_and); 71// MAKE_ENV_PROC(global_env, "string?", proc_is_string);
72 MAKE_ENV_PROC(global_env, "or", proc_or); 72// MAKE_ENV_PROC(global_env, "fixnum?", proc_is_fixnum);
73 MAKE_ENV_PROC(global_env, "if", proc_if); 73// MAKE_ENV_PROC(global_env, "pair?", proc_is_pair);
74 MAKE_ENV_PROC(global_env, "cond", proc_cond); 74// MAKE_ENV_PROC(global_env, "procedure?", proc_is_procedure);
75 MAKE_ENV_PROC(global_env, "<", proc_num_less_than); 75// MAKE_ENV_PROC(global_env, "error?", proc_is_error);
76 MAKE_ENV_PROC(global_env, "<=", proc_num_lesseq_than); 76// MAKE_ENV_PROC(global_env, "not", proc_not);
77 MAKE_ENV_PROC(global_env, ">", proc_num_greater_than); 77// MAKE_ENV_PROC(global_env, "and", proc_and);
78 MAKE_ENV_PROC(global_env, ">=", proc_num_greatereq_than); 78// MAKE_ENV_PROC(global_env, "or", proc_or);
79 MAKE_ENV_PROC(global_env, "=", proc_num_equal); 79// MAKE_ENV_PROC(global_env, "if", proc_if);
80 MAKE_ENV_PROC(global_env, "eq?", proc_equal); 80// MAKE_ENV_PROC(global_env, "cond", proc_cond);
81 MAKE_ENV_PROC(global_env, "def", proc_define); 81// MAKE_ENV_PROC(global_env, "<", proc_num_less_than);
82 MAKE_ENV_PROC(global_env, "set!", proc_set); 82// MAKE_ENV_PROC(global_env, "<=", proc_num_lesseq_than);
83 MAKE_ENV_PROC(global_env, "lambda", proc_lambda); 83// MAKE_ENV_PROC(global_env, ">", proc_num_greater_than);
84 MAKE_ENV_PROC(global_env, "fun", proc_fun); 84// MAKE_ENV_PROC(global_env, ">=", proc_num_greatereq_than);
85 85// MAKE_ENV_PROC(global_env, "=", proc_num_equal);
86 // Runtime procedures. 86// MAKE_ENV_PROC(global_env, "eq?", proc_equal);
87 MAKE_ENV_PROC(global_env, "supress-errors", proc_supress_errors); 87// MAKE_ENV_PROC(global_env, "def", proc_define);
88// MAKE_ENV_PROC(global_env, "set!", proc_set);
89// MAKE_ENV_PROC(global_env, "lambda", proc_lambda);
90// MAKE_ENV_PROC(global_env, "fun", proc_fun);
91
92// // Runtime procedures.
93// MAKE_ENV_PROC(global_env, "supress-errors", proc_supress_errors);
88} 94}
89 95
90void 96void
@@ -102,17 +108,40 @@ process_source(const StringView *source) {
102 .current = 0, 108 .current = 0,
103 }; 109 };
104 while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) { 110 while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) {
111 // check the stack before parsing
112 size_t root_stack_size = gc.roots.size;
105 Object *root = parse_tree(&visitor); 113 Object *root = parse_tree(&visitor);
114 gc.roots.size = root_stack_size;
115 push_root(root);
116 // printf("AFTER: %ld\n", gc.roots.size);
117 // return the stack before parsing to previous state except we now have
118 // the root object as well.
119 // printf("-----------\n");
120 // printf("ROOTS: \n");
121 // for (size_t i = 0; i < gc.roots.size; i++) {
122 // display(gc.roots.buf[i]);
123 // printf("\n");
124 // }
125 // printf("...........\n");
126 for (size_t i = 0; i < gc.obj_cap; i++) {
127 Object *obj = &gc.obj_list[i];
128 printf("marked? : %d ", obj->marked);
129 printf("type: %d ", obj->type);
130 display(obj);
131 printf("\n");
132 }
133 // printf("===========\n");
106 if (root == obj_err || errors_n != 0) { 134 if (root == obj_err || errors_n != 0) {
107 break; 135 break;
108 } 136 }
109 137
110 // FIXME: Not freeing result or intermediate objects, can leak memory.
111 Object *result = eval(global_env, root); 138 Object *result = eval(global_env, root);
112 if (result != obj_nil) { 139 if (result != obj_nil) {
113 display(result); 140 display(result);
114 printf("\n"); 141 printf("\n");
115 } 142 }
143 pop_root();
144 // mark_and_sweep();
116 } 145 }
117 146
118 if (tokens.buf != NULL) { 147 if (tokens.buf != NULL) {
diff --git a/src/bootstrap/objects.c b/src/bootstrap/objects.c
index cf881a0..2bd5b1a 100644
--- a/src/bootstrap/objects.c
+++ b/src/bootstrap/objects.c
@@ -14,6 +14,7 @@ struct Environment;
14 14
15typedef struct Object { 15typedef struct Object {
16 ObjectType type; 16 ObjectType type;
17 bool marked;
17 union { 18 union {
18 // OBJ_TYPE_FIXNUM 19 // OBJ_TYPE_FIXNUM
19 ssize_t fixnum; 20 ssize_t fixnum;
@@ -56,17 +57,13 @@ static Object *obj_nil;
56static Object *obj_true; 57static Object *obj_true;
57static Object *obj_false; 58static Object *obj_false;
58static Object *obj_err; 59static Object *obj_err;
60static Object *obj_quote;
59 61
60// 62//
61// Constructors. 63// Constructors.
62// 64//
63 65
64Object * 66Object * alloc_object(ObjectType);
65alloc_object(ObjectType type) {
66 Object *obj = malloc(sizeof(Object));
67 obj->type = type;
68 return obj;
69}
70 67
71Object * 68Object *
72make_fixnum(ssize_t num) { 69make_fixnum(ssize_t num) {
@@ -141,14 +138,14 @@ obj_duplicate(Object *obj) {
141 append_string(copy, (StringView){obj->string, obj->string_n}); 138 append_string(copy, (StringView){obj->string, obj->string_n});
142 } break; 139 } break;
143 case OBJ_TYPE_PAIR: { 140 case OBJ_TYPE_PAIR: {
144 // Object *root = make_pair(obj_duplicate(obj->car), obj_nil); 141 Object *root = make_pair(obj_duplicate(obj->car), obj_nil);
145 // copy = root; 142 copy = root;
146 // obj = obj->cdr; 143 obj = obj->cdr;
147 // while (obj != obj_nil) { 144 while (obj != obj_nil) {
148 // root->cdr = make_pair(obj_duplicate(obj->car), obj_nil); 145 root->cdr = make_pair(obj_duplicate(obj->car), obj_nil);
149 // root = root->cdr; 146 root = root->cdr;
150 // obj = obj->cdr; 147 obj = obj->cdr;
151 // } 148 }
152 } break; 149 } break;
153 } 150 }
154 return copy; 151 return copy;
diff --git a/src/bootstrap/parser.c b/src/bootstrap/parser.c
index 869678e..77ece9d 100644
--- a/src/bootstrap/parser.c
+++ b/src/bootstrap/parser.c
@@ -18,6 +18,8 @@ has_next_token(const Visitor *visitor) {
18 return visitor->current < visitor->tokens.size; 18 return visitor->current < visitor->tokens.size;
19} 19}
20 20
21void push_root(Object*);
22
21Object * 23Object *
22parse_fixnum(Token tok) { 24parse_fixnum(Token tok) {
23 ssize_t num = 0; 25 ssize_t num = 0;
@@ -30,7 +32,10 @@ parse_fixnum(Token tok) {
30 } 32 }
31 num = num * 10 + (c - '0'); 33 num = num * 10 + (c - '0');
32 } 34 }
33 return make_fixnum(num * sign); 35
36 Object *obj = make_fixnum(num * sign);
37 push_root(obj);
38 return obj;
34} 39}
35 40
36Object * parse_tree(Visitor *vs); 41Object * parse_tree(Visitor *vs);
@@ -41,11 +46,13 @@ parse_list(Visitor *vs) {
41 if (tok.type == TOKEN_EOF) { 46 if (tok.type == TOKEN_EOF) {
42 return obj_err; 47 return obj_err;
43 } 48 }
49 Object *root = make_pair(obj_nil, obj_nil);
50 push_root(root);
44 Object *next_obj = parse_tree(vs); 51 Object *next_obj = parse_tree(vs);
45 if (next_obj == obj_err) { 52 if (next_obj == obj_err) {
46 return obj_err; 53 return obj_err;
47 } 54 }
48 Object *root = make_pair(next_obj, obj_nil); 55 root->car = next_obj;
49 Object *list = root; 56 Object *list = root;
50 while (has_next_token(vs)) { 57 while (has_next_token(vs)) {
51 Token tok = peek_token(vs); 58 Token tok = peek_token(vs);
@@ -89,12 +96,15 @@ parse_tree(Visitor *vs) {
89 return obj_err; 96 return obj_err;
90 } break; 97 } break;
91 case TOKEN_QUOTE: { 98 case TOKEN_QUOTE: {
92 Object *quote_sym = make_symbol((StringView){"quote", 5}); 99 Object *base = make_pair(obj_quote, obj_nil);
100 base->cdr = make_pair(obj_nil, obj_nil);
101 push_root(base);
93 Object *next_obj = parse_tree(vs); 102 Object *next_obj = parse_tree(vs);
94 if (next_obj == obj_err) { 103 if (next_obj == obj_err) {
95 return obj_err; 104 return obj_err;
96 } 105 }
97 return make_pair(quote_sym, make_pair(next_obj, obj_nil)); 106 base->cdr->car = next_obj;
107 return base;
98 } break; 108 } break;
99 case TOKEN_LPAREN: { 109 case TOKEN_LPAREN: {
100 Object *obj = parse_list(vs); 110 Object *obj = parse_list(vs);
@@ -110,11 +120,14 @@ parse_tree(Visitor *vs) {
110 } break; 120 } break;
111 case TOKEN_STRING: { 121 case TOKEN_STRING: {
112 Object *obj = make_string(); 122 Object *obj = make_string();
123 push_root(obj);
113 append_string(obj, tok.value); 124 append_string(obj, tok.value);
114 return obj; 125 return obj;
115 } break; 126 } break;
116 case TOKEN_SYMBOL: { 127 case TOKEN_SYMBOL: {
117 return make_symbol(tok.value); 128 Object *obj = make_symbol(tok.value);
129 push_root(obj);
130 return obj;
118 } break; 131 } break;
119 case TOKEN_NIL: { 132 case TOKEN_NIL: {
120 return obj_nil; 133 return obj_nil;
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c
index 4c3e4c6..35208b0 100644
--- a/src/bootstrap/primitives.c
+++ b/src/bootstrap/primitives.c
@@ -2,6 +2,7 @@
2 2
3Object * 3Object *
4eval(Environment* env, Object *root) { 4eval(Environment* env, Object *root) {
5 return obj_nil; // DEBUG: gc
5 switch (root->type) { 6 switch (root->type) {
6 case OBJ_TYPE_ERR: 7 case OBJ_TYPE_ERR:
7 case OBJ_TYPE_PROCEDURE: 8 case OBJ_TYPE_PROCEDURE: