Add and multiply now work, but robustly.
This commit is contained in:
parent
0826dcfdda
commit
648a4cd522
|
@ -88,7 +88,8 @@ int main( int argc, char *argv[] ) {
|
||||||
bind_function( "read", &lisp_read );
|
bind_function( "read", &lisp_read );
|
||||||
bind_function( "print", &lisp_print );
|
bind_function( "print", &lisp_print );
|
||||||
|
|
||||||
bind_function( "plus", &lisp_plus);
|
bind_function( "add", &lisp_add);
|
||||||
|
bind_function( "multiply", &lisp_multiply);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* primitive special forms
|
* primitive special forms
|
||||||
|
|
48
src/peano.c
48
src/peano.c
|
@ -32,7 +32,7 @@
|
||||||
* @return a pointer to an integer or real.
|
* @return a pointer to an integer or real.
|
||||||
*/
|
*/
|
||||||
struct cons_pointer
|
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;
|
struct cons_pointer result = NIL;
|
||||||
long int i_accumulator = 0;
|
long int i_accumulator = 0;
|
||||||
long double d_accumulator = 0;
|
long double d_accumulator = 0;
|
||||||
|
@ -71,3 +71,49 @@ lisp_plus(struct stack_frame *frame, struct cons_pointer env) {
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
10
src/peano.h
10
src/peano.h
|
@ -23,8 +23,16 @@ extern "C" {
|
||||||
* @return a pointer to an integer or real.
|
* @return a pointer to an integer or real.
|
||||||
*/
|
*/
|
||||||
struct cons_pointer
|
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
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in a new issue