Post Scarcity 0.0.6
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// TODO: think about
68// bool greaterp( struct cons_pointer arg_1, struct cons_pointer arg_2) {
69// bool result = false;
70// struct cons_space_object * cell_1 = & pointer2cell( arg_1 );
71// struct cons_space_object * cell_2 = & pointer2cell( arg_2 );
72
73// if (cell_1->tag.value == cell_2->tag.value) {
74
75// switch ( cell_1->tag.value ) {
76// case INTEGERTV:{
77// if ( nilp(cell_1->payload.integer.more) && nilp( cell_2->payload.integer.more)) {
78// result = cell_1->payload.integer.value > cell_2->payload.integer.value;
79// }
80// // else deal with comparing bignums...
81// }
82// break;
83// case RATIOTV:
84// result = lisp_ratio_to_real( cell_1) > ratio_to_real( cell_2);
85// break;
86// case REALTV:
87// result = ( cell.payload.real.value == 0 );
88// break;
89// }
90// }
91
92// return result;
93
94// }
95
96/**
97 * does this `arg` point to a negative number?
98 */
99bool is_negative( struct cons_pointer arg ) {
100 bool result = false;
101 struct cons_space_object cell = pointer2cell( arg );
102
103 switch ( cell.tag.value ) {
104 case INTEGERTV:
105 result = cell.payload.integer.value < 0;
106 break;
107 case RATIOTV:
108 result = is_negative( cell.payload.ratio.dividend );
109 break;
110 case REALTV:
111 result = ( cell.payload.real.value < 0 );
112 break;
113 }
114
115 return result;
116}
117
118/**
119 * @brief if `arg` is a number, return the absolute value of that number, else
120 * `NIL`
121 *
122 * @param arg a cons space object, probably a number.
123 * @return struct cons_pointer
124 */
125struct cons_pointer absolute( struct cons_pointer arg ) {
126 struct cons_pointer result = NIL;
127 struct cons_space_object cell = pointer2cell( arg );
128
129 if ( numberp( arg ) ) {
130 if ( is_negative( arg ) ) {
131 switch ( cell.tag.value ) {
132 case INTEGERTV:
133 result =
134 make_integer( llabs( cell.payload.integer.value ),
135 cell.payload.integer.more );
136 break;
137 case RATIOTV:
138 result =
139 make_ratio( absolute( cell.payload.ratio.dividend ),
140 cell.payload.ratio.divisor, false );
141 break;
142 case REALTV:
143 result = make_real( 0 - cell.payload.real.value );
144 break;
145 }
146 } else {
147 result = arg;
148 }
149 }
150
151 return result;
152}
153
154/**
155 * Return the closest possible `binary64` representation to the value of
156 * this `arg`, expected to be an integer, ratio or real, or `NAN` if `arg`
157 * is not any of these.
158 *
159 * @arg a pointer to an integer, ratio or real.
160 *
161 * \todo cannot throw an exception out of here, which is a problem
162 * if a ratio may legally have zero as a divisor, or something which is
163 * not a number is passed in.
164 */
165long double to_long_double( struct cons_pointer arg ) {
166 long double result = 0;
167 struct cons_space_object cell = pointer2cell( arg );
168
169 switch ( cell.tag.value ) {
170 case INTEGERTV:
171 // obviously, this doesn't work for bignums
172 result = ( long double ) cell.payload.integer.value;
173 // sadly, this doesn't work at all.
174// result += 1.0;
175// for (bool is_first = false; integerp(arg); is_first = true) {
176// debug_printf(DEBUG_ARITH, L"to_long_double: accumulator = %lf, arg = ", result);
177// debug_dump_object(arg, DEBUG_ARITH);
178// if (!is_first) {
179// result *= (long double)(MAX_INTEGER + 1);
180// }
181// result *= (long double)(cell.payload.integer.value);
182// arg = cell.payload.integer.more;
183// cell = pointer2cell( arg );
184// }
185 break;
186 case RATIOTV:
187 result = to_long_double( cell.payload.ratio.dividend ) /
188 to_long_double( cell.payload.ratio.divisor );
189 break;
190 case REALTV:
191 result = cell.payload.real.value;
192 break;
193 default:
194 result = NAN;
195 break;
196 }
197
198 debug_print( L"to_long_double( ", DEBUG_ARITH );
200 debug_printf( DEBUG_ARITH, L") => %lf\n", result );
201
202 return result;
203}
204
205
206/**
207 * Return the closest possible `int64_t` representation to the value of
208 * this `arg`, expected to be an integer, ratio or real, or `NAN` if `arg`
209 * is not any of these.
210 *
211 * @arg a pointer to an integer, ratio or real.
212 *
213 * \todo cannot throw an exception out of here, which is a problem
214 * if a ratio may legally have zero as a divisor, or something which is
215 * not a number (or is a big number) is passed in.
216 */
217int64_t to_long_int( struct cons_pointer arg ) {
218 int64_t result = 0;
219 struct cons_space_object cell = pointer2cell( arg );
220 switch ( cell.tag.value ) {
221 case INTEGERTV:
222 /* \todo if (integerp(cell.payload.integer.more)) {
223 * throw an exception!
224 * } */
225 result = cell.payload.integer.value;
226 break;
227 case RATIOTV:
228 result = lroundl( to_long_double( arg ) );
229 break;
230 case REALTV:
231 result = lroundl( cell.payload.real.value );
232 break;
233 }
234 return result;
235}
236
237
238/**
239 * Function: calculate the absolute value of a number.
240 *
241 * (absolute arg)
242 *
243 * @param env the evaluation environment - ignored;
244 * @param frame the stack frame.
245 * @return the absolute value of the number represented by the first
246 * argument, or NIL if it was not a number.
247 */
249 *frame, struct cons_pointer frame_pointer, struct
250 cons_pointer env ) {
251 return absolute( frame->arg[0] );
252}
253
254/**
255 * return a cons_pointer indicating a number which is the sum of
256 * the numbers indicated by `arg1` and `arg2`.
257 */
258struct cons_pointer add_2( struct stack_frame *frame,
259 struct cons_pointer frame_pointer,
260 struct cons_pointer arg1,
261 struct cons_pointer arg2 ) {
262 struct cons_pointer result;
263 struct cons_space_object cell1 = pointer2cell( arg1 );
264 struct cons_space_object cell2 = pointer2cell( arg2 );
265
266 debug_print( L"add_2( arg1 = ", DEBUG_ARITH );
268 debug_print( L"; arg2 = ", DEBUG_ARITH );
270 debug_print( L"\n", DEBUG_ARITH );
271
272 if ( zerop( arg1 ) ) {
273 result = arg2;
274 } else if ( zerop( arg2 ) ) {
275 result = arg1;
276 } else {
277
278 switch ( cell1.tag.value ) {
279 case EXCEPTIONTV:
280 result = arg1;
281 break;
282 case INTEGERTV:
283 switch ( cell2.tag.value ) {
284 case EXCEPTIONTV:
285 result = arg2;
286 break;
287 case INTEGERTV:
288 result = add_integers( arg1, arg2 );
289 break;
290 case RATIOTV:
291 result = add_integer_ratio( arg1, arg2 );
292 break;
293 case REALTV:
294 result =
295 make_real( to_long_double( arg1 ) +
296 to_long_double( arg2 ) );
297 break;
298 default:
299 result =
302 ( L"Cannot add: not a number" ),
303 frame_pointer );
304 break;
305 }
306 break;
307 case RATIOTV:
308 switch ( cell2.tag.value ) {
309 case EXCEPTIONTV:
310 result = arg2;
311 break;
312 case INTEGERTV:
313 result = add_integer_ratio( arg2, arg1 );
314 break;
315 case RATIOTV:
316 result = add_ratio_ratio( arg1, arg2 );
317 break;
318 case REALTV:
319 result =
320 make_real( to_long_double( arg1 ) +
321 to_long_double( arg2 ) );
322 break;
323 default:
324 result =
327 ( L"Cannot add: not a number" ),
328 frame_pointer );
329 break;
330 }
331 break;
332 case REALTV:
333 result =
334 make_real( to_long_double( arg1 ) +
335 to_long_double( arg2 ) );
336 break;
337 default:
338 result = exceptionp( arg2 ) ? arg2 :
341 ( L"Cannot add: not a number" ),
342 frame_pointer );
343 }
344 }
345
346 debug_print( L"}; => ", DEBUG_ARITH );
348 debug_print( L"\n", DEBUG_ARITH );
349
350 return result;
351}
352
353/**
354 * Add an indefinite number of numbers together
355 * @param env the evaluation environment - ignored;
356 * @param frame the stack frame.
357 * @return a pointer to an integer, ratio or real.
358 * @exception if any argument is not a number, returns an exception.
359 */
361 *frame, struct cons_pointer frame_pointer, struct
362 cons_pointer env ) {
363 struct cons_pointer result = make_integer( 0, NIL );
364 struct cons_pointer tmp;
365
366 for ( int i = 0;
367 i < args_in_frame &&
368 !nilp( frame->arg[i] ) && !exceptionp( result ); i++ ) {
369 tmp = result;
370 result = add_2( frame, frame_pointer, result, frame->arg[i] );
371 if ( !eq( tmp, result ) ) {
372 dec_ref( tmp );
373 }
374 }
375
376 struct cons_pointer more = frame->more;
377 while ( consp( more ) && !exceptionp( result ) ) {
378 tmp = result;
379 result = add_2( frame, frame_pointer, result, c_car( more ) );
380 if ( !eq( tmp, result ) ) {
381 dec_ref( tmp );
382 }
383
384 more = c_cdr( more );
385 }
386
387 return result;
388}
389
390
391/**
392 * return a cons_pointer indicating a number which is the product of
393 * the numbers indicated by `arg1` and `arg2`.
394 */
395struct cons_pointer multiply_2( struct stack_frame *frame,
396 struct cons_pointer frame_pointer,
397 struct cons_pointer arg1,
398 struct cons_pointer arg2 ) {
399 struct cons_pointer result;
400 struct cons_space_object cell1 = pointer2cell( arg1 );
401 struct cons_space_object cell2 = pointer2cell( arg2 );
402
403 debug_print( L"multiply_2( arg1 = ", DEBUG_ARITH );
405 debug_print( L"; arg2 = ", DEBUG_ARITH );
407 debug_print( L")\n", DEBUG_ARITH );
408
409 if ( zerop( arg1 ) ) {
410 result = arg2;
411 } else if ( zerop( arg2 ) ) {
412 result = arg1;
413 } else {
414 switch ( cell1.tag.value ) {
415 case EXCEPTIONTV:
416 result = arg1;
417 break;
418 case INTEGERTV:
419 switch ( cell2.tag.value ) {
420 case EXCEPTIONTV:
421 result = arg2;
422 break;
423 case INTEGERTV:
424 result = multiply_integers( arg1, arg2 );
425 break;
426 case RATIOTV:
427 result = multiply_integer_ratio( arg1, arg2 );
428 break;
429 case REALTV:
430 result =
431 make_real( to_long_double( arg1 ) *
432 to_long_double( arg2 ) );
433 break;
434 default:
435 result =
439 ( L"Cannot multiply: argument 2 is not a number: " ),
440 c_type( arg2 ) ),
441 frame_pointer );
442 break;
443 }
444 break;
445 case RATIOTV:
446 switch ( cell2.tag.value ) {
447 case EXCEPTIONTV:
448 result = arg2;
449 break;
450 case INTEGERTV:
451 result = multiply_integer_ratio( arg2, arg1 );
452 break;
453 case RATIOTV:
454 result = multiply_ratio_ratio( arg1, arg2 );
455 break;
456 case REALTV:
457 result =
458 make_real( to_long_double( arg1 ) *
459 to_long_double( arg2 ) );
460 break;
461 default:
462 result =
466 ( L"Cannot multiply: argument 2 is not a number" ),
467 c_type( arg2 ) ),
468 frame_pointer );
469 }
470 break;
471 case REALTV:
472 result = exceptionp( arg2 ) ? arg2 :
473 make_real( to_long_double( arg1 ) *
474 to_long_double( arg2 ) );
475 break;
476 default:
479 ( L"Cannot multiply: argument 1 is not a number" ),
480 c_type( arg1 ) ),
481 frame_pointer );
482 break;
483 }
484 }
485
486 debug_print( L"multiply_2 returning: ", DEBUG_ARITH );
488 debug_print( L"\n", DEBUG_ARITH );
489
490 return result;
491}
492
493#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 );}}
494
495/**
496 * Multiply an indefinite number of numbers together
497 * @param env the evaluation environment - ignored;
498 * @param frame the stack frame.
499 * @return a pointer to an integer, ratio or real.
500 * @exception if any argument is not a number, returns an exception.
501 */
504 *frame, struct cons_pointer frame_pointer, struct
505 cons_pointer env ) {
506 struct cons_pointer result = make_integer( 1, NIL );
507 struct cons_pointer tmp;
508
509 for ( int i = 0; i < args_in_frame && !nilp( frame->arg[i] )
510 && !exceptionp( result ); i++ ) {
511 debug_print( L"lisp_multiply: accumulator = ", DEBUG_ARITH );
513 debug_print( L"; arg = ", DEBUG_ARITH );
514 debug_print_object( frame->arg[i], DEBUG_ARITH );
516
517 multiply_one_arg( frame->arg[i] );
518 }
519
520 struct cons_pointer more = frame->more;
521 while ( consp( more )
522 && !exceptionp( result ) ) {
523 multiply_one_arg( c_car( more ) );
524 more = c_cdr( more );
525 }
526
527 debug_print( L"lisp_multiply returning: ", DEBUG_ARITH );
530
531 return result;
532}
533
534/**
535 * return a cons_pointer indicating a number which is the
536 * 0 - the number indicated by `arg`.
537 */
538struct cons_pointer negative( struct cons_pointer arg ) {
539 struct cons_pointer result = NIL;
540 struct cons_space_object cell = pointer2cell( arg );
541
542 switch ( cell.tag.value ) {
543 case EXCEPTIONTV:
544 result = arg;
545 break;
546 case INTEGERTV:
547 result =
548 make_integer( 0 - cell.payload.integer.value,
549 cell.payload.integer.more );
550 break;
551 case NILTV:
552 result = TRUE;
553 break;
554 case RATIOTV:
555 result = make_ratio( negative( cell.payload.ratio.dividend ),
556 cell.payload.ratio.divisor, false );
557 break;
558 case REALTV:
559 result = make_real( 0 - to_long_double( arg ) );
560 break;
561 case TRUETV:
562 result = NIL;
563 break;
564 }
565
566 return result;
567}
568
569
570/**
571 * Function: is this number negative?
572 *
573 * * (negative? arg)
574 *
575 * @param env the evaluation environment - ignored;
576 * @param frame the stack frame.
577 * @return T if the first argument was a negative number, or NIL if it
578 * was not.
579 */
581 *frame,
582 struct cons_pointer frame_pointer, struct
583 cons_pointer env ) {
584 return is_negative( frame->arg[0] ) ? TRUE : NIL;
585}
586
587
588/**
589 * return a cons_pointer indicating a number which is the result of
590 * subtracting the number indicated by `arg2` from that indicated by `arg1`,
591 * in the context of this `frame`.
592 */
593struct cons_pointer subtract_2( struct stack_frame *frame,
594 struct cons_pointer frame_pointer,
595 struct cons_pointer arg1,
596 struct cons_pointer arg2 ) {
597 struct cons_pointer result = NIL;
598
599 switch ( pointer2cell( arg1 ).tag.value ) {
600 case EXCEPTIONTV:
601 result = arg1;
602 break;
603 case INTEGERTV:
604 switch ( pointer2cell( arg2 ).tag.value ) {
605 case EXCEPTIONTV:
606 result = arg2;
607 break;
608 case INTEGERTV:{
609 struct cons_pointer i = negative( arg2 );
610 inc_ref( i );
611 result = add_integers( arg1, i );
612 dec_ref( i );
613 }
614 break;
615 case RATIOTV:{
616 struct cons_pointer tmp = make_ratio( arg1,
617 make_integer( 1,
618 NIL ),
619 false );
620 inc_ref( tmp );
621 result = subtract_ratio_ratio( tmp, arg2 );
622 dec_ref( tmp );
623 }
624 break;
625 case REALTV:
626 result =
627 make_real( to_long_double( arg1 ) -
628 to_long_double( arg2 ) );
629 break;
630 default:
633 ( L"Cannot subtract: not a number" ),
634 frame_pointer );
635 break;
636 }
637 break;
638 case RATIOTV:
639 switch ( pointer2cell( arg2 ).tag.value ) {
640 case EXCEPTIONTV:
641 result = arg2;
642 break;
643 case INTEGERTV:{
644 struct cons_pointer tmp = make_ratio( arg2,
645 make_integer( 1,
646 NIL ),
647 false );
648 inc_ref( tmp );
649 result = subtract_ratio_ratio( arg1, tmp );
650 dec_ref( tmp );
651 }
652 break;
653 case RATIOTV:
654 result = subtract_ratio_ratio( arg1, arg2 );
655 break;
656 case REALTV:
657 result =
658 make_real( to_long_double( arg1 ) -
659 to_long_double( arg2 ) );
660 break;
661 default:
664 ( L"Cannot subtract: not a number" ),
665 frame_pointer );
666 break;
667 }
668 break;
669 case REALTV:
670 result = exceptionp( arg2 ) ? arg2 :
671 make_real( to_long_double( arg1 ) - to_long_double( arg2 ) );
672 break;
673 default:
676 ( L"Cannot subtract: not a number" ),
677 frame_pointer );
678 break;
679 }
680
681 // and if not nilp[frame->arg[2]) we also have an error.
682
683 return result;
684}
685
686/**
687 * Subtract one number from another. If more than two arguments are passed
688 * in the frame, the additional arguments are ignored.
689 * @param env the evaluation environment - ignored;
690 * @param frame the stack frame.
691 * @return a pointer to an integer, ratio or real.
692 * @exception if either argument is not a number, returns an exception.
693 */
696 *frame, struct cons_pointer frame_pointer, struct
697 cons_pointer env ) {
698 return subtract_2( frame, frame_pointer, frame->arg[0], frame->arg[1] );
699}
700
701/**
702 * Divide one number by another. If more than two arguments are passed
703 * in the frame, the additional arguments are ignored.
704 * @param env the evaluation environment - ignored;
705 * @param frame the stack frame.
706 * @return a pointer to an integer or real.
707 * @exception if either argument is not a number, returns an exception.
708 */
711 *frame, struct cons_pointer frame_pointer, struct
712 cons_pointer env ) {
713 struct cons_pointer result = NIL;
714 struct cons_space_object arg0 = pointer2cell( frame->arg[0] );
715 struct cons_space_object arg1 = pointer2cell( frame->arg[1] );
716
717 switch ( arg0.tag.value ) {
718 case EXCEPTIONTV:
719 result = frame->arg[0];
720 break;
721 case INTEGERTV:
722 switch ( arg1.tag.value ) {
723 case EXCEPTIONTV:
724 result = frame->arg[1];
725 break;
726 case INTEGERTV:{
727 result =
728 make_ratio( frame->arg[0], frame->arg[1], true );
729 }
730 break;
731 case RATIOTV:{
732 struct cons_pointer one = make_integer( 1, NIL );
733 struct cons_pointer ratio =
734 make_ratio( frame->arg[0], one, false );
735 inc_ref( ratio );
736 result = divide_ratio_ratio( ratio, frame->arg[1] );
737 dec_ref( ratio );
738 }
739 break;
740 case REALTV:
741 result =
742 make_real( to_long_double( frame->arg[0] ) /
743 to_long_double( frame->arg[1] ) );
744 break;
745 default:
748 ( L"Cannot divide: not a number" ),
749 frame_pointer );
750 break;
751 }
752 break;
753 case RATIOTV:
754 switch ( arg1.tag.value ) {
755 case EXCEPTIONTV:
756 result = frame->arg[1];
757 break;
758 case INTEGERTV:{
759 struct cons_pointer one = make_integer( 1, NIL );
760 struct cons_pointer ratio =
761 make_ratio( frame->arg[1], one, false );
762 result = divide_ratio_ratio( frame->arg[0], ratio );
763 dec_ref( ratio );
764 dec_ref( one );
765 }
766 break;
767 case RATIOTV:
768 result =
769 divide_ratio_ratio( frame->arg[0], frame->arg[1] );
770 break;
771 case REALTV:
772 result =
773 make_real( to_long_double( frame->arg[0] ) /
774 to_long_double( frame->arg[1] ) );
775 break;
776 default:
779 ( L"Cannot divide: not a number" ),
780 frame_pointer );
781 break;
782 }
783 break;
784 case REALTV:
785 result = exceptionp( frame->arg[1] ) ? frame->arg[1] :
786 make_real( to_long_double( frame->arg[0] ) /
787 to_long_double( frame->arg[1] ) );
788 break;
789 default:
792 ( L"Cannot divide: not a number" ),
793 frame_pointer );
794 break;
795 }
796
797 return result;
798}
799
800/**
801 * @brief Function: return a real (approcimately) equal in value to the ratio
802 * which is the first argument.
803 *
804 * @param frame
805 * @param frame_pointer
806 * @param env
807 * @return struct cons_pointer a pointer to a real
808 */
809// struct cons_pointer lisp_eval( struct stack_frame *frame, struct cons_pointer frame_pointer,
810// struct cons_pointer env )
812 struct cons_pointer frame_pointer,
813 struct cons_pointer env ) {
814 struct cons_pointer result = NIL;
815 struct cons_pointer rat = frame->arg[0];
816
817 debug_print( L"\nc_ratio_to_ld: ", DEBUG_ARITH );
819
820 if ( ratiop( rat ) ) {
821 result = make_real( c_ratio_to_ld( rat ) );
822 } // TODO: else throw an exception?
823
824 return result;
825}
#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_string_to_lisp_symbol(wchar_t *symbol)
Return a lisp symbol representation of this wide character string.
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
#define numberp(conspoint)
true if conspoint points to some sort of a number 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:104
void debug_dump_object(struct cons_pointer pointer, int level)
Like dump_object, q.v., but protected by the verbosity mechanism.
Definition debug.c:155
void debug_printf(int level, wchar_t *format,...)
wprintf adapted for the debug logging system.
Definition debug.c:120
void debug_print(wchar_t *message, int level)
print this debug message to stderr, if verbosity matches level.
Definition debug.c:60
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:138
#define DEBUG_ARITH
Print messages debugging arithmetic operations.
Definition debug.h:31
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:28
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:328
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 location, struct cons_pointer payload, struct cons_pointer frame_pointer)
Throw an exception.
Definition lispops.c:1396
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:248
struct cons_pointer absolute(struct cons_pointer arg)
if arg is a number, return the absolute value of that number, else NIL
Definition peano.c:125
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:395
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:538
bool is_negative(struct cons_pointer arg)
does this arg point to a negative number?
Definition peano.c:99
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:811
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:580
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:258
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:694
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:709
#define multiply_one_arg(arg)
Definition peano.c:493
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:165
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:502
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:360
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:593
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:217
long double c_ratio_to_ld(struct cons_pointer rat)
convert a ratio to an equivalent long double.
Definition ratio.c:384
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:94
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:206
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:179
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:258
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:139
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:295
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:317
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