From 43861f9d91782d864dc9866eee1d39288bb3a76d Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 10 Oct 2021 18:03:56 +0200 Subject: Add list manipulation primitives --- src/bootstrap/primitives.c | 51 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 8 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index f6b354e..6300067 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -610,26 +610,57 @@ proc_num_equal(Object *args) { Object * proc_car(Object *args) { - // TODO: stub - return NULL; + if (args == obj_nil) { + fprintf(stderr, "error: not enough arguments\n"); + return obj_nil; + } + Object *obj = eval(args->car); + if (obj->type != OBJ_TYPE_PAIR) { + fprintf(stderr, "error: wrong argument type\n"); + return obj_nil; + } + return obj->car; } Object * proc_cdr(Object *args) { - // TODO: stub - return NULL; + if (args == obj_nil) { + fprintf(stderr, "error: not enough arguments\n"); + return obj_nil; + } + Object *obj = eval(args->car); + if (obj->type != OBJ_TYPE_PAIR) { + fprintf(stderr, "error: wrong argument type\n"); + return obj_nil; + } + return obj->cdr; } Object * proc_cons(Object *args) { - // TODO: stub - return NULL; + if (args == obj_nil || args->cdr == obj_nil) { + fprintf(stderr, "error: not enough arguments\n"); + return obj_nil; + } + Object *a = eval(args->car); + Object *b = eval(args->cdr->car); + return make_pair(a, b); } Object * proc_list(Object *args) { - // TODO: stub - return NULL; + if (args == obj_nil) { + return obj_nil; + } + Object *head = make_pair(eval(args->car), obj_nil); + Object *curr = head; + args = args->cdr; + while (args != obj_nil) { + curr->cdr = make_pair(eval(args->car), obj_nil); + curr = curr->cdr; + args = args->cdr; + } + return head; } // @@ -639,6 +670,7 @@ proc_list(Object *args) { Object * proc_equal(Object *args) { // TODO: stub + (void) args; return NULL; } @@ -649,3 +681,6 @@ proc_equal(Object *args) { // TODO: LAMBDA // TODO: let // TODO: better error handling? +// TODO: Revise all instances where we are returning an object, since currently +// we may be returning a pointer to an object instead of a new one. Check also +// on eval function and everytime we do make_xxx(obj). -- cgit v1.2.1