#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(Object *a, 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; }