#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 = malloc(sizeof(char) * sv.n); memcpy(obj->symbol, sv.start, sv.n); obj->symbol_n = sv.n; return obj; } Object * make_string(void) { Object *obj = alloc_object(OBJ_TYPE_STRING); obj->string = NULL; obj->string_n = 0; return obj; } void append_string(Object *obj, const StringView sv) { assert(obj != NULL); assert(obj->type == OBJ_TYPE_STRING); if (sv.n == 0) { return; } obj->string = realloc(obj->string, (obj->string_n + sv.n) * sizeof(char)); memcpy(obj->string + obj->string_n, sv.start, sv.n); obj->string_n += 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)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; 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 (a->string_n != b->string_n) { return false; } for (size_t i = 0; i < a->string_n; i++) { if (a->string[i] != b->string[i]) { return false; } } } break; case OBJ_TYPE_SYMBOL: { if (a->symbol_n != b->symbol_n) { return false; } for (size_t i = 0; i < a->symbol_n; i++) { if (a->symbol[i] != b->symbol[i]) { return false; } } } break; default: { return a == b; } break; } return true; }