From 859c33f37f0174a7b9d76cdcbe889ff12047c99c Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 9 Oct 2021 19:00:17 +0200 Subject: Split main into separate files --- src/bootstrap/primitives.c | 151 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/bootstrap/primitives.c (limited to 'src/bootstrap/primitives.c') diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c new file mode 100644 index 0000000..50a2dfb --- /dev/null +++ b/src/bootstrap/primitives.c @@ -0,0 +1,151 @@ +void +display(Object *root) { + if (root == NULL) { + return; + } + + switch (root->type) { + case OBJ_TYPE_FIXNUM: { + printf("%zd", root->fixnum); + } break; + case OBJ_TYPE_BOOL: { + if (root->boolean) { + printf("true"); + } else { + printf("false"); + } + } break; + case OBJ_TYPE_NIL: { + printf("()"); + } break; + case OBJ_TYPE_STRING: { + printf("\"%.*s\"", (int)root->string_n, root->string); + } break; + case OBJ_TYPE_SYMBOL: { + printf(":%.*s", (int)root->symbol_n, root->symbol); + } break; + case OBJ_TYPE_PAIR: { + printf("("); + display_pair(root); + printf(")"); + } break; + default: { + printf("TYPE NOT IMPLEMENTED FOR DISPLAY."); + } break; + } +} + +Object * +eval(Object *root) { + if (root == NULL) { + return NULL; + } + + switch (root->type) { + case OBJ_TYPE_FIXNUM: + case OBJ_TYPE_BOOL: + case OBJ_TYPE_NIL: + case OBJ_TYPE_STRING: + case OBJ_TYPE_SYMBOL: { + return root; + } break; + case OBJ_TYPE_PAIR: { + if (root->car->type == OBJ_TYPE_SYMBOL) { + Object *value = find_environment_symbol(root->car); + if (value == NULL) { + printf("error: symbol not found: `"); + display(root->car); + printf("`\n"); + return NULL; + } + if (value->type == OBJ_TYPE_PROCEDURE) { + return value->proc(root->cdr); + } + } + } break; + default: { + printf("error: can't eval type %d.\n", root->type); + } break; + } + + return NULL; +} + +Object * +proc_add(Object *args) { + ssize_t tot = 0; + while (args->type == OBJ_TYPE_PAIR) { + Object *car = eval(args->car); + if (car->type != OBJ_TYPE_FIXNUM) { + fprintf(stderr, "addition not supported for type %d\n", car->type); + return NULL; + } + tot += car->fixnum; + args = args->cdr; + } + return make_fixnum(tot); +} + +Object * +proc_sub(Object *args) { + if (args->type != OBJ_TYPE_PAIR) { + fprintf(stderr, "substraction not supported for type %d\n", args->type); + return NULL; + } + + // Extract first parameter. + Object *car = eval(args->car); + args = args->cdr; + ssize_t tot = car->fixnum; + + while (args->type == OBJ_TYPE_PAIR) { + Object *car = eval(args->car); + if (car->type != OBJ_TYPE_FIXNUM) { + fprintf(stderr, "substraction not supported for type %d\n", car->type); + return NULL; + } + tot -= car->fixnum; + args = args->cdr; + } + return make_fixnum(tot); +} + +Object * +proc_mul(Object *args) { + ssize_t tot = 1; + while (args->type == OBJ_TYPE_PAIR) { + Object *car = eval(args->car); + if (car->type != OBJ_TYPE_FIXNUM) { + fprintf(stderr, "multiply not supported for type %d\n", car->type); + return NULL; + } + tot *= car->fixnum; + args = args->cdr; + } + return make_fixnum(tot); +} + +Object * +proc_div(Object *args) { + if (args->type != OBJ_TYPE_PAIR) { + fprintf(stderr, "substraction not supported for type %d\n", args->type); + return NULL; + } + + // Extract first parameter. + Object *car = eval(args->car); + args = args->cdr; + ssize_t tot = car->fixnum; + + while (args->type == OBJ_TYPE_PAIR) { + Object *car = eval(args->car); + if (car->type != OBJ_TYPE_FIXNUM) { + fprintf(stderr, "div not supported for type %d\n", car->type); + return NULL; + } + tot /= car->fixnum; + args = args->cdr; + } + return make_fixnum(tot); +} + -- cgit v1.2.1