From 645ab3674e3d4c1c9a2cc539231a6fefb4f2c374 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Fri, 7 Dec 2018 06:43:23 +0000 Subject: [PATCH] All unit tests pass. The eval-quote problem is solved. --- src/init.c | 2 +- src/lispops.c | 47 +++++++++++++++++------------------------------ 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/init.c b/src/init.c index e60ae76..6e5f398 100644 --- a/src/init.c +++ b/src/init.c @@ -86,6 +86,7 @@ int main( int argc, char *argv[] ) { bind_function( "cons", &lisp_cons ); bind_function( "eq", &lisp_eq ); bind_function( "equal", &lisp_equal ); + bind_function( "eval", &lisp_eval ); bind_function( "multiply", &lisp_multiply ); bind_function( "read", &lisp_read ); bind_function( "print", &lisp_print ); @@ -101,7 +102,6 @@ int main( int argc, char *argv[] ) { * primitive special forms */ bind_special( "cond", &lisp_cond ); - bind_function( "eval", &lisp_eval ); bind_special( "quote", &lisp_quote ); diff --git a/src/lispops.c b/src/lispops.c index 9523284..047870c 100644 --- a/src/lispops.c +++ b/src/lispops.c @@ -36,8 +36,6 @@ /* * also to create in this section: - * struct cons_pointer lisp_cond( struct cons_pointer args, struct cons_pointer env, - struct stack_frame* frame); * struct cons_pointer lisp_let( struct cons_pointer args, struct cons_pointer env, struct stack_frame* frame); * struct cons_pointer lisp_mapcar( struct cons_pointer args, struct cons_pointer env, @@ -74,9 +72,9 @@ struct cons_pointer c_cdr( struct cons_pointer arg ) { /** - * Useful building block; evaluate this single form in the context of this + * Useful building block; evaluate this single form in the context of this * parent stack frame and this environment. - * @param parent the parent stack frame. + * @param parent the parent stack frame. * @param form the form to be evaluated. * @param env the evaluation environment. * @return the result of evaluating the form. @@ -130,7 +128,7 @@ c_apply( struct stack_frame *frame, struct cons_pointer env ) { case FUNCTIONTV: /* - * actually, this is apply + * actually, this is apply */ { struct stack_frame *next = make_stack_frame( frame, args, env ); @@ -179,11 +177,11 @@ struct cons_pointer c_type( struct cons_pointer pointer ) { /** * (eval s_expr) * - * Special form. + * function. * If s_expr is a number, NIL, or T, returns s_expr. * If s_expr is an unprotected string, returns the value that s_expr is bound * to in the evaluation environment (env). - * If s_expr is a list, expects the car to be something that evaluates to a + * If s_expr is a list, expects the car to be something that evaluates to a * function or special form. * If a function, evaluates all the other top level elements in s_expr and * passes them in a stack frame as arguments to the function. @@ -200,17 +198,6 @@ lisp_eval( struct stack_frame *frame, struct cons_pointer env ) { switch ( cell.tag.value ) { case CONSTV: result = c_apply( frame, env ); - /* I have a profound misunderstanding of how quote and eval should interact! - * if ( equal( c_car(frame->arg[0]), c_string_to_lisp_symbol("quote"))) - * /\* car is QUOTE. TODO: It is ABSURDLY expensive to 'equal' each time! *\/ - * { - * /\* we need to eval it again *\/ - * frame->arg[0] = result; - * fputws( L"quote - re-evaling", stderr); - * dump_frame( stderr, frame ); - * result = c_apply(frame, env); - * } */ - break; case SYMBOLTV: @@ -227,11 +214,11 @@ lisp_eval( struct stack_frame *frame, struct cons_pointer env ) { } break; /* - * the Clojure practice of having a map serve in the function place of + * the Clojure practice of having a map serve in the function place of * an s-expression is a good one and I should adopt it; also if the * object is a consp it could be interpretable source code but in the - * long run I don't want an interpreter, and if I can get away without - * so much the better. + * long run I don't want an interpreter, and if I can get away without + * so much the better. */ } @@ -245,7 +232,7 @@ lisp_eval( struct stack_frame *frame, struct cons_pointer env ) { /** * (apply fn args) - * + * * function. Apply the function which is the result of evaluating the * first argoment to the list of arguments which is the result of evaluating * the second argument @@ -386,7 +373,7 @@ lisp_equal( struct stack_frame *frame, struct cons_pointer env ) { /** * (read) * (read read-stream) - * Read one complete lisp form and return it. If read-stream is specified and + * Read one complete lisp form and return it. If read-stream is specified and * is a read stream, then read from that stream, else stdin. */ struct cons_pointer @@ -404,7 +391,7 @@ lisp_read( struct stack_frame *frame, struct cons_pointer env ) { /** * (print expr) * (print expr write-stream) - * Print one complete lisp form and return NIL. If write-stream is specified and + * Print one complete lisp form and return NIL. If write-stream is specified and * is a write stream, then print to that stream, else stdout. */ struct cons_pointer @@ -434,13 +421,13 @@ lisp_type( struct stack_frame *frame, struct cons_pointer env ) { /** - * Function; evaluate the forms which are listed in my single argument + * Function; evaluate the forms which are listed in my single argument * sequentially and return the value of the last. This function is called 'do' * in some dialects of Lisp. - * + * * @param frame My stack frame. * @param env My environment (ignored). - * @return the value of the last form on the sequence which is my single + * @return the value of the last form on the sequence which is my single * argument. */ struct cons_pointer @@ -459,9 +446,9 @@ lisp_progn( struct stack_frame *frame, struct cons_pointer env ) { } /** - * Special form: conditional. Each arg is expected to be a list; if the first - * item in such a list evaluates to non-NIL, the remaining items in that list - * are evaluated in turn and the value of the last returned. If no arg (clause) + * Special form: conditional. Each arg is expected to be a list; if the first + * item in such a list evaluates to non-NIL, the remaining items in that list + * are evaluated in turn and the value of the last returned. If no arg (clause) * has a first element which evaluates to non NIL, then NIL is returned. * @param frame My stack frame. * @param env My environment (ignored).