Post Scarcity
A prototype for a post scarcity programming environment
Loading...
Searching...
No Matches
peano.c
Go to the documentation of this file.
1/*
2 * peano.c
3 *
4 * Basic peano arithmetic
5 *
6 * (c) 2017 Simon Brooke <simon@journeyman.cc>
7 * Licensed under GPL version 2.0, or, at your option, any later version.
8 */
9
10#include <ctype.h>
11#include <math.h>
12#include <stdbool.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
18#include "memory/conspage.h"
19#include "debug.h"
20#include "ops/equal.h"
21#include "arith/integer.h"
22#include "ops/intern.h"
23#include "ops/lispops.h"
24#include "arith/peano.h"
25#include "io/print.h"
26#include "arith/ratio.h"
27#include "io/read.h"
28#include "arith/real.h"
29#include "memory/stack.h"
30
31long double to_long_double( struct cons_pointer arg );
32int64_t to_long_int( struct cons_pointer arg );
33struct cons_pointer add_2( struct stack_frame *frame,
34 struct cons_pointer frame_pointer,
35 struct cons_pointer arg1,
36 struct cons_pointer arg2 );
37
38/**
39 * return true if this `arg` points to a number whose value is zero.
40 */
41bool zerop( struct cons_pointer arg ) {
42 bool result = false;
43 struct cons_space_object cell = pointer2cell( arg );
44
45 switch ( cell.tag.value ) {
46 case INTEGERTV:{
47 do {
48 debug_print( L"zerop: ", DEBUG_ARITH );
50 result =
51 ( pointer2cell( arg ).payload.integer.value == 0 );
52 arg = pointer2cell( arg ).payload.integer.more;
53 } while ( result && integerp( arg ) );
54 }
55 break;
56 case RATIOTV:
57 result = zerop( cell.payload.ratio.dividend );
58 break;
59 case REALTV:
60 result = ( cell.payload.real.value == 0 );
61 break;
62 }
63
64 return result;
65}
66
67/**
68 * does this `arg` point to a negative number?
69 */
70bool is_negative( struct cons_pointer arg ) {
71 bool result = false;
72 struct cons_space_object cell = pointer2cell( arg );
73
74 switch ( cell.tag.value ) {
75 case INTEGERTV:
76 result = cell.payload.integer.value < 0;
77 break;
78 case RATIOTV:
79 result = is_negative( cell.payload.ratio.dividend );
80 break;
81 case REALTV:
82 result = ( cell.payload.real.value < 0 );
83 break;
84 }
85
86 return result;
87}
88
89struct cons_pointer absolute( struct cons_pointer arg ) {
90 struct cons_pointer result = NIL;
91 struct cons_space_object cell = pointer2cell( arg );
92
93 if ( is_negative( arg ) ) {
94 switch ( cell.tag.value ) {
95 case INTEGERTV:
96 result =
97 make_integer( llabs( cell.payload.integer.value ),
98 cell.payload.integer.more );
99 break;
100 case RATIOTV:
101 result = make_ratio( absolute( cell.payload.ratio.dividend ),
102 cell.payload.ratio.divisor, false );
103 break;
104 case REALTV:
105 result = make_real( 0 - cell.payload.real.value );
106 break;
107 }
108 }
109
110 return result;
111}
112
113/**
114 * Return the closest possible `binary64` representation to the value of
115 * this `arg`, expected to be an integer, ratio or real, or `NAN` if `arg`
116 * is not any of these.
117 *
118 * @arg a pointer to an integer, ratio or real.
119 *
120 * \todo cannot throw an exception out of here, which is a problem
121 * if a ratio may legally have zero as a divisor, or something which is
122 * not a number is passed in.
123 */
124long double to_long_double( struct cons_pointer arg ) {
125 long double result = 0;
126 struct cons_space_object cell = pointer2cell( arg );
127
128 switch ( cell.tag.value ) {
129 case INTEGERTV:
130 // obviously, this doesn't work for bignums
131 result = ( long double ) cell.payload.integer.value;
132 // sadly, this doesn't work at all.
133// result += 1.0;
134// for (bool is_first = false; integerp(arg); is_first = true) {
135// debug_printf(DEBUG_ARITH, L"to_long_double: accumulator = %lf, arg = ", result);
136// debug_dump_object(arg, DEBUG_ARITH);
137// if (!is_first) {
138// result *= (long double)(MAX_INTEGER + 1);
139// }
140// result *= (long double)(cell.payload.integer.value);
141// arg = cell.payload.integer.more;
142// cell = pointer2cell( arg );
143// }
144 break;
145 case RATIOTV:
146 result = to_long_double( cell.payload.ratio.dividend ) /
147 to_long_double( cell.payload.ratio.divisor );
148 break;
149 case REALTV:
150 result = cell.payload.real.value;
151 break;
152 default:
153 result = NAN;
154 break;
155 }
156
157 debug_print( L"to_long_double( ", DEBUG_ARITH );
159 debug_printf( DEBUG_ARITH, L") => %lf\n", result );
160
161 return result;
162}
163
164
165/**
166 * Return the closest possible `int64_t` representation to the value of
167 * this `arg`, expected to be an integer, ratio or real, or `NAN` if `arg`
168 * is not any of these.
169 *
170 * @arg a pointer to an integer, ratio or real.
171 *
172 * \todo cannot throw an exception out of here, which is a problem
173 * if a ratio may legally have zero as a divisor, or something which is
174 * not a number (or is a big number) is passed in.
175 */
176int64_t to_long_int( struct cons_pointer arg ) {
177 int64_t result = 0;
178 struct cons_space_object cell = pointer2cell( arg );
179 switch ( cell.tag.value ) {
180 case INTEGERTV:
181 /* \todo if (integerp(cell.payload.integer.more)) {
182 * throw an exception!
183 * } */
184 result = cell.payload.integer.value;
185 break;
186 case RATIOTV:
187 result = lroundl( to_long_double( arg ) );
188 break;
189 case REALTV:
190 result = lroundl( cell.payload.real.value );
191 break;
192 }
193 return result;
194}
195
196
197/**
198 * Function: calculate the absolute value of a number.
199 *
200 * (absolute arg)
201 *
202 * @param env the evaluation environment - ignored;
203 * @param frame the stack frame.
204 * @return the absolute value of the number represented by the first
205 * argument, or NIL if it was not a number.
206 */
208 *frame, struct cons_pointer frame_pointer, struct
209 cons_pointer env ) {
210 return absolute( frame->arg[0] );
211}
212
213/**
214 * return a cons_pointer indicating a number which is the sum of
215 * the numbers indicated by `arg1` and `arg2`.
216 */
217struct cons_pointer add_2( struct stack_frame *frame,
218 struct cons_pointer frame_pointer,
219 struct cons_pointer arg1,
220 struct cons_pointer arg2 ) {
221 struct cons_pointer result;
222 struct cons_space_object cell1 = pointer2cell( arg1 );
223 struct cons_space_object cell2 = pointer2cell( arg2 );
224
225 debug_print( L"add_2( arg1 = ", DEBUG_ARITH );
227 debug_print( L"; arg2 = ", DEBUG_ARITH );
229 debug_print( L"\n", DEBUG_ARITH );
230
231 if ( zerop( arg1 ) ) {
232 result = arg2;
233 } else if ( zerop( arg2 ) ) {
234 result = arg1;
235 } else {
236
237 switch ( cell1.tag.value ) {
238 case EXCEPTIONTV:
239 result = arg1;
240 break;
241 case INTEGERTV:
242 switch ( cell2.tag.value ) {
243 case EXCEPTIONTV:
244 result = arg2;
245 break;
246 case INTEGERTV:
247 result = add_integers( arg1, arg2 );
248 break;
249 case RATIOTV:
250 result = add_integer_ratio( arg1, arg2 );
251 break;
252 case REALTV:
253 result =
254 make_real( to_long_double( arg1 ) +
255 to_long_double( arg2 ) );
256 break;
257 default:
259 ( L"Cannot add: not a number" ),
260 frame_pointer );
261 break;
262 }
263 break;
264 case RATIOTV:
265 switch ( cell2.tag.value ) {
266 case EXCEPTIONTV:
267 result = arg2;
268 break;
269 case INTEGERTV:
270 result = add_integer_ratio( arg2, arg1 );
271 break;
272 case RATIOTV:
273 result = add_ratio_ratio( arg1, arg2 );
274 break;
275 case REALTV:
276 result =
277 make_real( to_long_double( arg1 ) +
278 to_long_double( arg2 ) );
279 break;
280 default:
282 ( L"Cannot add: not a number" ),
283 frame_pointer );
284 break;
285 }
286 break;
287 case REALTV:
288 result =
289 make_real( to_long_double( arg1 ) +
290 to_long_double( arg2 ) );
291 break;
292 default:
293 result = exceptionp( arg2 ) ? arg2 :
295 ( L"Cannot add: not a number" ),
296 frame_pointer );
297 }
298 }
299
300 debug_print( L"}; => ", DEBUG_ARITH );
302 debug_print( L"\n", DEBUG_ARITH );
303
304 return result;
305}
306
307/**
308 * Add an indefinite number of numbers together
309 * @param env the evaluation environment - ignored;
310 * @param frame the stack frame.
311 * @return a pointer to an integer, ratio or real.
312 * @exception if any argument is not a number, returns an exception.
313 */
315 *frame, struct cons_pointer frame_pointer, struct
316 cons_pointer env ) {
317 struct cons_pointer result = make_integer( 0, NIL );
318 struct cons_pointer tmp;
319
320 for ( int i = 0;
321 i < args_in_frame &&
322 !nilp( frame->arg[i] ) && !exceptionp( result ); i++ ) {
323 tmp = result;
324 result = add_2( frame, frame_pointer, result, frame->arg[i] );
325 if ( !eq( tmp, result ) ) {
326 dec_ref( tmp );
327 }
328 }
329
330 struct cons_pointer more = frame->more;
331 while ( consp( more ) && !exceptionp( result ) ) {
332 tmp = result;
333 result = add_2( frame, frame_pointer, result, c_car( more ) );
334 if ( !eq( tmp, result ) ) {
335 dec_ref( tmp );
336 }
337
338 more = c_cdr( more );
339 }
340
341 return result;
342}
343
344
345/**
346 * return a cons_pointer indicating a number which is the product of
347 * the numbers indicated by `arg1` and `arg2`.
348 */
349struct cons_pointer multiply_2( struct stack_frame *frame,
350 struct cons_pointer frame_pointer,
351 struct cons_pointer arg1,
352 struct cons_pointer arg2 ) {
353 struct cons_pointer result;
354 struct cons_space_object cell1 = pointer2cell( arg1 );
355 struct cons_space_object cell2 = pointer2cell( arg2 );
356
357 debug_print( L"multiply_2( arg1 = ", DEBUG_ARITH );
359 debug_print( L"; arg2 = ", DEBUG_ARITH );
361 debug_print( L")\n", DEBUG_ARITH );
362
363 if ( zerop( arg1 ) ) {
364 result = arg2;
365 } else if ( zerop( arg2 ) ) {
366 result = arg1;
367 } else {
368 switch ( cell1.tag.value ) {
369 case EXCEPTIONTV:
370 result = arg1;
371 break;
372 case INTEGERTV:
373 switch ( cell2.tag.value ) {
374 case EXCEPTIONTV:
375 result = arg2;
376 break;
377 case INTEGERTV:
378 result = multiply_integers( arg1, arg2 );
379 break;
380 case RATIOTV:
381 result = multiply_integer_ratio( arg1, arg2 );
382 break;
383 case REALTV:
384 result =
385 make_real( to_long_double( arg1 ) *
386 to_long_double( arg2 ) );
387 break;
388 default:
389 result =
392 ( L"Cannot multiply: argument 2 is not a number: " ),
393 c_type( arg2 ) ),
394 frame_pointer );
395 break;
396 }
397 break;
398 case RATIOTV:
399 switch ( cell2.tag.value ) {
400 case EXCEPTIONTV:
401 result = arg2;
402 break;
403 case INTEGERTV:
404 result = multiply_integer_ratio( arg2, arg1 );
405 break;
406 case RATIOTV:
407 result = multiply_ratio_ratio( arg1, arg2 );
408 break;
409 case REALTV:
410 result =
411 make_real( to_long_double( arg1 ) *
412 to_long_double( arg2 ) );
413 break;
414 default:
415 result =
418 ( L"Cannot multiply: argument 2 is not a number" ),
419 c_type( arg2 ) ),
420 frame_pointer );
421 }
422 break;
423 case REALTV:
424 result = exceptionp( arg2 ) ? arg2 :
425 make_real( to_long_double( arg1 ) *
426 to_long_double( arg2 ) );
427 break;
428 default:
430 ( L"Cannot multiply: argument 1 is not a number" ),
431 c_type( arg1 ) ),
432 frame_pointer );
433 break;
434 }
435 }
436
437 debug_print( L"multiply_2 returning: ", DEBUG_ARITH );
439 debug_print( L"\n", DEBUG_ARITH );
440
441 return result;
442}
443
444#define multiply_one_arg(arg) {if (exceptionp(arg)){result=arg;}else{tmp = result; result = multiply_2( frame, frame_pointer, result, arg ); if ( !eq( tmp, result ) ) dec_ref( tmp );}}
445
446/**
447 * Multiply an indefinite number of numbers together
448 * @param env the evaluation environment - ignored;
449 * @param frame the stack frame.
450 * @return a pointer to an integer, ratio or real.
451 * @exception if any argument is not a number, returns an exception.
452 */
455 *frame, struct cons_pointer frame_pointer, struct
456 cons_pointer env ) {
457 struct cons_pointer result = make_integer( 1, NIL );
458 struct cons_pointer tmp;
459
460 for ( int i = 0; i < args_in_frame && !nilp( frame->arg[i] )
461 && !exceptionp( result ); i++ ) {
462 debug_print( L"lisp_multiply: accumulator = ", DEBUG_ARITH );
464 debug_print( L"; arg = ", DEBUG_ARITH );
465 debug_print_object( frame->arg[i], DEBUG_ARITH );
467
468 multiply_one_arg( frame->arg[i] );
469 }
470
471 struct cons_pointer more = frame->more;
472 while ( consp( more )
473 && !exceptionp( result ) ) {
474 multiply_one_arg( c_car( more ) );
475 more = c_cdr( more );
476 }
477
478 debug_print( L"lisp_multiply returning: ", DEBUG_ARITH );
481
482 return result;
483}
484
485/**
486 * return a cons_pointer indicating a number which is the
487 * 0 - the number indicated by `arg`.
488 */
489struct cons_pointer negative( struct cons_pointer arg ) {
490 struct cons_pointer result = NIL;
491 struct cons_space_object cell = pointer2cell( arg );
492
493 switch ( cell.tag.value ) {
494 case EXCEPTIONTV:
495 result = arg;
496 break;
497 case INTEGERTV:
498 result =
499 make_integer( 0 - cell.payload.integer.value,
500 cell.payload.integer.more );
501 break;
502 case NILTV:
503 result = TRUE;
504 break;
505 case RATIOTV:
506 result = make_ratio( negative( cell.payload.ratio.dividend ),
507 cell.payload.ratio.divisor, false );
508 break;
509 case REALTV:
510 result = make_real( 0 - to_long_double( arg ) );
511 break;
512 case TRUETV:
513 result = NIL;
514 break;
515 }
516
517 return result;
518}
519
520
521/**
522 * Function: is this number negative?
523 *
524 * * (negative? arg)
525 *
526 * @param env the evaluation environment - ignored;
527 * @param frame the stack frame.
528 * @return T if the first argument was a negative number, or NIL if it
529 * was not.
530 */
532 *frame,
533 struct cons_pointer frame_pointer, struct
534 cons_pointer env ) {
535 return is_negative( frame->arg[0] ) ? TRUE : NIL;
536}
537
538
539/**
540 * return a cons_pointer indicating a number which is the result of
541 * subtracting the number indicated by `arg2` from that indicated by `arg1`,
542 * in the context of this `frame`.
543 */
544struct cons_pointer subtract_2( struct stack_frame *frame,
545 struct cons_pointer frame_pointer,
546 struct cons_pointer arg1,
547 struct cons_pointer arg2 ) {
548 struct cons_pointer result = NIL;
549
550 switch ( pointer2cell( arg1 ).tag.value ) {
551 case EXCEPTIONTV:
552 result = arg1;
553 break;
554 case INTEGERTV:
555 switch ( pointer2cell( arg2 ).tag.value ) {
556 case EXCEPTIONTV:
557 result = arg2;
558 break;
559 case INTEGERTV:{
560 struct cons_pointer i = negative( arg2 );
561 inc_ref( i );
562 result = add_integers( arg1, i );
563 dec_ref( i );
564 }
565 break;
566 case RATIOTV:{
567 struct cons_pointer tmp = make_ratio( arg1,
568 make_integer( 1,
569 NIL ), false );
570 inc_ref( tmp );
571 result = subtract_ratio_ratio( tmp, arg2 );
572 dec_ref( tmp );
573 }
574 break;
575 case REALTV:
576 result =
577 make_real( to_long_double( arg1 ) -
578 to_long_double( arg2 ) );
579 break;
580 default:
582 ( L"Cannot subtract: not a number" ),
583 frame_pointer );
584 break;
585 }
586 break;
587 case RATIOTV:
588 switch ( pointer2cell( arg2 ).tag.value ) {
589 case EXCEPTIONTV:
590 result = arg2;
591 break;
592 case INTEGERTV:{
593 struct cons_pointer tmp = make_ratio( arg2,
594 make_integer( 1,
595 NIL ), false );
596 inc_ref( tmp );
597 result = subtract_ratio_ratio( arg1, tmp );
598 dec_ref( tmp );
599 }
600 break;
601 case RATIOTV:
602 result = subtract_ratio_ratio( arg1, arg2 );
603 break;
604 case REALTV:
605 result =
606 make_real( to_long_double( arg1 ) -
607 to_long_double( arg2 ) );
608 break;
609 default:
611 ( L"Cannot subtract: not a number" ),
612 frame_pointer );
613 break;
614 }
615 break;
616 case REALTV:
617 result = exceptionp( arg2 ) ? arg2 :
618 make_real( to_long_double( arg1 ) - to_long_double( arg2 ) );
619 break;
620 default:
622 ( L"Cannot subtract: not a number" ),
623 frame_pointer );
624 break;
625 }
626
627 // and if not nilp[frame->arg[2]) we also have an error.
628
629 return result;
630}
631
632/**
633 * Subtract one number from another. If more than two arguments are passed
634 * in the frame, the additional arguments are ignored.
635 * @param env the evaluation environment - ignored;
636 * @param frame the stack frame.
637 * @return a pointer to an integer, ratio or real.
638 * @exception if either argument is not a number, returns an exception.
639 */
642 *frame, struct cons_pointer frame_pointer, struct
643 cons_pointer env ) {
644 return subtract_2( frame, frame_pointer, frame->arg[0], frame->arg[1] );
645}
646
647/**
648 * Divide one number by another. If more than two arguments are passed
649 * in the frame, the additional arguments are ignored.
650 * @param env the evaluation environment - ignored;
651 * @param frame the stack frame.
652 * @return a pointer to an integer or real.
653 * @exception if either argument is not a number, returns an exception.
654 */
657 *frame, struct cons_pointer frame_pointer, struct
658 cons_pointer env ) {
659 struct cons_pointer result = NIL;
660 struct cons_space_object arg0 = pointer2cell( frame->arg[0] );
661 struct cons_space_object arg1 = pointer2cell( frame->arg[1] );
662
663 switch ( arg0.tag.value ) {
664 case EXCEPTIONTV:
665 result = frame->arg[0];
666 break;
667 case INTEGERTV:
668 switch ( arg1.tag.value ) {
669 case EXCEPTIONTV:
670 result = frame->arg[1];
671 break;
672 case INTEGERTV:{
673 result =
674 make_ratio( frame->arg[0],
675 frame->arg[1], true);
676 }
677 break;
678 case RATIOTV:{
679 struct cons_pointer one = make_integer( 1, NIL );
680 struct cons_pointer ratio =
681 make_ratio( frame->arg[0], one, false );
682 inc_ref( ratio );
683 result = divide_ratio_ratio( ratio, frame->arg[1] );
684 dec_ref( ratio );
685 }
686 break;
687 case REALTV:
688 result =
689 make_real( to_long_double( frame->arg[0] ) /
690 to_long_double( frame->arg[1] ) );
691 break;
692 default:
694 ( L"Cannot divide: not a number" ),
695 frame_pointer );
696 break;
697 }
698 break;
699 case RATIOTV:
700 switch ( arg1.tag.value ) {
701 case EXCEPTIONTV:
702 result = frame->arg[1];
703 break;
704 case INTEGERTV:{
705 struct cons_pointer one = make_integer( 1, NIL );
706 struct cons_pointer ratio =
707 make_ratio( frame->arg[1], one, false);
708 result = divide_ratio_ratio( frame->arg[0], ratio );
709 dec_ref( ratio );
710 dec_ref( one );
711 }
712 break;
713 case RATIOTV:
714 result =
715 divide_ratio_ratio( frame->arg[0], frame->arg[1] );
716 break;
717 case REALTV:
718 result =
719 make_real( to_long_double( frame->arg[0] ) /
720 to_long_double( frame->arg[1] ) );
721 break;
722 default:
724 ( L"Cannot divide: not a number" ),
725 frame_pointer );
726 break;
727 }
728 break;
729 case REALTV:
730 result = exceptionp( frame->arg[1] ) ? frame->arg[1] :
731 make_real( to_long_double( frame->arg[0] ) /
732 to_long_double( frame->arg[1] ) );
733 break;
734 default:
736 ( L"Cannot divide: not a number" ),
737 frame_pointer );
738 break;
739 }
740
741 return result;
742}
743
744/**
745 * @brief Function: return a real (approcimately) equal in value to the ratio
746 * which is the first argument.
747 *
748 * @param frame
749 * @param frame_pointer
750 * @param env
751 * @return struct cons_pointer a pointer to a real
752 */
753// struct cons_pointer lisp_eval( struct stack_frame *frame, struct cons_pointer frame_pointer,
754// struct cons_pointer env )
756 struct cons_pointer frame_pointer,
757 struct cons_pointer env ) {
758 struct cons_pointer result = NIL;
759 struct cons_pointer rat = frame->arg[0];
760
761 debug_print( L"\nc_ratio_to_ld: ", DEBUG_ARITH );
763
764 if ( ratiop( rat ) ) {
765 result = make_real( c_ratio_to_ld( rat ) );
766 } // TODO: else throw an exception?
767
768 return result;
769}
#define ratiop(conspoint)
true if conspoint points to a rational number cell, else false
#define exceptionp(conspoint)
true if conspoint points to an exception, else false
#define args_in_frame
union cons_space_object::@2 tag
union cons_space_object::@3 payload
#define NIL
a cons pointer which points to the special NIL cell
struct cons_pointer c_cdr(struct cons_pointer arg)
Implementation of cdr in C.
#define INTEGERTV
The string INTR, considered as an unsigned int.
#define RATIOTV
The string RTIO, considered as an unsigned int.
#define consp(conspoint)
true if conspoint points to a cons cell, else false
#define nilp(conspoint)
true if conspoint points to the special cell NIL, else false (there should only be one of these so it...
#define TRUETV
The string TRUE, considered as an unsigned int.
#define REALTV
The string REAL, considered as an unsigned int.
struct cons_pointer c_string_to_lisp_string(wchar_t *string)
Return a lisp string representation of this wide character string.
struct cons_pointer inc_ref(struct cons_pointer pointer)
increment the reference count of the object at this cons pointer.
#define NILTV
The string NIL, considered as an unsigned int.
#define EXCEPTIONTV
The string EXEP, considered as an unsigned int.
#define TRUE
a cons pointer which points to the special T cell
struct cons_pointer c_car(struct cons_pointer arg)
Implementation of car in C.
struct cons_pointer c_type(struct cons_pointer pointer)
Get the Lisp type of the single argument.
struct cons_pointer dec_ref(struct cons_pointer pointer)
Decrement the reference count of the object at this cons pointer.
#define pointer2cell(pointer)
given a cons_pointer as argument, return the cell.
#define integerp(conspoint)
true if conspoint points to an integer cell, else false
struct cons_pointer make_cons(struct cons_pointer car, struct cons_pointer cdr)
Construct a cons cell from this pair of pointers.
An indirect pointer to a cons cell.
an object in cons space.
A stack frame.
void debug_println(int level)
print a line feed to stderr, if verbosity matches level.
Definition debug.c:85
void debug_dump_object(struct cons_pointer pointer, int level)
Like dump_object, q.v., but protected by the verbosity mechanism.
Definition debug.c:136
void debug_printf(int level, wchar_t *format,...)
wprintf adapted for the debug logging system.
Definition debug.c:101
void debug_print(wchar_t *message, int level)
print this debug message to stderr, if verbosity matches level.
Definition debug.c:41
void debug_print_object(struct cons_pointer pointer, int level)
print the object indicated by this pointer to stderr, if verbosity matches level.
Definition debug.c:119
#define DEBUG_ARITH
Print messages debugging arithmetic operations.
Definition debug.h:28
bool eq(struct cons_pointer a, struct cons_pointer b)
Shallow, and thus cheap, equality: true if these two objects are the same object, else false.
Definition equal.c:24
struct cons_pointer multiply_integers(struct cons_pointer a, struct cons_pointer b)
Return a pointer to an integer representing the product of the integers pointed to by a and b.
Definition integer.c:343
struct cons_pointer add_integers(struct cons_pointer a, struct cons_pointer b)
Return a pointer to an integer representing the sum of the integers pointed to by a and b.
Definition integer.c:224
struct cons_pointer make_integer(int64_t value, struct cons_pointer more)
Allocate an integer cell representing this value and return a cons_pointer to it.
Definition integer.c:89
struct cons_pointer throw_exception(struct cons_pointer message, struct cons_pointer frame_pointer)
Throw an exception.
Definition lispops.c:1208
struct cons_pointer lisp_absolute(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: calculate the absolute value of a number.
Definition peano.c:207
struct cons_pointer absolute(struct cons_pointer arg)
Definition peano.c:89
struct cons_pointer multiply_2(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the product of the numbers indicated by arg1 and a...
Definition peano.c:349
struct cons_pointer negative(struct cons_pointer arg)
return a cons_pointer indicating a number which is the 0 - the number indicated by arg.
Definition peano.c:489
bool is_negative(struct cons_pointer arg)
does this arg point to a negative number?
Definition peano.c:70
struct cons_pointer lisp_ratio_to_real(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return a real (approcimately) equal in value to the ratio which is the first argument.
Definition peano.c:755
struct cons_pointer lisp_is_negative(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: is this number negative?
Definition peano.c:531
struct cons_pointer add_2(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the sum of the numbers indicated by arg1 and arg2.
Definition peano.c:217
struct cons_pointer lisp_subtract(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Subtract one number from another.
Definition peano.c:640
struct cons_pointer lisp_divide(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Divide one number by another.
Definition peano.c:655
#define multiply_one_arg(arg)
Definition peano.c:444
long double to_long_double(struct cons_pointer arg)
Return the closest possible binary64 representation to the value of this arg, expected to be an integ...
Definition peano.c:124
struct cons_pointer lisp_multiply(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Multiply an indefinite number of numbers together.
Definition peano.c:453
struct cons_pointer lisp_add(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Add an indefinite number of numbers together.
Definition peano.c:314
struct cons_pointer subtract_2(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the result of subtracting the number indicated by ...
Definition peano.c:544
bool zerop(struct cons_pointer arg)
return true if this arg points to a number whose value is zero.
Definition peano.c:41
int64_t to_long_int(struct cons_pointer arg)
Return the closest possible int64_t representation to the value of this arg, expected to be an intege...
Definition peano.c:176
long double c_ratio_to_ld(struct cons_pointer rat)
convert a ratio to an equivalent long double.
Definition ratio.c:379
struct cons_pointer add_ratio_ratio(struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the sum of the ratios indicated by arg1 and arg2.
Definition ratio.c:93
struct cons_pointer multiply_ratio_ratio(struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the product of the ratios indicated by arg1 and ar...
Definition ratio.c:203
struct cons_pointer divide_ratio_ratio(struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer to a ratio which represents the value of the ratio indicated by arg1 divided by...
Definition ratio.c:176
struct cons_pointer multiply_integer_ratio(struct cons_pointer intarg, struct cons_pointer ratarg)
return a cons_pointer indicating a number which is the product of the intger indicated by intarg and ...
Definition ratio.c:254
struct cons_pointer add_integer_ratio(struct cons_pointer intarg, struct cons_pointer ratarg)
return a cons_pointer indicating a number which is the sum of the intger indicated by intarg and the ...
Definition ratio.c:137
struct cons_pointer subtract_ratio_ratio(struct cons_pointer arg1, struct cons_pointer arg2)
return a cons_pointer indicating a number which is the difference of the ratios indicated by arg1 and...
Definition ratio.c:290
struct cons_pointer make_ratio(struct cons_pointer dividend, struct cons_pointer divisor, bool simplify)
Construct a ratio frame from this dividend and divisor, expected to be integers, in the context of th...
Definition ratio.c:312
struct cons_pointer make_real(long double value)
Allocate a real number cell representing this value and return a cons pointer to it.
Definition real.c:21