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// 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:
300 ( L"Cannot add: not a number" ),
301 frame_pointer );
302 break;
303 }
304 break;
305 case RATIOTV:
306 switch ( cell2.tag.value ) {
307 case EXCEPTIONTV:
308 result = arg2;
309 break;
310 case INTEGERTV:
311 result = add_integer_ratio( arg2, arg1 );
312 break;
313 case RATIOTV:
314 result = add_ratio_ratio( arg1, arg2 );
315 break;
316 case REALTV:
317 result =
318 make_real( to_long_double( arg1 ) +
319 to_long_double( arg2 ) );
320 break;
321 default:
323 ( L"Cannot add: not a number" ),
324 frame_pointer );
325 break;
326 }
327 break;
328 case REALTV:
329 result =
330 make_real( to_long_double( arg1 ) +
331 to_long_double( arg2 ) );
332 break;
333 default:
334 result = exceptionp( arg2 ) ? arg2 :
336 ( L"Cannot add: not a number" ),
337 frame_pointer );
338 }
339 }
340
341 debug_print( L"}; => ", DEBUG_ARITH );
343 debug_print( L"\n", DEBUG_ARITH );
344
345 return result;
346}
347
348/**
349 * Add an indefinite number of numbers together
350 * @param env the evaluation environment - ignored;
351 * @param frame the stack frame.
352 * @return a pointer to an integer, ratio or real.
353 * @exception if any argument is not a number, returns an exception.
354 */
356 *frame, struct cons_pointer frame_pointer, struct
357 cons_pointer env ) {
358 struct cons_pointer result = make_integer( 0, NIL );
359 struct cons_pointer tmp;
360
361 for ( int i = 0;
362 i < args_in_frame &&
363 !nilp( frame->arg[i] ) && !exceptionp( result ); i++ ) {
364 tmp = result;
365 result = add_2( frame, frame_pointer, result, frame->arg[i] );
366 if ( !eq( tmp, result ) ) {
367 dec_ref( tmp );
368 }
369 }
370
371 struct cons_pointer more = frame->more;
372 while ( consp( more ) && !exceptionp( result ) ) {
373 tmp = result;
374 result = add_2( frame, frame_pointer, result, c_car( more ) );
375 if ( !eq( tmp, result ) ) {
376 dec_ref( tmp );
377 }
378
379 more = c_cdr( more );
380 }
381
382 return result;
383}
384
385
386/**
387 * return a cons_pointer indicating a number which is the product of
388 * the numbers indicated by `arg1` and `arg2`.
389 */
390struct cons_pointer multiply_2( struct stack_frame *frame,
391 struct cons_pointer frame_pointer,
392 struct cons_pointer arg1,
393 struct cons_pointer arg2 ) {
394 struct cons_pointer result;
395 struct cons_space_object cell1 = pointer2cell( arg1 );
396 struct cons_space_object cell2 = pointer2cell( arg2 );
397
398 debug_print( L"multiply_2( arg1 = ", DEBUG_ARITH );
400 debug_print( L"; arg2 = ", DEBUG_ARITH );
402 debug_print( L")\n", DEBUG_ARITH );
403
404 if ( zerop( arg1 ) ) {
405 result = arg2;
406 } else if ( zerop( arg2 ) ) {
407 result = arg1;
408 } else {
409 switch ( cell1.tag.value ) {
410 case EXCEPTIONTV:
411 result = arg1;
412 break;
413 case INTEGERTV:
414 switch ( cell2.tag.value ) {
415 case EXCEPTIONTV:
416 result = arg2;
417 break;
418 case INTEGERTV:
419 result = multiply_integers( arg1, arg2 );
420 break;
421 case RATIOTV:
422 result = multiply_integer_ratio( arg1, arg2 );
423 break;
424 case REALTV:
425 result =
426 make_real( to_long_double( arg1 ) *
427 to_long_double( arg2 ) );
428 break;
429 default:
430 result =
433 ( L"Cannot multiply: argument 2 is not a number: " ),
434 c_type( arg2 ) ),
435 frame_pointer );
436 break;
437 }
438 break;
439 case RATIOTV:
440 switch ( cell2.tag.value ) {
441 case EXCEPTIONTV:
442 result = arg2;
443 break;
444 case INTEGERTV:
445 result = multiply_integer_ratio( arg2, arg1 );
446 break;
447 case RATIOTV:
448 result = multiply_ratio_ratio( arg1, arg2 );
449 break;
450 case REALTV:
451 result =
452 make_real( to_long_double( arg1 ) *
453 to_long_double( arg2 ) );
454 break;
455 default:
456 result =
459 ( L"Cannot multiply: argument 2 is not a number" ),
460 c_type( arg2 ) ),
461 frame_pointer );
462 }
463 break;
464 case REALTV:
465 result = exceptionp( arg2 ) ? arg2 :
466 make_real( to_long_double( arg1 ) *
467 to_long_double( arg2 ) );
468 break;
469 default:
471 ( L"Cannot multiply: argument 1 is not a number" ),
472 c_type( arg1 ) ),
473 frame_pointer );
474 break;
475 }
476 }
477
478 debug_print( L"multiply_2 returning: ", DEBUG_ARITH );
480 debug_print( L"\n", DEBUG_ARITH );
481
482 return result;
483}
484
485#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 );}}
486
487/**
488 * Multiply an indefinite number of numbers together
489 * @param env the evaluation environment - ignored;
490 * @param frame the stack frame.
491 * @return a pointer to an integer, ratio or real.
492 * @exception if any argument is not a number, returns an exception.
493 */
496 *frame, struct cons_pointer frame_pointer, struct
497 cons_pointer env ) {
498 struct cons_pointer result = make_integer( 1, NIL );
499 struct cons_pointer tmp;
500
501 for ( int i = 0; i < args_in_frame && !nilp( frame->arg[i] )
502 && !exceptionp( result ); i++ ) {
503 debug_print( L"lisp_multiply: accumulator = ", DEBUG_ARITH );
505 debug_print( L"; arg = ", DEBUG_ARITH );
506 debug_print_object( frame->arg[i], DEBUG_ARITH );
508
509 multiply_one_arg( frame->arg[i] );
510 }
511
512 struct cons_pointer more = frame->more;
513 while ( consp( more )
514 && !exceptionp( result ) ) {
515 multiply_one_arg( c_car( more ) );
516 more = c_cdr( more );
517 }
518
519 debug_print( L"lisp_multiply returning: ", DEBUG_ARITH );
522
523 return result;
524}
525
526/**
527 * return a cons_pointer indicating a number which is the
528 * 0 - the number indicated by `arg`.
529 */
530struct cons_pointer negative( struct cons_pointer arg ) {
531 struct cons_pointer result = NIL;
532 struct cons_space_object cell = pointer2cell( arg );
533
534 switch ( cell.tag.value ) {
535 case EXCEPTIONTV:
536 result = arg;
537 break;
538 case INTEGERTV:
539 result =
540 make_integer( 0 - cell.payload.integer.value,
541 cell.payload.integer.more );
542 break;
543 case NILTV:
544 result = TRUE;
545 break;
546 case RATIOTV:
547 result = make_ratio( negative( cell.payload.ratio.dividend ),
548 cell.payload.ratio.divisor, false );
549 break;
550 case REALTV:
551 result = make_real( 0 - to_long_double( arg ) );
552 break;
553 case TRUETV:
554 result = NIL;
555 break;
556 }
557
558 return result;
559}
560
561
562/**
563 * Function: is this number negative?
564 *
565 * * (negative? arg)
566 *
567 * @param env the evaluation environment - ignored;
568 * @param frame the stack frame.
569 * @return T if the first argument was a negative number, or NIL if it
570 * was not.
571 */
573 *frame,
574 struct cons_pointer frame_pointer, struct
575 cons_pointer env ) {
576 return is_negative( frame->arg[0] ) ? TRUE : NIL;
577}
578
579
580/**
581 * return a cons_pointer indicating a number which is the result of
582 * subtracting the number indicated by `arg2` from that indicated by `arg1`,
583 * in the context of this `frame`.
584 */
585struct cons_pointer subtract_2( struct stack_frame *frame,
586 struct cons_pointer frame_pointer,
587 struct cons_pointer arg1,
588 struct cons_pointer arg2 ) {
589 struct cons_pointer result = NIL;
590
591 switch ( pointer2cell( arg1 ).tag.value ) {
592 case EXCEPTIONTV:
593 result = arg1;
594 break;
595 case INTEGERTV:
596 switch ( pointer2cell( arg2 ).tag.value ) {
597 case EXCEPTIONTV:
598 result = arg2;
599 break;
600 case INTEGERTV:{
601 struct cons_pointer i = negative( arg2 );
602 inc_ref( i );
603 result = add_integers( arg1, i );
604 dec_ref( i );
605 }
606 break;
607 case RATIOTV:{
608 struct cons_pointer tmp = make_ratio( arg1,
609 make_integer( 1,
610 NIL ),
611 false );
612 inc_ref( tmp );
613 result = subtract_ratio_ratio( tmp, arg2 );
614 dec_ref( tmp );
615 }
616 break;
617 case REALTV:
618 result =
619 make_real( to_long_double( arg1 ) -
620 to_long_double( arg2 ) );
621 break;
622 default:
624 ( L"Cannot subtract: not a number" ),
625 frame_pointer );
626 break;
627 }
628 break;
629 case RATIOTV:
630 switch ( pointer2cell( arg2 ).tag.value ) {
631 case EXCEPTIONTV:
632 result = arg2;
633 break;
634 case INTEGERTV:{
635 struct cons_pointer tmp = make_ratio( arg2,
636 make_integer( 1,
637 NIL ),
638 false );
639 inc_ref( tmp );
640 result = subtract_ratio_ratio( arg1, tmp );
641 dec_ref( tmp );
642 }
643 break;
644 case RATIOTV:
645 result = subtract_ratio_ratio( arg1, arg2 );
646 break;
647 case REALTV:
648 result =
649 make_real( to_long_double( arg1 ) -
650 to_long_double( arg2 ) );
651 break;
652 default:
654 ( L"Cannot subtract: not a number" ),
655 frame_pointer );
656 break;
657 }
658 break;
659 case REALTV:
660 result = exceptionp( arg2 ) ? arg2 :
661 make_real( to_long_double( arg1 ) - to_long_double( arg2 ) );
662 break;
663 default:
665 ( L"Cannot subtract: not a number" ),
666 frame_pointer );
667 break;
668 }
669
670 // and if not nilp[frame->arg[2]) we also have an error.
671
672 return result;
673}
674
675/**
676 * Subtract one number from another. If more than two arguments are passed
677 * in the frame, the additional arguments are ignored.
678 * @param env the evaluation environment - ignored;
679 * @param frame the stack frame.
680 * @return a pointer to an integer, ratio or real.
681 * @exception if either argument is not a number, returns an exception.
682 */
685 *frame, struct cons_pointer frame_pointer, struct
686 cons_pointer env ) {
687 return subtract_2( frame, frame_pointer, frame->arg[0], frame->arg[1] );
688}
689
690/**
691 * Divide one number by another. If more than two arguments are passed
692 * in the frame, the additional arguments are ignored.
693 * @param env the evaluation environment - ignored;
694 * @param frame the stack frame.
695 * @return a pointer to an integer or real.
696 * @exception if either argument is not a number, returns an exception.
697 */
700 *frame, struct cons_pointer frame_pointer, struct
701 cons_pointer env ) {
702 struct cons_pointer result = NIL;
703 struct cons_space_object arg0 = pointer2cell( frame->arg[0] );
704 struct cons_space_object arg1 = pointer2cell( frame->arg[1] );
705
706 switch ( arg0.tag.value ) {
707 case EXCEPTIONTV:
708 result = frame->arg[0];
709 break;
710 case INTEGERTV:
711 switch ( arg1.tag.value ) {
712 case EXCEPTIONTV:
713 result = frame->arg[1];
714 break;
715 case INTEGERTV:{
716 result =
717 make_ratio( frame->arg[0], frame->arg[1], true );
718 }
719 break;
720 case RATIOTV:{
721 struct cons_pointer one = make_integer( 1, NIL );
722 struct cons_pointer ratio =
723 make_ratio( frame->arg[0], one, false );
724 inc_ref( ratio );
725 result = divide_ratio_ratio( ratio, frame->arg[1] );
726 dec_ref( ratio );
727 }
728 break;
729 case REALTV:
730 result =
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 break;
741 case RATIOTV:
742 switch ( arg1.tag.value ) {
743 case EXCEPTIONTV:
744 result = frame->arg[1];
745 break;
746 case INTEGERTV:{
747 struct cons_pointer one = make_integer( 1, NIL );
748 struct cons_pointer ratio =
749 make_ratio( frame->arg[1], one, false );
750 result = divide_ratio_ratio( frame->arg[0], ratio );
751 dec_ref( ratio );
752 dec_ref( one );
753 }
754 break;
755 case RATIOTV:
756 result =
757 divide_ratio_ratio( frame->arg[0], frame->arg[1] );
758 break;
759 case REALTV:
760 result =
761 make_real( to_long_double( frame->arg[0] ) /
762 to_long_double( frame->arg[1] ) );
763 break;
764 default:
766 ( L"Cannot divide: not a number" ),
767 frame_pointer );
768 break;
769 }
770 break;
771 case REALTV:
772 result = exceptionp( frame->arg[1] ) ? frame->arg[1] :
773 make_real( to_long_double( frame->arg[0] ) /
774 to_long_double( frame->arg[1] ) );
775 break;
776 default:
778 ( L"Cannot divide: not a number" ),
779 frame_pointer );
780 break;
781 }
782
783 return result;
784}
785
786/**
787 * @brief Function: return a real (approcimately) equal in value to the ratio
788 * which is the first argument.
789 *
790 * @param frame
791 * @param frame_pointer
792 * @param env
793 * @return struct cons_pointer a pointer to a real
794 */
795// struct cons_pointer lisp_eval( struct stack_frame *frame, struct cons_pointer frame_pointer,
796// struct cons_pointer env )
798 struct cons_pointer frame_pointer,
799 struct cons_pointer env ) {
800 struct cons_pointer result = NIL;
801 struct cons_pointer rat = frame->arg[0];
802
803 debug_print( L"\nc_ratio_to_ld: ", DEBUG_ARITH );
805
806 if ( ratiop( rat ) ) {
807 result = make_real( c_ratio_to_ld( rat ) );
808 } // TODO: else throw an exception?
809
810 return result;
811}
#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
#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: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: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: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:1249
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:390
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:530
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:797
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:572
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:683
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:698
#define multiply_one_arg(arg)
Definition peano.c:485
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:494
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:355
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:585
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: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: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:204
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:177
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:255
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:138
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:291
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:313
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