From 9a5fceac983db127de876c875a59307f8f2893ba Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 16 Oct 2021 11:30:07 +0200 Subject: Tag all objects as roots during parsing --- src/bootstrap/main.c | 129 +++++++++++++++++++++++++++------------------ src/bootstrap/objects.c | 25 ++++----- src/bootstrap/parser.c | 23 ++++++-- src/bootstrap/primitives.c | 1 + 4 files changed, 109 insertions(+), 69 deletions(-) (limited to 'src') 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) { obj_true = alloc_object(OBJ_TYPE_BOOL); obj_false = alloc_object(OBJ_TYPE_BOOL); obj_err = alloc_object(OBJ_TYPE_ERR); - - // Global environment. - global_env = env_create(NULL); - - // Primitive symbols. - MAKE_ENV_VAR(global_env, "else", obj_true); - MAKE_ENV_VAR(global_env, "nil", obj_nil); - - // Primitive procedures. - MAKE_ENV_PROC(global_env, "eval", proc_eval); - MAKE_ENV_PROC(global_env, "quote", proc_quote); - MAKE_ENV_PROC(global_env, "car", proc_car); - MAKE_ENV_PROC(global_env, "cdr", proc_cdr); - MAKE_ENV_PROC(global_env, "cons", proc_cons); - MAKE_ENV_PROC(global_env, "list", proc_list); - MAKE_ENV_PROC(global_env, "+", proc_sum); - MAKE_ENV_PROC(global_env, "-", proc_sub); - MAKE_ENV_PROC(global_env, "*", proc_mul); - MAKE_ENV_PROC(global_env, "/", proc_div); - MAKE_ENV_PROC(global_env, "%", proc_mod); - MAKE_ENV_PROC(global_env, "print", proc_print); - MAKE_ENV_PROC(global_env, "display", proc_display); - MAKE_ENV_PROC(global_env, "newline", proc_newline); - MAKE_ENV_PROC(global_env, "boolean?", proc_is_boolean); - MAKE_ENV_PROC(global_env, "nil?", proc_is_nil); - MAKE_ENV_PROC(global_env, "symbol?", proc_is_symbol); - MAKE_ENV_PROC(global_env, "string?", proc_is_string); - MAKE_ENV_PROC(global_env, "fixnum?", proc_is_fixnum); - MAKE_ENV_PROC(global_env, "pair?", proc_is_pair); - MAKE_ENV_PROC(global_env, "procedure?", proc_is_procedure); - MAKE_ENV_PROC(global_env, "error?", proc_is_error); - MAKE_ENV_PROC(global_env, "not", proc_not); - MAKE_ENV_PROC(global_env, "and", proc_and); - MAKE_ENV_PROC(global_env, "or", proc_or); - MAKE_ENV_PROC(global_env, "if", proc_if); - MAKE_ENV_PROC(global_env, "cond", proc_cond); - MAKE_ENV_PROC(global_env, "<", proc_num_less_than); - MAKE_ENV_PROC(global_env, "<=", proc_num_lesseq_than); - MAKE_ENV_PROC(global_env, ">", proc_num_greater_than); - MAKE_ENV_PROC(global_env, ">=", proc_num_greatereq_than); - MAKE_ENV_PROC(global_env, "=", proc_num_equal); - MAKE_ENV_PROC(global_env, "eq?", proc_equal); - MAKE_ENV_PROC(global_env, "def", proc_define); - MAKE_ENV_PROC(global_env, "set!", proc_set); - MAKE_ENV_PROC(global_env, "lambda", proc_lambda); - MAKE_ENV_PROC(global_env, "fun", proc_fun); - - // Runtime procedures. - MAKE_ENV_PROC(global_env, "supress-errors", proc_supress_errors); + obj_quote = make_symbol((StringView){"quote", 5}); + push_root(obj_nil); + push_root(obj_true); + push_root(obj_false); + push_root(obj_err); + push_root(obj_quote); + +// // Global environment. +// global_env = env_create(NULL); + +// // Primitive symbols. +// MAKE_ENV_VAR(global_env, "else", obj_true); +// MAKE_ENV_VAR(global_env, "nil", obj_nil); + +// // Primitive procedures. +// MAKE_ENV_PROC(global_env, "eval", proc_eval); +// MAKE_ENV_PROC(global_env, "quote", proc_quote); +// MAKE_ENV_PROC(global_env, "car", proc_car); +// MAKE_ENV_PROC(global_env, "cdr", proc_cdr); +// MAKE_ENV_PROC(global_env, "cons", proc_cons); +// MAKE_ENV_PROC(global_env, "list", proc_list); +// MAKE_ENV_PROC(global_env, "+", proc_sum); +// MAKE_ENV_PROC(global_env, "-", proc_sub); +// MAKE_ENV_PROC(global_env, "*", proc_mul); +// MAKE_ENV_PROC(global_env, "/", proc_div); +// MAKE_ENV_PROC(global_env, "%", proc_mod); +// MAKE_ENV_PROC(global_env, "print", proc_print); +// MAKE_ENV_PROC(global_env, "display", proc_display); +// MAKE_ENV_PROC(global_env, "newline", proc_newline); +// MAKE_ENV_PROC(global_env, "boolean?", proc_is_boolean); +// MAKE_ENV_PROC(global_env, "nil?", proc_is_nil); +// MAKE_ENV_PROC(global_env, "symbol?", proc_is_symbol); +// MAKE_ENV_PROC(global_env, "string?", proc_is_string); +// MAKE_ENV_PROC(global_env, "fixnum?", proc_is_fixnum); +// MAKE_ENV_PROC(global_env, "pair?", proc_is_pair); +// MAKE_ENV_PROC(global_env, "procedure?", proc_is_procedure); +// MAKE_ENV_PROC(global_env, "error?", proc_is_error); +// MAKE_ENV_PROC(global_env, "not", proc_not); +// MAKE_ENV_PROC(global_env, "and", proc_and); +// MAKE_ENV_PROC(global_env, "or", proc_or); +// MAKE_ENV_PROC(global_env, "if", proc_if); +// MAKE_ENV_PROC(global_env, "cond", proc_cond); +// MAKE_ENV_PROC(global_env, "<", proc_num_less_than); +// MAKE_ENV_PROC(global_env, "<=", proc_num_lesseq_than); +// MAKE_ENV_PROC(global_env, ">", proc_num_greater_than); +// MAKE_ENV_PROC(global_env, ">=", proc_num_greatereq_than); +// MAKE_ENV_PROC(global_env, "=", proc_num_equal); +// MAKE_ENV_PROC(global_env, "eq?", proc_equal); +// MAKE_ENV_PROC(global_env, "def", proc_define); +// MAKE_ENV_PROC(global_env, "set!", proc_set); +// MAKE_ENV_PROC(global_env, "lambda", proc_lambda); +// MAKE_ENV_PROC(global_env, "fun", proc_fun); + +// // Runtime procedures. +// MAKE_ENV_PROC(global_env, "supress-errors", proc_supress_errors); } void @@ -102,17 +108,40 @@ process_source(const StringView *source) { .current = 0, }; while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) { + // check the stack before parsing + size_t root_stack_size = gc.roots.size; Object *root = parse_tree(&visitor); + gc.roots.size = root_stack_size; + push_root(root); + // printf("AFTER: %ld\n", gc.roots.size); + // return the stack before parsing to previous state except we now have + // the root object as well. + // printf("-----------\n"); + // printf("ROOTS: \n"); + // for (size_t i = 0; i < gc.roots.size; i++) { + // display(gc.roots.buf[i]); + // printf("\n"); + // } + // printf("...........\n"); + for (size_t i = 0; i < gc.obj_cap; i++) { + Object *obj = &gc.obj_list[i]; + printf("marked? : %d ", obj->marked); + printf("type: %d ", obj->type); + display(obj); + printf("\n"); + } + // printf("===========\n"); if (root == obj_err || errors_n != 0) { break; } - // FIXME: Not freeing result or intermediate objects, can leak memory. Object *result = eval(global_env, root); if (result != obj_nil) { display(result); printf("\n"); } + pop_root(); + // mark_and_sweep(); } 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; typedef struct Object { ObjectType type; + bool marked; union { // OBJ_TYPE_FIXNUM ssize_t fixnum; @@ -56,17 +57,13 @@ static Object *obj_nil; static Object *obj_true; static Object *obj_false; static Object *obj_err; +static Object *obj_quote; // // Constructors. // -Object * -alloc_object(ObjectType type) { - Object *obj = malloc(sizeof(Object)); - obj->type = type; - return obj; -} +Object * alloc_object(ObjectType); Object * make_fixnum(ssize_t num) { @@ -141,14 +138,14 @@ obj_duplicate(Object *obj) { append_string(copy, (StringView){obj->string, obj->string_n}); } break; case OBJ_TYPE_PAIR: { - // Object *root = make_pair(obj_duplicate(obj->car), obj_nil); - // copy = root; - // obj = obj->cdr; - // while (obj != obj_nil) { - // root->cdr = make_pair(obj_duplicate(obj->car), obj_nil); - // root = root->cdr; - // obj = obj->cdr; - // } + Object *root = make_pair(obj_duplicate(obj->car), obj_nil); + copy = root; + obj = obj->cdr; + while (obj != obj_nil) { + root->cdr = make_pair(obj_duplicate(obj->car), obj_nil); + root = root->cdr; + obj = obj->cdr; + } } break; } 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) { return visitor->current < visitor->tokens.size; } +void push_root(Object*); + Object * parse_fixnum(Token tok) { ssize_t num = 0; @@ -30,7 +32,10 @@ parse_fixnum(Token tok) { } num = num * 10 + (c - '0'); } - return make_fixnum(num * sign); + + Object *obj = make_fixnum(num * sign); + push_root(obj); + return obj; } Object * parse_tree(Visitor *vs); @@ -41,11 +46,13 @@ parse_list(Visitor *vs) { if (tok.type == TOKEN_EOF) { return obj_err; } + Object *root = make_pair(obj_nil, obj_nil); + push_root(root); Object *next_obj = parse_tree(vs); if (next_obj == obj_err) { return obj_err; } - Object *root = make_pair(next_obj, obj_nil); + root->car = next_obj; Object *list = root; while (has_next_token(vs)) { Token tok = peek_token(vs); @@ -89,12 +96,15 @@ parse_tree(Visitor *vs) { return obj_err; } break; case TOKEN_QUOTE: { - Object *quote_sym = make_symbol((StringView){"quote", 5}); + Object *base = make_pair(obj_quote, obj_nil); + base->cdr = make_pair(obj_nil, obj_nil); + push_root(base); Object *next_obj = parse_tree(vs); if (next_obj == obj_err) { return obj_err; } - return make_pair(quote_sym, make_pair(next_obj, obj_nil)); + base->cdr->car = next_obj; + return base; } break; case TOKEN_LPAREN: { Object *obj = parse_list(vs); @@ -110,11 +120,14 @@ parse_tree(Visitor *vs) { } break; case TOKEN_STRING: { Object *obj = make_string(); + push_root(obj); append_string(obj, tok.value); return obj; } break; case TOKEN_SYMBOL: { - return make_symbol(tok.value); + Object *obj = make_symbol(tok.value); + push_root(obj); + return obj; } break; case TOKEN_NIL: { 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 @@ Object * eval(Environment* env, Object *root) { + return obj_nil; // DEBUG: gc switch (root->type) { case OBJ_TYPE_ERR: case OBJ_TYPE_PROCEDURE: -- cgit v1.2.1