diff --git a/src/init.c b/src/init.c index b85b656..d5207f1 100644 --- a/src/init.c +++ b/src/init.c @@ -88,7 +88,8 @@ int main( int argc, char *argv[] ) { bind_function( "read", &lisp_read ); bind_function( "print", &lisp_print ); - bind_function( "plus", &lisp_plus); + bind_function( "add", &lisp_add); + bind_function( "multiply", &lisp_multiply); /* * primitive special forms diff --git a/src/peano.c b/src/peano.c index e39a58e..55da8ba 100644 --- a/src/peano.c +++ b/src/peano.c @@ -32,7 +32,7 @@ * @return a pointer to an integer or real. */ struct cons_pointer -lisp_plus(struct stack_frame *frame, struct cons_pointer env) { +lisp_add(struct stack_frame *frame, struct cons_pointer env) { struct cons_pointer result = NIL; long int i_accumulator = 0; long double d_accumulator = 0; @@ -71,3 +71,49 @@ lisp_plus(struct stack_frame *frame, struct cons_pointer env) { return result; } +/** + * Multiply an indefinite number of numbers together + * @param env the evaluation environment - ignored; + * @param frame the stack frame. + * @return a pointer to an integer or real. + */ +struct cons_pointer +lisp_multiply(struct stack_frame *frame, struct cons_pointer env) { + struct cons_pointer result = NIL; + long int i_accumulator = 1; + long double d_accumulator = 1; + bool is_int = true; + + for (int i = 0; i < args_in_frame && !nilp(frame->arg[i]); i++) { + struct cons_space_object arg = pointer2cell(frame->arg[i]); + + switch (arg.tag.value) { + case INTEGERTV: + i_accumulator *= arg.payload.integer.value; + d_accumulator *= numeric_value( frame->arg[i]); + break; + case REALTV: + d_accumulator *= arg.payload.real.value; + is_int = false; + default: + lisp_throw( + c_string_to_lisp_string("Cannot multiply: not a number"), + frame); + } + + if (! nilp(frame->more)) { + lisp_throw( + c_string_to_lisp_string("Cannot yet multiply more than 8 numbers"), + frame); + } + + if ( is_int) { + result = make_integer( i_accumulator); + } else { + result = make_real( d_accumulator); + } + } + + return result; +} + diff --git a/src/peano.h b/src/peano.h index b50f922..6c9c781 100644 --- a/src/peano.h +++ b/src/peano.h @@ -23,8 +23,16 @@ extern "C" { * @return a pointer to an integer or real. */ struct cons_pointer -lisp_plus(struct stack_frame *frame, struct cons_pointer env); +lisp_add(struct stack_frame *frame, struct cons_pointer env); +/** + * Multiply an indefinite number of numbers together + * @param env the evaluation environment - ignored; + * @param frame the stack frame. + * @return a pointer to an integer or real. + */ +struct cons_pointer +lisp_multiply(struct stack_frame *frame, struct cons_pointer env); #ifdef __cplusplus