2 * Copyright © 2016 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
15 #include "ao_scheme.h"
20 builtin_size(void *addr)
23 return sizeof (struct ao_scheme_builtin);
27 builtin_mark(void *addr)
33 builtin_move(void *addr)
38 const struct ao_scheme_type ao_scheme_builtin_type = {
44 #ifdef AO_SCHEME_MAKE_CONST
46 #define AO_SCHEME_BUILTIN_CASENAME
47 #include "ao_scheme_builtin.h"
49 char *ao_scheme_args_name(uint8_t args) {
50 args &= AO_SCHEME_FUNC_MASK;
52 case AO_SCHEME_FUNC_LAMBDA: return ao_scheme_poly_atom(_ao_scheme_atom_lambda)->name;
53 case AO_SCHEME_FUNC_NLAMBDA: return ao_scheme_poly_atom(_ao_scheme_atom_nlambda)->name;
54 case AO_SCHEME_FUNC_MACRO: return ao_scheme_poly_atom(_ao_scheme_atom_macro)->name;
55 default: return (char *) "???";
60 #define AO_SCHEME_BUILTIN_ARRAYNAME
61 #include "ao_scheme_builtin.h"
64 ao_scheme_builtin_name(enum ao_scheme_builtin_id b) {
65 if (b < _builtin_last)
66 return ao_scheme_poly_atom(builtin_names[b])->name;
67 return (char *) "???";
70 static const ao_poly ao_scheme_args_atoms[] = {
71 [AO_SCHEME_FUNC_LAMBDA] = _ao_scheme_atom_lambda,
72 [AO_SCHEME_FUNC_NLAMBDA] = _ao_scheme_atom_nlambda,
73 [AO_SCHEME_FUNC_MACRO] = _ao_scheme_atom_macro,
77 ao_scheme_args_name(uint8_t args)
79 args &= AO_SCHEME_FUNC_MASK;
80 if (args < sizeof ao_scheme_args_atoms / sizeof ao_scheme_args_atoms[0])
81 return ao_scheme_poly_atom(ao_scheme_args_atoms[args])->name;
82 return (char *) "(unknown)";
87 ao_scheme_builtin_write(ao_poly b)
89 struct ao_scheme_builtin *builtin = ao_scheme_poly_builtin(b);
90 printf("%s", ao_scheme_builtin_name(builtin->func));
94 ao_scheme_check_argc(ao_poly name, struct ao_scheme_cons *cons, int min, int max)
98 while (cons && argc <= max) {
100 cons = ao_scheme_cons_cdr(cons);
102 if (argc < min || argc > max)
103 return ao_scheme_error(AO_SCHEME_INVALID, "%s: invalid arg count", ao_scheme_poly_atom(name)->name);
104 return _ao_scheme_bool_true;
108 ao_scheme_arg(struct ao_scheme_cons *cons, int argc)
111 return AO_SCHEME_NIL;
114 return AO_SCHEME_NIL;
115 cons = ao_scheme_cons_cdr(cons);
121 ao_scheme_check_argt(ao_poly name, struct ao_scheme_cons *cons, int argc, int type, int nil_ok)
123 ao_poly car = ao_scheme_arg(cons, argc);
125 if ((!car && !nil_ok) || ao_scheme_poly_type(car) != type)
126 return ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, car);
127 return _ao_scheme_bool_true;
131 ao_scheme_arg_int(ao_poly name, struct ao_scheme_cons *cons, int argc)
133 ao_poly p = ao_scheme_arg(cons, argc);
134 int32_t i = ao_scheme_poly_integer(p);
136 if (i == AO_SCHEME_NOT_INTEGER)
137 (void) ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, p);
142 ao_scheme_do_car(struct ao_scheme_cons *cons)
144 if (!ao_scheme_check_argc(_ao_scheme_atom_car, cons, 1, 1))
145 return AO_SCHEME_NIL;
146 if (!ao_scheme_check_argt(_ao_scheme_atom_car, cons, 0, AO_SCHEME_CONS, 0))
147 return AO_SCHEME_NIL;
148 return ao_scheme_poly_cons(cons->car)->car;
152 ao_scheme_do_cdr(struct ao_scheme_cons *cons)
154 if (!ao_scheme_check_argc(_ao_scheme_atom_cdr, cons, 1, 1))
155 return AO_SCHEME_NIL;
156 if (!ao_scheme_check_argt(_ao_scheme_atom_cdr, cons, 0, AO_SCHEME_CONS, 0))
157 return AO_SCHEME_NIL;
158 return ao_scheme_poly_cons(cons->car)->cdr;
162 ao_scheme_do_cons(struct ao_scheme_cons *cons)
165 if(!ao_scheme_check_argc(_ao_scheme_atom_cons, cons, 2, 2))
166 return AO_SCHEME_NIL;
167 car = ao_scheme_arg(cons, 0);
168 cdr = ao_scheme_arg(cons, 1);
169 return ao_scheme__cons(car, cdr);
173 ao_scheme_do_last(struct ao_scheme_cons *cons)
175 struct ao_scheme_cons *list;
176 if (!ao_scheme_check_argc(_ao_scheme_atom_last, cons, 1, 1))
177 return AO_SCHEME_NIL;
178 if (!ao_scheme_check_argt(_ao_scheme_atom_last, cons, 0, AO_SCHEME_CONS, 1))
179 return AO_SCHEME_NIL;
180 for (list = ao_scheme_poly_cons(ao_scheme_arg(cons, 0));
182 list = ao_scheme_cons_cdr(list))
187 return AO_SCHEME_NIL;
191 ao_scheme_do_length(struct ao_scheme_cons *cons)
193 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
194 return AO_SCHEME_NIL;
195 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
196 return AO_SCHEME_NIL;
197 return ao_scheme_int_poly(ao_scheme_cons_length(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
201 ao_scheme_do_list_copy(struct ao_scheme_cons *cons)
203 struct ao_scheme_cons *new;
205 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
206 return AO_SCHEME_NIL;
207 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
208 return AO_SCHEME_NIL;
209 new = ao_scheme_cons_copy(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
210 return ao_scheme_cons_poly(new);
214 ao_scheme_do_quote(struct ao_scheme_cons *cons)
216 if (!ao_scheme_check_argc(_ao_scheme_atom_quote, cons, 1, 1))
217 return AO_SCHEME_NIL;
218 return ao_scheme_arg(cons, 0);
222 ao_scheme_do_set(struct ao_scheme_cons *cons)
224 if (!ao_scheme_check_argc(_ao_scheme_atom_set, cons, 2, 2))
225 return AO_SCHEME_NIL;
226 if (!ao_scheme_check_argt(_ao_scheme_atom_set, cons, 0, AO_SCHEME_ATOM, 0))
227 return AO_SCHEME_NIL;
229 return ao_scheme_atom_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
233 ao_scheme_do_def(struct ao_scheme_cons *cons)
235 if (!ao_scheme_check_argc(_ao_scheme_atom_def, cons, 2, 2))
236 return AO_SCHEME_NIL;
237 if (!ao_scheme_check_argt(_ao_scheme_atom_def, cons, 0, AO_SCHEME_ATOM, 0))
238 return AO_SCHEME_NIL;
240 return ao_scheme_atom_def(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
244 ao_scheme_do_setq(struct ao_scheme_cons *cons)
247 if (!ao_scheme_check_argc(_ao_scheme_atom_set21, cons, 2, 2))
248 return AO_SCHEME_NIL;
250 if (ao_scheme_poly_type(name) != AO_SCHEME_ATOM)
251 return ao_scheme_error(AO_SCHEME_INVALID, "set! of non-atom %v", name);
252 if (!ao_scheme_atom_ref(name, NULL))
253 return ao_scheme_error(AO_SCHEME_INVALID, "atom %v not defined", name);
254 return ao_scheme__cons(_ao_scheme_atom_set,
255 ao_scheme__cons(ao_scheme__cons(_ao_scheme_atom_quote,
256 ao_scheme__cons(name, AO_SCHEME_NIL)),
261 ao_scheme_do_cond(struct ao_scheme_cons *cons)
263 ao_scheme_set_cond(cons);
264 return AO_SCHEME_NIL;
268 ao_scheme_do_begin(struct ao_scheme_cons *cons)
270 ao_scheme_stack->state = eval_begin;
271 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
272 return AO_SCHEME_NIL;
276 ao_scheme_do_while(struct ao_scheme_cons *cons)
278 ao_scheme_stack->state = eval_while;
279 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
280 return AO_SCHEME_NIL;
284 ao_scheme_do_write(struct ao_scheme_cons *cons)
286 ao_poly val = AO_SCHEME_NIL;
289 ao_scheme_poly_write(val);
290 cons = ao_scheme_cons_cdr(cons);
294 return _ao_scheme_bool_true;
298 ao_scheme_do_display(struct ao_scheme_cons *cons)
300 ao_poly val = AO_SCHEME_NIL;
303 ao_scheme_poly_display(val);
304 cons = ao_scheme_cons_cdr(cons);
306 return _ao_scheme_bool_true;
310 ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
312 struct ao_scheme_cons *cons;
313 ao_poly ret = AO_SCHEME_NIL;
315 for (cons = orig_cons; cons; cons = ao_scheme_cons_cdr(cons)) {
316 ao_poly car = cons->car;
317 uint8_t rt = ao_scheme_poly_type(ret);
318 uint8_t ct = ao_scheme_poly_type(car);
320 if (cons == orig_cons) {
322 ao_scheme_cons_stash(0, cons);
323 if (cons->cdr == AO_SCHEME_NIL) {
326 if (ao_scheme_integer_typep(ct))
327 ret = ao_scheme_integer_poly(-ao_scheme_poly_integer(ret));
328 #ifdef AO_SCHEME_FEATURE_FLOAT
329 else if (ct == AO_SCHEME_FLOAT)
330 ret = ao_scheme_float_get(-ao_scheme_poly_number(ret));
334 if (ao_scheme_integer_typep(ct) && ao_scheme_poly_integer(ret) == 1) {
336 #ifdef AO_SCHEME_FEATURE_FLOAT
337 if (ao_scheme_number_typep(ct)) {
338 float v = ao_scheme_poly_number(ret);
339 ret = ao_scheme_float_get(1/v);
342 ret = ao_scheme_integer_poly(0);
350 cons = ao_scheme_cons_fetch(0);
351 } else if (ao_scheme_integer_typep(rt) && ao_scheme_integer_typep(ct)) {
352 int32_t r = ao_scheme_poly_integer(ret);
353 int32_t c = ao_scheme_poly_integer(car);
354 #ifdef AO_SCHEME_FEATURE_FLOAT
362 #ifdef AO_SCHEME_FEATURE_FLOAT
363 if (r < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < r)
372 #ifdef AO_SCHEME_FEATURE_FLOAT
373 t = (int64_t) r * (int64_t) c;
374 if (t < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < t)
382 #ifdef AO_SCHEME_FEATURE_FLOAT
383 if (c != 0 && (r % c) == 0)
391 case builtin_quotient:
393 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "quotient by zero");
394 if (r % c != 0 && (c < 0) != (r < 0))
399 case builtin_remainder:
401 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "remainder by zero");
406 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "modulo by zero");
408 if ((r < 0) != (c < 0))
414 ao_scheme_cons_stash(0, cons);
415 ret = ao_scheme_integer_poly(r);
416 cons = ao_scheme_cons_fetch(0);
417 #ifdef AO_SCHEME_FEATURE_FLOAT
418 } else if (ao_scheme_number_typep(rt) && ao_scheme_number_typep(ct)) {
421 r = ao_scheme_poly_number(ret);
422 c = ao_scheme_poly_number(car);
436 case builtin_quotient:
437 case builtin_remainder:
439 return ao_scheme_error(AO_SCHEME_INVALID, "non-integer value in integer divide");
443 ao_scheme_cons_stash(0, cons);
444 ret = ao_scheme_float_get(r);
445 cons = ao_scheme_cons_fetch(0);
448 else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus) {
449 ao_scheme_cons_stash(0, cons);
450 ret = ao_scheme_string_poly(ao_scheme_string_cat(ao_scheme_poly_string(ret),
451 ao_scheme_poly_string(car)));
452 cons = ao_scheme_cons_fetch(0);
457 return ao_scheme_error(AO_SCHEME_INVALID, "invalid args");
463 ao_scheme_do_plus(struct ao_scheme_cons *cons)
465 return ao_scheme_math(cons, builtin_plus);
469 ao_scheme_do_minus(struct ao_scheme_cons *cons)
471 return ao_scheme_math(cons, builtin_minus);
475 ao_scheme_do_times(struct ao_scheme_cons *cons)
477 return ao_scheme_math(cons, builtin_times);
481 ao_scheme_do_divide(struct ao_scheme_cons *cons)
483 return ao_scheme_math(cons, builtin_divide);
487 ao_scheme_do_quotient(struct ao_scheme_cons *cons)
489 return ao_scheme_math(cons, builtin_quotient);
493 ao_scheme_do_modulo(struct ao_scheme_cons *cons)
495 return ao_scheme_math(cons, builtin_modulo);
499 ao_scheme_do_remainder(struct ao_scheme_cons *cons)
501 return ao_scheme_math(cons, builtin_remainder);
505 ao_scheme_compare(struct ao_scheme_cons *cons, enum ao_scheme_builtin_id op)
510 return _ao_scheme_bool_true;
513 for (cons = ao_scheme_cons_cdr(cons); cons; cons = ao_scheme_cons_cdr(cons)) {
514 ao_poly right = cons->car;
516 if (op == builtin_equal && left == right) {
519 uint8_t lt = ao_scheme_poly_type(left);
520 uint8_t rt = ao_scheme_poly_type(right);
521 if (ao_scheme_integer_typep(lt) && ao_scheme_integer_typep(rt)) {
522 int32_t l = ao_scheme_poly_integer(left);
523 int32_t r = ao_scheme_poly_integer(right);
528 return _ao_scheme_bool_false;
530 case builtin_greater:
532 return _ao_scheme_bool_false;
534 case builtin_less_equal:
536 return _ao_scheme_bool_false;
538 case builtin_greater_equal:
540 return _ao_scheme_bool_false;
544 return _ao_scheme_bool_false;
548 #ifdef AO_SCHEME_FEATURE_FLOAT
549 } else if (ao_scheme_number_typep(lt) && ao_scheme_number_typep(rt)) {
552 l = ao_scheme_poly_number(left);
553 r = ao_scheme_poly_number(right);
558 return _ao_scheme_bool_false;
560 case builtin_greater:
562 return _ao_scheme_bool_false;
564 case builtin_less_equal:
566 return _ao_scheme_bool_false;
568 case builtin_greater_equal:
570 return _ao_scheme_bool_false;
574 return _ao_scheme_bool_false;
578 #endif /* AO_SCHEME_FEATURE_FLOAT */
579 } else if (lt == AO_SCHEME_STRING && rt == AO_SCHEME_STRING) {
580 int c = strcmp(ao_scheme_poly_string(left),
581 ao_scheme_poly_string(right));
585 return _ao_scheme_bool_false;
587 case builtin_greater:
589 return _ao_scheme_bool_false;
591 case builtin_less_equal:
593 return _ao_scheme_bool_false;
595 case builtin_greater_equal:
597 return _ao_scheme_bool_false;
601 return _ao_scheme_bool_false;
607 return _ao_scheme_bool_false;
611 return _ao_scheme_bool_true;
615 ao_scheme_do_equal(struct ao_scheme_cons *cons)
617 return ao_scheme_compare(cons, builtin_equal);
621 ao_scheme_do_less(struct ao_scheme_cons *cons)
623 return ao_scheme_compare(cons, builtin_less);
627 ao_scheme_do_greater(struct ao_scheme_cons *cons)
629 return ao_scheme_compare(cons, builtin_greater);
633 ao_scheme_do_less_equal(struct ao_scheme_cons *cons)
635 return ao_scheme_compare(cons, builtin_less_equal);
639 ao_scheme_do_greater_equal(struct ao_scheme_cons *cons)
641 return ao_scheme_compare(cons, builtin_greater_equal);
645 ao_scheme_do_list_to_string(struct ao_scheme_cons *cons)
647 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3estring, cons, 1, 1))
648 return AO_SCHEME_NIL;
649 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3estring, cons, 0, AO_SCHEME_CONS, 1))
650 return AO_SCHEME_NIL;
651 return ao_scheme_string_pack(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
655 ao_scheme_do_string_to_list(struct ao_scheme_cons *cons)
657 if (!ao_scheme_check_argc(_ao_scheme_atom_string2d3elist, cons, 1, 1))
658 return AO_SCHEME_NIL;
659 if (!ao_scheme_check_argt(_ao_scheme_atom_string2d3elist, cons, 0, AO_SCHEME_STRING, 0))
660 return AO_SCHEME_NIL;
661 return ao_scheme_string_unpack(ao_scheme_poly_string(ao_scheme_arg(cons, 0)));
665 ao_scheme_do_string_ref(struct ao_scheme_cons *cons)
669 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dref, cons, 2, 2))
670 return AO_SCHEME_NIL;
671 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dref, cons, 0, AO_SCHEME_STRING, 0))
672 return AO_SCHEME_NIL;
673 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dref, cons, 1);
674 if (ref == AO_SCHEME_NOT_INTEGER)
675 return AO_SCHEME_NIL;
676 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
677 while (*string && ref) {
682 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
683 _ao_scheme_atom_string2dref,
684 ao_scheme_arg(cons, 0),
685 ao_scheme_arg(cons, 1));
686 return ao_scheme_int_poly(*string);
690 ao_scheme_do_string_length(struct ao_scheme_cons *cons)
694 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dlength, cons, 1, 1))
695 return AO_SCHEME_NIL;
696 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dlength, cons, 0, AO_SCHEME_STRING, 0))
697 return AO_SCHEME_NIL;
698 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
699 return ao_scheme_integer_poly(strlen(string));
703 ao_scheme_do_string_copy(struct ao_scheme_cons *cons)
707 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dcopy, cons, 1, 1))
708 return AO_SCHEME_NIL;
709 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dcopy, cons, 0, AO_SCHEME_STRING, 0))
710 return AO_SCHEME_NIL;
711 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
712 return ao_scheme_string_poly(ao_scheme_string_copy(string));
716 ao_scheme_do_string_set(struct ao_scheme_cons *cons)
722 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dset21, cons, 3, 3))
723 return AO_SCHEME_NIL;
724 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dset21, cons, 0, AO_SCHEME_STRING, 0))
725 return AO_SCHEME_NIL;
726 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
727 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 1);
728 if (ref == AO_SCHEME_NOT_INTEGER)
729 return AO_SCHEME_NIL;
730 val = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 2);
731 if (val == AO_SCHEME_NOT_INTEGER)
732 return AO_SCHEME_NIL;
733 while (*string && ref) {
738 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
739 _ao_scheme_atom_string2dset21,
740 ao_scheme_arg(cons, 0),
741 ao_scheme_arg(cons, 1));
743 return ao_scheme_int_poly(*string);
747 ao_scheme_do_flush_output(struct ao_scheme_cons *cons)
749 if (!ao_scheme_check_argc(_ao_scheme_atom_flush2doutput, cons, 0, 0))
750 return AO_SCHEME_NIL;
751 ao_scheme_os_flush();
752 return _ao_scheme_bool_true;
756 ao_scheme_do_led(struct ao_scheme_cons *cons)
759 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
760 return AO_SCHEME_NIL;
761 led = ao_scheme_arg_int(_ao_scheme_atom_led, cons, 0);
762 if (led == AO_SCHEME_NOT_INTEGER)
763 return AO_SCHEME_NIL;
764 led = ao_scheme_arg(cons, 0);
765 ao_scheme_os_led(ao_scheme_poly_int(led));
770 ao_scheme_do_delay(struct ao_scheme_cons *cons)
774 if (!ao_scheme_check_argc(_ao_scheme_atom_delay, cons, 1, 1))
775 return AO_SCHEME_NIL;
776 delay = ao_scheme_arg_int(_ao_scheme_atom_delay, cons, 0);
777 if (delay == AO_SCHEME_NOT_INTEGER)
778 return AO_SCHEME_NIL;
779 ao_scheme_os_delay(delay);
784 ao_scheme_do_eval(struct ao_scheme_cons *cons)
786 if (!ao_scheme_check_argc(_ao_scheme_atom_eval, cons, 1, 1))
787 return AO_SCHEME_NIL;
788 ao_scheme_stack->state = eval_sexpr;
793 ao_scheme_do_apply(struct ao_scheme_cons *cons)
795 if (!ao_scheme_check_argc(_ao_scheme_atom_apply, cons, 2, INT_MAX))
796 return AO_SCHEME_NIL;
797 ao_scheme_stack->state = eval_apply;
798 return ao_scheme_cons_poly(cons);
802 ao_scheme_do_read(struct ao_scheme_cons *cons)
804 if (!ao_scheme_check_argc(_ao_scheme_atom_read, cons, 0, 0))
805 return AO_SCHEME_NIL;
806 return ao_scheme_read();
810 ao_scheme_do_collect(struct ao_scheme_cons *cons)
814 free = ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
815 return ao_scheme_integer_poly(free);
819 ao_scheme_do_nullp(struct ao_scheme_cons *cons)
821 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
822 return AO_SCHEME_NIL;
823 if (ao_scheme_arg(cons, 0) == AO_SCHEME_NIL)
824 return _ao_scheme_bool_true;
826 return _ao_scheme_bool_false;
830 ao_scheme_do_not(struct ao_scheme_cons *cons)
832 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
833 return AO_SCHEME_NIL;
834 if (ao_scheme_arg(cons, 0) == _ao_scheme_bool_false)
835 return _ao_scheme_bool_true;
837 return _ao_scheme_bool_false;
841 ao_scheme_do_typep(int type, struct ao_scheme_cons *cons)
843 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
844 return AO_SCHEME_NIL;
845 if (ao_scheme_poly_type(ao_scheme_arg(cons, 0)) == type)
846 return _ao_scheme_bool_true;
847 return _ao_scheme_bool_false;
851 ao_scheme_do_pairp(struct ao_scheme_cons *cons)
854 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
855 return AO_SCHEME_NIL;
856 v = ao_scheme_arg(cons, 0);
857 if (v != AO_SCHEME_NIL && ao_scheme_poly_type(v) == AO_SCHEME_CONS)
858 return _ao_scheme_bool_true;
859 return _ao_scheme_bool_false;
863 ao_scheme_do_integerp(struct ao_scheme_cons *cons)
865 #ifdef AO_SCHEME_FEATURE_BIGINT
866 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
867 return AO_SCHEME_NIL;
868 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
870 case AO_SCHEME_BIGINT:
871 return _ao_scheme_bool_true;
873 return _ao_scheme_bool_false;
876 return ao_scheme_do_typep(AO_SCHEME_INT, cons);
881 ao_scheme_do_numberp(struct ao_scheme_cons *cons)
883 #if defined(AO_SCHEME_FEATURE_BIGINT) || defined(AO_SCHEME_FEATURE_FLOAT)
884 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
885 return AO_SCHEME_NIL;
886 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
888 #ifdef AO_SCHEME_FEATURE_BIGINT
889 case AO_SCHEME_BIGINT:
891 #ifdef AO_SCHEME_FEATURE_FLOAT
892 case AO_SCHEME_FLOAT:
894 return _ao_scheme_bool_true;
896 return _ao_scheme_bool_false;
899 return ao_scheme_do_integerp(cons);
904 ao_scheme_do_stringp(struct ao_scheme_cons *cons)
906 return ao_scheme_do_typep(AO_SCHEME_STRING, cons);
910 ao_scheme_do_symbolp(struct ao_scheme_cons *cons)
912 return ao_scheme_do_typep(AO_SCHEME_ATOM, cons);
916 ao_scheme_do_booleanp(struct ao_scheme_cons *cons)
918 return ao_scheme_do_typep(AO_SCHEME_BOOL, cons);
922 ao_scheme_do_procedurep(struct ao_scheme_cons *cons)
924 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
925 return AO_SCHEME_NIL;
926 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
927 case AO_SCHEME_BUILTIN:
928 case AO_SCHEME_LAMBDA:
929 return _ao_scheme_bool_true;
931 return _ao_scheme_bool_false;
935 /* This one is special -- a list is either nil or
936 * a 'proper' list with only cons cells
939 ao_scheme_do_listp(struct ao_scheme_cons *cons)
942 if (!ao_scheme_check_argc(_ao_scheme_atom_list3f, cons, 1, 1))
943 return AO_SCHEME_NIL;
944 v = ao_scheme_arg(cons, 0);
946 if (v == AO_SCHEME_NIL)
947 return _ao_scheme_bool_true;
948 if (ao_scheme_poly_type(v) != AO_SCHEME_CONS)
949 return _ao_scheme_bool_false;
950 v = ao_scheme_poly_cons(v)->cdr;
955 ao_scheme_do_set_car(struct ao_scheme_cons *cons)
957 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
958 return AO_SCHEME_NIL;
959 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
960 return AO_SCHEME_NIL;
961 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->car = ao_scheme_arg(cons, 1);
965 ao_scheme_do_set_cdr(struct ao_scheme_cons *cons)
967 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
968 return AO_SCHEME_NIL;
969 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
970 return AO_SCHEME_NIL;
971 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->cdr = ao_scheme_arg(cons, 1);
975 ao_scheme_do_symbol_to_string(struct ao_scheme_cons *cons)
977 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
978 return AO_SCHEME_NIL;
979 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_ATOM, 0))
980 return AO_SCHEME_NIL;
981 return ao_scheme_string_poly(ao_scheme_string_copy(ao_scheme_poly_atom(ao_scheme_arg(cons, 0))->name));
985 ao_scheme_do_string_to_symbol(struct ao_scheme_cons *cons)
987 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
988 return AO_SCHEME_NIL;
989 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_STRING, 0))
990 return AO_SCHEME_NIL;
992 return ao_scheme_atom_poly(ao_scheme_atom_intern(ao_scheme_poly_string(ao_scheme_arg(cons, 0))));
996 ao_scheme_do_read_char(struct ao_scheme_cons *cons)
999 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1000 return AO_SCHEME_NIL;
1002 return ao_scheme_int_poly(c);
1006 ao_scheme_do_write_char(struct ao_scheme_cons *cons)
1008 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1009 return AO_SCHEME_NIL;
1010 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_INT, 0))
1011 return AO_SCHEME_NIL;
1012 putchar(ao_scheme_poly_integer(ao_scheme_arg(cons, 0)));
1013 return _ao_scheme_bool_true;
1017 ao_scheme_do_exit(struct ao_scheme_cons *cons)
1019 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1020 return AO_SCHEME_NIL;
1021 ao_scheme_exception |= AO_SCHEME_EXIT;
1022 return _ao_scheme_bool_true;
1026 ao_scheme_do_current_jiffy(struct ao_scheme_cons *cons)
1030 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1031 return AO_SCHEME_NIL;
1032 jiffy = ao_scheme_os_jiffy();
1033 return (ao_scheme_int_poly(jiffy));
1037 ao_scheme_do_current_second(struct ao_scheme_cons *cons)
1041 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1042 return AO_SCHEME_NIL;
1043 second = ao_scheme_os_jiffy() / AO_SCHEME_JIFFIES_PER_SECOND;
1044 return (ao_scheme_int_poly(second));
1048 ao_scheme_do_jiffies_per_second(struct ao_scheme_cons *cons)
1050 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1051 return AO_SCHEME_NIL;
1052 return (ao_scheme_int_poly(AO_SCHEME_JIFFIES_PER_SECOND));
1055 #ifdef AO_SCHEME_FEATURE_VECTOR
1058 ao_scheme_do_vector(struct ao_scheme_cons *cons)
1060 return ao_scheme_vector_poly(ao_scheme_list_to_vector(cons));
1064 ao_scheme_do_make_vector(struct ao_scheme_cons *cons)
1068 if (!ao_scheme_check_argc(_ao_scheme_atom_make2dvector, cons, 2, 2))
1069 return AO_SCHEME_NIL;
1070 k = ao_scheme_arg_int(_ao_scheme_atom_make2dvector, cons, 0);
1071 if (k == AO_SCHEME_NOT_INTEGER)
1072 return AO_SCHEME_NIL;
1073 return ao_scheme_vector_poly(ao_scheme_vector_alloc(k, ao_scheme_arg(cons, 1)));
1077 ao_scheme_do_vector_ref(struct ao_scheme_cons *cons)
1079 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dref, cons, 2, 2))
1080 return AO_SCHEME_NIL;
1081 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dref, cons, 0, AO_SCHEME_VECTOR, 0))
1082 return AO_SCHEME_NIL;
1083 return ao_scheme_vector_get(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
1087 ao_scheme_do_vector_set(struct ao_scheme_cons *cons)
1089 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dset21, cons, 3, 3))
1090 return AO_SCHEME_NIL;
1091 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dset21, cons, 0, AO_SCHEME_VECTOR, 0))
1092 return AO_SCHEME_NIL;
1093 return ao_scheme_vector_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1), ao_scheme_arg(cons, 2));
1097 ao_scheme_do_list_to_vector(struct ao_scheme_cons *cons)
1099 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3evector, cons, 1, 1))
1100 return AO_SCHEME_NIL;
1101 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3evector, cons, 0, AO_SCHEME_CONS, 0))
1102 return AO_SCHEME_NIL;
1103 return ao_scheme_vector_poly(ao_scheme_list_to_vector(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
1107 ao_scheme_do_vector_to_list(struct ao_scheme_cons *cons)
1109 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1))
1110 return AO_SCHEME_NIL;
1111 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1112 return AO_SCHEME_NIL;
1113 return ao_scheme_cons_poly(ao_scheme_vector_to_list(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))));
1117 ao_scheme_do_vector_length(struct ao_scheme_cons *cons)
1119 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1))
1120 return AO_SCHEME_NIL;
1121 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1122 return AO_SCHEME_NIL;
1123 return ao_scheme_integer_poly(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))->length);
1127 ao_scheme_do_vectorp(struct ao_scheme_cons *cons)
1129 return ao_scheme_do_typep(AO_SCHEME_VECTOR, cons);
1132 #endif /* AO_SCHEME_FEATURE_VECTOR */
1134 #define AO_SCHEME_BUILTIN_FUNCS
1135 #include "ao_scheme_builtin.h"