post-scarcity/src/peano.c

74 lines
1.9 KiB
C

/**
* peano.c
*
* Basic peano arithmetic
*
* (c) 2017 Simon Brooke <simon@journeyman.cc>
* Licensed under GPL version 2.0, or, at your option, any later version.
*/
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#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;
}