diff --git a/builtins.c b/builtins.c index 37c1434..f1248c0 100644 --- a/builtins.c +++ b/builtins.c @@ -10,11 +10,29 @@ struct Builtin { struct Object *(*func)(struct Object *args); }; -static struct Object *func_sum(struct Object *numbers); +// Type predicates +static struct Object *func_booleanQN(struct Object *args); +static struct Object *func_charQN(struct Object *args); +static struct Object *func_nullQN(struct Object *args); +static struct Object *func_numberQN(struct Object *args); +static struct Object *func_pairQN(struct Object *args); +static struct Object *func_stringQN(struct Object *args); +static struct Object *func_symbolQN(struct Object *args); +// Other +static struct Object *func_sum(struct Object *args); static struct Builtin builtins[] = { - { "+", func_sum }, - { NULL, NULL }, + // Type predicates + { "boolean?", func_booleanQN }, + { "char?", func_charQN }, + { "null?", func_nullQN }, + { "number?", func_numberQN }, + { "pair?", func_pairQN }, + { "string?", func_stringQN }, + { "symbol?", func_symbolQN }, + // Other + { "+", func_sum }, + { NULL, NULL }, }; struct Object *builtins_call(const char *name, struct Object *args) @@ -28,21 +46,88 @@ struct Object *builtins_call(const char *name, struct Object *args) abort(); } -struct Object *func_sum(struct Object *const numbers) +struct Object *func_booleanQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return + Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_BOOLEAN); +} + +struct Object *func_charQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_CHAR); +} + +struct Object *func_nullQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return Object_new_boolean(args->pair.a == NULL); +} + +struct Object *func_numberQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return + Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_NUMBER); +} + +struct Object *func_pairQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_PAIR); +} + +struct Object *func_stringQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return + Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_STRING); +} + +struct Object *func_symbolQN(struct Object *args) +{ + assert(args); + assert(args->type == TYPE_PAIR); + assert(args->pair.b == NULL); + + return + Object_new_boolean(args->pair.a && args->pair.a->type == TYPE_SYMBOL); +} + +struct Object *func_sum(struct Object *const args) { struct Object *const object = Object_new_number(0); - if (!numbers) return object; + if (!args) return object; - assert(numbers->type == TYPE_PAIR); - assert(numbers->pair.a); - assert(numbers->pair.a->type == TYPE_NUMBER); + assert(args->type == TYPE_PAIR); + assert(args->pair.a); + assert(args->pair.a->type == TYPE_NUMBER); - object->i = numbers->pair.a->i; + object->i = args->pair.a->i; - if (!numbers->pair.b) return object; + if (!args->pair.b) return object; - struct Object *const b_sum = func_sum(numbers->pair.b); + struct Object *const b_sum = func_sum(args->pair.b); object->i += b_sum->i; diff --git a/object.c b/object.c index 681add9..900b8af 100644 --- a/object.c +++ b/object.c @@ -81,6 +81,12 @@ void Object_print(struct Object *const self, const unsigned indent) 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); @@ -88,7 +94,5 @@ void Object_print(struct Object *const self, const unsigned indent) case TYPE_NUMBER: printf("%li\n", self->i); break; - default: - break; } }