/** * peano.c * * Basic peano arithmetic * * (c) 2017 Simon Brooke * Licensed under GPL version 2.0, or, at your option, any later version. */ #include #include #include #include #include #include #include "consspaceobject.h" #include "conspage.h" #include "equal.h" #include "integer.h" #include "intern.h" #include "lispops.h" #include "print.h" #include "read.h" #include "real.h" #include "stack.h" /** * Add 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_plus(struct stack_frame *frame, struct cons_pointer env) { struct cons_pointer result = NIL; long int i_accumulator = 0; long double d_accumulator = 0; 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 add: not a number"), frame); } if (! nilp(frame->more)) { lisp_throw( c_string_to_lisp_string("Cannot yet add more than 8 numbers"), frame); } if ( is_int) { result = make_integer( i_accumulator); } else { result = make_real( d_accumulator); } } return result; }