diff --git a/builtins.c b/builtins.c index 2f11570..1100c67 100644 --- a/builtins.c +++ b/builtins.c @@ -8,8 +8,6 @@ #include #include -// Evaluation -static struct Object *func_eval(struct Object *args); // Basic data structures static struct Object *func_cons(struct Object *args); static struct Object *func_quote(struct Object *args); @@ -32,8 +30,6 @@ static struct Object *func_newline(struct Object *args); static struct Object *func_sum(struct Object *args); static struct Object builtins[] = { - // Evaluation - { .type = TYPE_PROCEDURE, .procedure = { "eval", func_eval } }, // Basic data structures { .type = TYPE_PROCEDURE, .procedure = { "cons", func_cons } }, { .type = TYPE_PROCEDURE, .procedure = { "quote", func_quote } }, @@ -57,7 +53,7 @@ static struct Object builtins[] = { { .type = TYPE_PROCEDURE, .procedure = { NULL, NULL } }, }; -static struct Object *builtins_get(const char *name) +struct Object *builtins_get(const char *name) { for (size_t index = 0; builtins[index].procedure.name; ++index) { if (strcmp(name, builtins[index].procedure.name) == 0) { @@ -68,38 +64,6 @@ static struct Object *builtins_get(const char *name) abort(); } -struct Object *builtins_eval(struct Object *program) -{ - // NULL is an empty list, can't eval - assert(program); - - // Almost everything evaluates to itself - if (program->type != TYPE_PAIR && program->type != TYPE_SYMBOL) { - return program; - } - - // Symbols are variable names, but we can't lookup - assert(program->type != TYPE_SYMBOL); - - // The first item of pair should be an symbol - a function name - assert(program->pair.a && program->pair.a->type == TYPE_SYMBOL); - - return builtins_get(program->pair.a->s)->procedure.func(program->pair.b); -} - -/************** - * Evaluation * - **************/ - -struct Object *func_eval(struct Object *const args) -{ - assert(args); - assert(args->type == TYPE_PAIR); - assert(args->pair.b == NULL); - - return builtins_eval(args->pair.a); -} - /************************* * Basic data structures * *************************/ @@ -114,8 +78,8 @@ struct Object *func_cons(struct Object *const args) assert(args->pair.b->pair.a); assert(args->pair.b->pair.b == NULL); - struct Object *const car = builtins_eval(args->pair.a); - struct Object *const cdr = builtins_eval(args->pair.b->pair.a); + struct Object *const car = args->pair.a; + struct Object *const cdr = args->pair.b->pair.a; return Object_new_pair(car, cdr); } @@ -140,7 +104,7 @@ struct Object *func_booleanQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_BOOLEAN); } @@ -150,7 +114,7 @@ struct Object *func_charQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_CHAR); } @@ -160,7 +124,7 @@ struct Object *func_nullQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object == NULL); } @@ -170,7 +134,7 @@ struct Object *func_numberQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_NUMBER); } @@ -180,7 +144,7 @@ struct Object *func_pairQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_PAIR); } @@ -190,7 +154,7 @@ struct Object *func_stringQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_STRING); } @@ -200,7 +164,7 @@ struct Object *func_symbolQN(struct Object *args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; return Object_new_boolean(object && object->type == TYPE_SYMBOL); } @@ -214,7 +178,7 @@ struct Object *func_and(struct Object *args) while (args) { assert(args->type == TYPE_PAIR); - result = builtins_eval(args->pair.a); + result = args->pair.a; if (IS_FALSE(result)) break; args = args->pair.b; } @@ -228,7 +192,7 @@ struct Object *func_or(struct Object *args) while (args) { assert(args->type == TYPE_PAIR); - result = builtins_eval(args->pair.a); + result = args->pair.a; if (!IS_FALSE(result)) break; args = args->pair.b; } @@ -248,7 +212,7 @@ struct Object *func_display(struct Object *const args) assert(args->type == TYPE_PAIR); assert(args->pair.b == NULL); - struct Object *const object = builtins_eval(args->pair.a); + struct Object *const object = args->pair.a; if (!object) { printf("()"); diff --git a/builtins.h b/builtins.h index d53094f..dd64301 100644 --- a/builtins.h +++ b/builtins.h @@ -3,6 +3,6 @@ #include "object.h" -struct Object *builtins_eval(struct Object *args); +struct Object *builtins_get(const char *name); #endif diff --git a/main.c b/main.c index 18725df..33b9117 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,25 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); } +static struct Object *eval(struct Object *program) +{ + // NULL is an empty list, can't eval + assert(program); + + // Almost everything evaluates to itself + if (program->type != TYPE_PAIR && program->type != TYPE_SYMBOL) { + return program; + } + + // Symbols are variable names, but we can't lookup + assert(program->type != TYPE_SYMBOL); + + // The first item of pair should be an symbol - a function name + assert(program->pair.a && program->pair.a->type == TYPE_SYMBOL); + + return builtins_get(program->pair.a->s)->procedure.func(program->pair.b); +} + void run() { char chr; @@ -53,7 +72,7 @@ void run() Object_print(program, 0); printf("\n=== OUTPUT =======\n"); - struct Object *const result = builtins_eval(program); + struct Object *const result = eval(program); printf("\n\n=== RESULT =======\n"); Object_print(result, 0); @@ -78,16 +97,16 @@ void test() // #t // #t - assert(builtins_eval(sharp_true) == sharp_true); + assert(eval(sharp_true) == sharp_true); // 123 // 123 - assert(builtins_eval(num_123) == num_123); + assert(eval(num_123) == num_123); // (quote foo) // 'foo assert( - builtins_eval( + eval( Object_build_list(2, Object_new_symbol("quote"), sym_foo) ) == sym_foo ); @@ -95,7 +114,7 @@ void test() // (quote #t) // #t assert( - builtins_eval( + eval( Object_build_list(2, Object_new_symbol("quote"), sharp_true) ) == sharp_true ); @@ -103,7 +122,7 @@ void test() // (quote ()) // '() assert( - builtins_eval( + eval( Object_build_list(2, Object_new_symbol("quote"), NULL) ) == NULL ); @@ -111,7 +130,7 @@ void test() // (quote 123) // 123 assert( - builtins_eval( + eval( Object_build_list(2, Object_new_symbol("quote"), num_123) ) == num_123 ); @@ -120,7 +139,7 @@ void test() // #t { struct Object *const result = - builtins_eval(Object_build_list(1, Object_new_symbol("and"))); + eval(Object_build_list(1, Object_new_symbol("and"))); assert(IS_TRUE(result)); } @@ -128,14 +147,14 @@ void test() // #f { struct Object *const result = - builtins_eval(Object_build_list(1, Object_new_symbol("or"))); + eval(Object_build_list(1, Object_new_symbol("or"))); assert(IS_FALSE(result)); } // (and #t) // #t { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("and"), Object_new_boolean(true) @@ -146,7 +165,7 @@ void test() // (and 123) // 123 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("and"), num_123 @@ -157,7 +176,7 @@ void test() // (or #t) // #t { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("or"), Object_new_boolean(true) @@ -168,7 +187,7 @@ void test() // (or 123) // 123 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("or"), num_123 @@ -179,7 +198,7 @@ void test() // (and #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("and"), Object_new_boolean(false) @@ -190,7 +209,7 @@ void test() // (or #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 2, Object_new_symbol("or"), Object_new_boolean(false) @@ -201,7 +220,7 @@ void test() // (and #t #t) // #t { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), Object_new_boolean(true), @@ -213,7 +232,7 @@ void test() // (and 123 456) // 456 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), num_123, @@ -225,7 +244,7 @@ void test() // (and #f #t) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), Object_new_boolean(false), @@ -237,7 +256,7 @@ void test() // (and #f 123) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), Object_new_boolean(false), @@ -249,7 +268,7 @@ void test() // (and #t #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), Object_new_boolean(true), @@ -261,7 +280,7 @@ void test() // (and 123 #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), num_123, @@ -273,7 +292,7 @@ void test() // (and #f #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("and"), Object_new_boolean(false), @@ -285,7 +304,7 @@ void test() // (or #t #t) // #t { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), Object_new_boolean(true), @@ -297,7 +316,7 @@ void test() // (or 123 456) // 123 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), num_123, @@ -309,7 +328,7 @@ void test() // (or #f #t) // #t { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), Object_new_boolean(false), @@ -321,7 +340,7 @@ void test() // (or #f 123) // 123 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), Object_new_boolean(false), @@ -333,7 +352,7 @@ void test() // (or 123 #f) // 123 { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), num_123, @@ -345,7 +364,7 @@ void test() // (or #f #f) // #f { - struct Object *const result = builtins_eval(Object_build_list( + struct Object *const result = eval(Object_build_list( 3, Object_new_symbol("or"), Object_new_boolean(false), @@ -363,7 +382,7 @@ void test_booleanQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), NULL @@ -373,7 +392,7 @@ void test_booleanQN() // (boolean? #t) // #t - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_boolean(true) @@ -382,7 +401,7 @@ void test_booleanQN() // (boolean? #f) // #t - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_boolean(false) @@ -391,7 +410,7 @@ void test_booleanQN() // (boolean? #\n) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_char('\n') @@ -400,7 +419,7 @@ void test_booleanQN() // (boolean? 'foo) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_build_list( @@ -413,7 +432,7 @@ void test_booleanQN() // (boolean? "foo") // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_string("foo") @@ -422,7 +441,7 @@ void test_booleanQN() // (boolean? 123) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_number(123) @@ -433,7 +452,7 @@ void test_booleanQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("boolean?"), Object_new_pair(Object_new_number(123), Object_new_number(456)) @@ -450,7 +469,7 @@ void test_charQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), NULL @@ -460,7 +479,7 @@ void test_charQN() // (char? #t) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_boolean(true) @@ -469,7 +488,7 @@ void test_charQN() // (char? #f) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_boolean(false) @@ -478,7 +497,7 @@ void test_charQN() // (char? #\n) // #t - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_char('\n') @@ -487,7 +506,7 @@ void test_charQN() // (char? 'foo) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_build_list( @@ -500,7 +519,7 @@ void test_charQN() // (char? "foo") // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_string("foo") @@ -509,7 +528,7 @@ void test_charQN() // (char? 123) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_number(123) @@ -520,7 +539,7 @@ void test_charQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("char?"), Object_new_pair(Object_new_number(123), Object_new_number(456)) @@ -537,7 +556,7 @@ void test_nullQN() // #t // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), NULL @@ -547,7 +566,7 @@ void test_nullQN() // (null? #t) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_boolean(true) @@ -556,7 +575,7 @@ void test_nullQN() // (null? #f) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_boolean(false) @@ -565,7 +584,7 @@ void test_nullQN() // (null? #\n) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_char('\n') @@ -574,7 +593,7 @@ void test_nullQN() // (null? 'foo) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_build_list( @@ -587,7 +606,7 @@ void test_nullQN() // (null? "foo") // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_string("foo") @@ -596,7 +615,7 @@ void test_nullQN() // (null? 123) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_number(123) @@ -607,7 +626,7 @@ void test_nullQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("null?"), Object_new_pair(Object_new_number(123), Object_new_number(456)) @@ -624,7 +643,7 @@ void test_numberQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), NULL @@ -634,7 +653,7 @@ void test_numberQN() // (number? #t) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_boolean(true) @@ -643,7 +662,7 @@ void test_numberQN() // (number? #f) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_boolean(false) @@ -652,7 +671,7 @@ void test_numberQN() // (number? #\n) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_char('\n') @@ -661,7 +680,7 @@ void test_numberQN() // (number? 'foo) // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_build_list( @@ -674,7 +693,7 @@ void test_numberQN() // (number? "foo") // #f - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_string("foo") @@ -683,7 +702,7 @@ void test_numberQN() // (number? 123) // #t - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_number(123) @@ -694,7 +713,7 @@ void test_numberQN() // #f // TODO /* - result = builtins_eval(Object_build_list( + result = eval(Object_build_list( 2, Object_new_symbol("number?"), Object_new_pair(Object_new_number(123), Object_new_number(456))