#include "enums.h" #include "object.h" #include #include #include #include #include static struct Object *new(const enum Type type) { struct Object *const object = malloc(sizeof(struct Object)); assert(object); memset(object, 0, sizeof(struct Object)); object->type = type; return object; } struct Object *Object_new_procedure( const char *const name, struct Object *(*const func)(struct Object *args) ) { struct Object *const object = new(TYPE_PROCEDURE); object->procedure.name = NULL; if (name && name[0]) { object->procedure.name = malloc(strlen(name) + 1); assert(object->procedure.name); strcpy(object->procedure.name, name); } object->procedure.func = func; return object; } struct Object *Object_new_pair(struct Object *const a, struct Object *const b) { struct Object *const object = new(TYPE_PAIR); object->pair.a = a; object->pair.b = b; return object; } struct Object *Object_new_boolean(const bool boolean) { struct Object *const object = new(TYPE_BOOLEAN); object->boolean = boolean; return object; } struct Object *Object_new_char(const char chr) { struct Object *const object = new(TYPE_CHAR); object->chr = chr; return object; } struct Object *Object_new_symbol(const char *const s) { struct Object *const object = new(TYPE_SYMBOL); object->s = malloc(strlen(s) + 1); assert(object->s); strcpy(object->s, s); return object; } struct Object *Object_new_string(const char *const s) { struct Object *const object = new(TYPE_STRING); object->s = malloc(strlen(s) + 1); assert(object->s); strcpy(object->s, s); return object; } struct Object *Object_new_number(const int64_t i) { struct Object *const object = new(TYPE_NUMBER); object->i = i; return object; } struct Object *Object_build_list(int count, ...) { assert(count > 0); va_list va; va_start(va, count); struct Object *last = NULL; struct Object *list = Object_new_pair(va_arg(va, struct Object*), last); --count; while (count-- > 0) { struct Object *new_pair = Object_new_pair(va_arg(va, struct Object*), NULL); if (last) { last->pair.b = new_pair; last = new_pair; } else { last = new_pair; list->pair.b = last; } } va_end(va); return list; } void Object_print(struct Object *const self, const unsigned indent) { for (unsigned index = 0; index < indent; ++index) { printf(" "); } if (!self) { printf("NULL\n"); return; } printf("%s:", Type_to_str(self->type)); switch (self->type) { case TYPE_PROCEDURE: if (self->procedure.name) { printf("#\n", self->procedure.name); } else { printf("#\n"); } break; case TYPE_PAIR: printf("\n"); Object_print(self->pair.a, indent + 1); Object_print(self->pair.b, indent + 1); break; case TYPE_BOOLEAN: printf("%s\n", self->boolean ? "#t" : "#f"); break; case TYPE_CHAR: printf("%c\n", self->chr); break; case TYPE_SYMBOL: case TYPE_STRING: printf("%s\n", self->s); break; case TYPE_NUMBER: printf("%li\n", self->i); break; } }