From bb58afb57221eb0316d6ee14e19c5f4c4a822ba1 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 16 Oct 2021 21:22:08 +0200 Subject: Add a working GC with mark-and-sweep --- src/bootstrap/primitives.c | 47 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'src/bootstrap/primitives.c') diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 35208b0..abb87e7 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -2,7 +2,6 @@ Object * eval(Environment* env, Object *root) { - return obj_nil; // DEBUG: gc switch (root->type) { case OBJ_TYPE_ERR: case OBJ_TYPE_PROCEDURE: @@ -95,7 +94,8 @@ eval_lambda: }; root = root->cdr; } - return eval(env, root->car); + root = eval(env, root->car); + return root; } } break; } @@ -630,9 +630,20 @@ proc_cons(Environment *env, Object *obj) { }); return obj_err; } - Object *a = eval(env, obj->car); - Object *b = eval(env, obj->cdr->car); - return make_pair(a, b); + Object *head = make_pair(obj_nil, obj_nil); + push_root(head); + head->car = eval(env, obj->car); + if (head->car == obj_err) { + pop_root(); + return obj_err; + } + head->cdr = eval(env, obj->cdr->car); + if (head->cdr == obj_err) { + pop_root(); + return obj_err; + } + pop_root(); + return head; } Object * @@ -640,14 +651,28 @@ proc_list(Environment *env, Object *obj) { if (obj == obj_nil) { return obj_nil; } - Object *head = make_pair(eval(env, obj->car), obj_nil); + + Object *head = make_pair(obj_nil, obj_nil); + push_root(head); + Object *tmp = eval(env, obj->car); + if (tmp == obj_err) { + pop_root(); + return obj_err; + } + head->car = tmp; Object *curr = head; obj = obj->cdr; while (obj != obj_nil) { - curr->cdr = make_pair(eval(env, obj->car), obj_nil); + tmp = eval(env, obj->car); + if (tmp == obj_err) { + pop_root(); + return obj_err; + } + curr->cdr = make_pair(tmp, obj_nil); curr = curr->cdr; obj = obj->cdr; } + pop_root(); return head; } @@ -753,8 +778,8 @@ proc_lambda(Environment *env, Object *obj) { } Object *body = obj->cdr; Object *fun = alloc_object(OBJ_TYPE_LAMBDA); - fun->params = obj_duplicate(params); - fun->body = obj_duplicate(body); + fun->params = params; + fun->body = body; fun->env = env; return fun; } @@ -788,8 +813,8 @@ proc_fun(Environment *env, Object *obj) { } Object *body = obj->cdr->cdr; Object *fun = alloc_object(OBJ_TYPE_LAMBDA); - fun->params = obj_duplicate(params); - fun->body = obj_duplicate(body); + fun->params = params; + fun->body = body; fun->env = env; env_add_or_update_current(env, name, fun); return obj_nil; -- cgit v1.2.1