From eeff5e273f22aa28e81ab080e9ffdce85ac394b8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 09:59:31 +0200 Subject: Prepare skeleton for bytecode interpreter --- src/treewalk/objects.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/treewalk/objects.c (limited to 'src/treewalk/objects.c') diff --git a/src/treewalk/objects.c b/src/treewalk/objects.c new file mode 100644 index 0000000..c71bc40 --- /dev/null +++ b/src/treewalk/objects.c @@ -0,0 +1,141 @@ +#include "gc.h" +#include "objects.h" + +// +// Constructors. +// + +Object * +make_fixnum(ssize_t num) { + Object *obj = alloc_object(OBJ_TYPE_FIXNUM); + obj->fixnum = num; + return obj; +} + +Object * +make_procedure(Object *(*proc)(struct Environment *, struct Object *args)) { + Object *obj = alloc_object(OBJ_TYPE_PROCEDURE); + obj->proc = proc; + return obj; +} + +Object * +make_pair(Object *car, Object *cdr) { + Object *obj = alloc_object(OBJ_TYPE_PAIR); + obj->car = car; + obj->cdr = cdr; + return obj; +} + +Object * +make_symbol(StringView sv) { + Object *obj = alloc_object(OBJ_TYPE_SYMBOL); + obj->symbol = NULL; + array_init(obj->symbol, sv.n); + array_insert(obj->symbol, sv.start, sv.n); + return obj; +} + +Object * +make_string(void) { + Object *obj = alloc_object(OBJ_TYPE_STRING); + obj->string = NULL; + array_init(obj->string, 0); + return obj; +} + +void +append_string(Object *obj, const StringView sv) { + if (sv.n == 0) { + return; + } + array_insert(obj->string, sv.start, sv.n); +} + +void +display_pair(Object *root) { + display(root->car); + if (root->cdr->type == OBJ_TYPE_PAIR) { + printf(" "); + display_pair(root->cdr); + } else if (root->cdr == obj_nil) { + return; + } else { + printf(" . "); + display(root->cdr); + } +} + +void +display(Object *root) { + switch (root->type) { + case OBJ_TYPE_FIXNUM: { + printf("%zd", root->fixnum); + } break; + case OBJ_TYPE_BOOL: { + if (root == obj_true) { + printf("true"); + } else { + printf("false"); + } + } break; + case OBJ_TYPE_NIL: { + printf("()"); + } break; + case OBJ_TYPE_STRING: { + printf("\"%.*s\"", (int)array_size(root->string), root->string); + } break; + case OBJ_TYPE_SYMBOL: { + printf(":%.*s", (int)array_size(root->symbol), root->symbol); + } break; + case OBJ_TYPE_PAIR: { + printf("("); + display_pair(root); + printf(")"); + } break; + case OBJ_TYPE_LAMBDA: + case OBJ_TYPE_PROCEDURE: { + printf("#{procedure}"); + } break; + case OBJ_TYPE_ERR: { + printf("#{error}"); + } break; + } + return; +} + +bool +obj_eq(const Object *a, const Object* b) { + if (a->type != b->type) { + return false; + } + switch (a->type) { + case OBJ_TYPE_FIXNUM: { + return a->fixnum == b->fixnum; + } break; + case OBJ_TYPE_STRING: { + if (array_size(a->string) != array_size(b->string)) { + return false; + } + for (size_t i = 0; i < array_size(a->string); i++) { + if (a->string[i] != b->string[i]) { + return false; + } + } + } break; + case OBJ_TYPE_SYMBOL: { + if (array_size(a->symbol) != array_size(b->symbol)) { + return false; + } + for (size_t i = 0; i < array_size(a->symbol); i++) { + if (a->symbol[i] != b->symbol[i]) { + return false; + } + } + } break; + default: { + return a == b; + } break; + } + return true; +} -- cgit v1.2.1