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, bool write)
89 struct ao_scheme_builtin *builtin = ao_scheme_poly_builtin(b);
91 printf("%s", ao_scheme_builtin_name(builtin->func));
95 ao_scheme_check_argc(ao_poly name, struct ao_scheme_cons *cons, int min, int max)
99 while (cons && argc <= max) {
101 cons = ao_scheme_cons_cdr(cons);
103 if (argc < min || argc > max)
104 return ao_scheme_error(AO_SCHEME_INVALID, "%s: invalid arg count", ao_scheme_poly_atom(name)->name);
105 return _ao_scheme_bool_true;
109 ao_scheme_opt_arg(struct ao_scheme_cons *cons, int argc, ao_poly def)
116 cons = ao_scheme_cons_cdr(cons);
122 ao_scheme_arg(struct ao_scheme_cons *cons, int argc)
124 return ao_scheme_opt_arg(cons, argc, AO_SCHEME_NIL);
128 ao_scheme_check_argt(ao_poly name, struct ao_scheme_cons *cons, int argc, int type, int nil_ok)
130 ao_poly car = ao_scheme_arg(cons, argc);
132 if ((!car && !nil_ok) || ao_scheme_poly_type(car) != type)
133 return ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, car);
134 return _ao_scheme_bool_true;
138 ao_scheme_arg_int(ao_poly name, struct ao_scheme_cons *cons, int argc)
140 ao_poly p = ao_scheme_arg(cons, argc);
142 int32_t i = ao_scheme_poly_integer(p, &fail);
145 (void) ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, p);
150 ao_scheme_opt_arg_int(ao_poly name, struct ao_scheme_cons *cons, int argc, int def)
152 ao_poly p = ao_scheme_opt_arg(cons, argc, ao_scheme_int_poly(def));
154 int32_t i = ao_scheme_poly_integer(p, &fail);
157 (void) ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, p);
162 ao_scheme_do_car(struct ao_scheme_cons *cons)
164 if (!ao_scheme_check_argc(_ao_scheme_atom_car, cons, 1, 1))
165 return AO_SCHEME_NIL;
166 if (!ao_scheme_check_argt(_ao_scheme_atom_car, cons, 0, AO_SCHEME_CONS, 0))
167 return AO_SCHEME_NIL;
168 return ao_scheme_poly_cons(cons->car)->car;
172 ao_scheme_do_cdr(struct ao_scheme_cons *cons)
174 if (!ao_scheme_check_argc(_ao_scheme_atom_cdr, cons, 1, 1))
175 return AO_SCHEME_NIL;
176 if (!ao_scheme_check_argt(_ao_scheme_atom_cdr, cons, 0, AO_SCHEME_CONS, 0))
177 return AO_SCHEME_NIL;
178 return ao_scheme_poly_cons(cons->car)->cdr;
182 ao_scheme_do_cons(struct ao_scheme_cons *cons)
185 if(!ao_scheme_check_argc(_ao_scheme_atom_cons, cons, 2, 2))
186 return AO_SCHEME_NIL;
187 car = ao_scheme_arg(cons, 0);
188 cdr = ao_scheme_arg(cons, 1);
189 return ao_scheme_cons(car, cdr);
193 ao_scheme_do_last(struct ao_scheme_cons *cons)
195 struct ao_scheme_cons *list;
196 if (!ao_scheme_check_argc(_ao_scheme_atom_last, cons, 1, 1))
197 return AO_SCHEME_NIL;
198 if (!ao_scheme_check_argt(_ao_scheme_atom_last, cons, 0, AO_SCHEME_CONS, 1))
199 return AO_SCHEME_NIL;
200 for (list = ao_scheme_poly_cons(ao_scheme_arg(cons, 0));
202 list = ao_scheme_cons_cdr(list))
207 return AO_SCHEME_NIL;
211 ao_scheme_do_length(struct ao_scheme_cons *cons)
213 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
214 return AO_SCHEME_NIL;
215 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
216 return AO_SCHEME_NIL;
217 return ao_scheme_int_poly(ao_scheme_cons_length(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
221 ao_scheme_do_list_copy(struct ao_scheme_cons *cons)
223 struct ao_scheme_cons *new;
225 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
226 return AO_SCHEME_NIL;
227 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
228 return AO_SCHEME_NIL;
229 new = ao_scheme_cons_copy(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
230 return ao_scheme_cons_poly(new);
234 ao_scheme_do_quote(struct ao_scheme_cons *cons)
236 if (!ao_scheme_check_argc(_ao_scheme_atom_quote, cons, 1, 1))
237 return AO_SCHEME_NIL;
238 return ao_scheme_arg(cons, 0);
242 ao_scheme_do_set(struct ao_scheme_cons *cons)
244 if (!ao_scheme_check_argc(_ao_scheme_atom_set, cons, 2, 2))
245 return AO_SCHEME_NIL;
246 if (!ao_scheme_check_argt(_ao_scheme_atom_set, cons, 0, AO_SCHEME_ATOM, 0))
247 return AO_SCHEME_NIL;
249 return ao_scheme_atom_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
253 ao_scheme_do_def(struct ao_scheme_cons *cons)
255 if (!ao_scheme_check_argc(_ao_scheme_atom_def, cons, 2, 2))
256 return AO_SCHEME_NIL;
257 if (!ao_scheme_check_argt(_ao_scheme_atom_def, cons, 0, AO_SCHEME_ATOM, 0))
258 return AO_SCHEME_NIL;
260 return ao_scheme_atom_def(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
264 ao_scheme_do_setq(struct ao_scheme_cons *cons)
267 if (!ao_scheme_check_argc(_ao_scheme_atom_set21, cons, 2, 2))
268 return AO_SCHEME_NIL;
270 if (ao_scheme_poly_type(name) != AO_SCHEME_ATOM)
271 return ao_scheme_error(AO_SCHEME_INVALID, "set! of non-atom %v", name);
272 if (!ao_scheme_atom_ref(name, NULL))
273 return ao_scheme_error(AO_SCHEME_INVALID, "atom %v not defined", name);
274 return ao_scheme_cons(_ao_scheme_atom_set,
275 ao_scheme_cons(ao_scheme_cons(_ao_scheme_atom_quote,
276 ao_scheme_cons(name, AO_SCHEME_NIL)),
281 ao_scheme_do_cond(struct ao_scheme_cons *cons)
283 ao_scheme_set_cond(cons);
284 return AO_SCHEME_NIL;
288 ao_scheme_do_begin(struct ao_scheme_cons *cons)
290 ao_scheme_stack->state = eval_begin;
291 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
292 return AO_SCHEME_NIL;
296 ao_scheme_do_while(struct ao_scheme_cons *cons)
298 ao_scheme_stack->state = eval_while;
299 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
300 return AO_SCHEME_NIL;
304 ao_scheme_do_write(struct ao_scheme_cons *cons)
306 ao_poly val = AO_SCHEME_NIL;
309 ao_scheme_poly_write(val, true);
310 cons = ao_scheme_cons_cdr(cons);
314 return _ao_scheme_bool_true;
318 ao_scheme_do_display(struct ao_scheme_cons *cons)
320 ao_poly val = AO_SCHEME_NIL;
323 ao_scheme_poly_write(val, false);
324 cons = ao_scheme_cons_cdr(cons);
326 return _ao_scheme_bool_true;
330 ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
332 struct ao_scheme_cons *cons;
333 ao_poly ret = AO_SCHEME_NIL;
335 for (cons = orig_cons; cons; cons = ao_scheme_cons_cdr(cons)) {
336 ao_poly car = cons->car;
337 uint8_t rt = ao_scheme_poly_type(ret);
338 uint8_t ct = ao_scheme_poly_type(car);
340 if (cons == orig_cons) {
342 ao_scheme_cons_stash(cons);
343 if (cons->cdr == AO_SCHEME_NIL) {
346 if (ao_scheme_integer_typep(ct))
347 ret = ao_scheme_integer_poly(-ao_scheme_poly_integer(ret, NULL));
348 #ifdef AO_SCHEME_FEATURE_FLOAT
349 else if (ct == AO_SCHEME_FLOAT)
350 ret = ao_scheme_float_get(-ao_scheme_poly_number(ret));
354 if (ao_scheme_poly_integer(ret, NULL) == 1) {
356 #ifdef AO_SCHEME_FEATURE_FLOAT
357 if (ao_scheme_number_typep(ct)) {
358 float v = ao_scheme_poly_number(ret);
359 ret = ao_scheme_float_get(1/v);
362 ret = ao_scheme_integer_poly(0);
370 cons = ao_scheme_cons_fetch();
371 } else if (ao_scheme_integer_typep(rt) && ao_scheme_integer_typep(ct)) {
372 int32_t r = ao_scheme_poly_integer(ret, NULL);
373 int32_t c = ao_scheme_poly_integer(car, NULL);
374 #ifdef AO_SCHEME_FEATURE_FLOAT
382 #ifdef AO_SCHEME_FEATURE_FLOAT
383 if (r < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < r)
392 #ifdef AO_SCHEME_FEATURE_FLOAT
393 t = (int64_t) r * (int64_t) c;
394 if (t < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < t)
402 #ifdef AO_SCHEME_FEATURE_FLOAT
403 if (c != 0 && (r % c) == 0)
411 case builtin_quotient:
413 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "quotient by zero");
416 case builtin_floor_quotient:
418 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "floor-quotient by zero");
419 if (r % c != 0 && (c < 0) != (r < 0))
424 case builtin_remainder:
426 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "remainder by zero");
431 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "modulo by zero");
433 if ((r < 0) != (c < 0))
439 ao_scheme_cons_stash(cons);
440 ret = ao_scheme_integer_poly(r);
441 cons = ao_scheme_cons_fetch();
442 #ifdef AO_SCHEME_FEATURE_FLOAT
443 } else if (ao_scheme_number_typep(rt) && ao_scheme_number_typep(ct)) {
446 r = ao_scheme_poly_number(ret);
447 c = ao_scheme_poly_number(car);
461 case builtin_quotient:
462 case builtin_floor_quotient:
463 case builtin_remainder:
465 return ao_scheme_error(AO_SCHEME_INVALID, "non-integer value in integer divide");
469 ao_scheme_cons_stash(cons);
470 ret = ao_scheme_float_get(r);
471 cons = ao_scheme_cons_fetch();
474 else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus) {
475 ao_scheme_cons_stash(cons);
476 ret = ao_scheme_string_poly(ao_scheme_string_cat(ao_scheme_poly_string(ret),
477 ao_scheme_poly_string(car)));
478 cons = ao_scheme_cons_fetch();
483 return ao_scheme_error(AO_SCHEME_INVALID, "invalid args");
489 ao_scheme_do_plus(struct ao_scheme_cons *cons)
491 return ao_scheme_math(cons, builtin_plus);
495 ao_scheme_do_minus(struct ao_scheme_cons *cons)
497 return ao_scheme_math(cons, builtin_minus);
501 ao_scheme_do_times(struct ao_scheme_cons *cons)
503 return ao_scheme_math(cons, builtin_times);
507 ao_scheme_do_divide(struct ao_scheme_cons *cons)
509 return ao_scheme_math(cons, builtin_divide);
513 ao_scheme_do_quotient(struct ao_scheme_cons *cons)
515 return ao_scheme_math(cons, builtin_quotient);
519 ao_scheme_do_floor_quotient(struct ao_scheme_cons *cons)
521 return ao_scheme_math(cons, builtin_floor_quotient);
525 ao_scheme_do_modulo(struct ao_scheme_cons *cons)
527 return ao_scheme_math(cons, builtin_modulo);
531 ao_scheme_do_remainder(struct ao_scheme_cons *cons)
533 return ao_scheme_math(cons, builtin_remainder);
537 ao_scheme_compare(struct ao_scheme_cons *cons, enum ao_scheme_builtin_id op)
542 return _ao_scheme_bool_true;
545 for (cons = ao_scheme_cons_cdr(cons); cons; cons = ao_scheme_cons_cdr(cons)) {
546 ao_poly right = cons->car;
548 if (op == builtin_equal && left == right) {
551 uint8_t lt = ao_scheme_poly_type(left);
552 uint8_t rt = ao_scheme_poly_type(right);
553 if (ao_scheme_integer_typep(lt) && ao_scheme_integer_typep(rt)) {
554 int32_t l = ao_scheme_poly_integer(left, NULL);
555 int32_t r = ao_scheme_poly_integer(right, NULL);
560 return _ao_scheme_bool_false;
562 case builtin_greater:
564 return _ao_scheme_bool_false;
566 case builtin_less_equal:
568 return _ao_scheme_bool_false;
570 case builtin_greater_equal:
572 return _ao_scheme_bool_false;
576 return _ao_scheme_bool_false;
580 #ifdef AO_SCHEME_FEATURE_FLOAT
581 } else if (ao_scheme_number_typep(lt) && ao_scheme_number_typep(rt)) {
584 l = ao_scheme_poly_number(left);
585 r = ao_scheme_poly_number(right);
590 return _ao_scheme_bool_false;
592 case builtin_greater:
594 return _ao_scheme_bool_false;
596 case builtin_less_equal:
598 return _ao_scheme_bool_false;
600 case builtin_greater_equal:
602 return _ao_scheme_bool_false;
606 return _ao_scheme_bool_false;
610 #endif /* AO_SCHEME_FEATURE_FLOAT */
611 } else if (lt == AO_SCHEME_STRING && rt == AO_SCHEME_STRING) {
612 int c = strcmp(ao_scheme_poly_string(left)->val,
613 ao_scheme_poly_string(right)->val);
617 return _ao_scheme_bool_false;
619 case builtin_greater:
621 return _ao_scheme_bool_false;
623 case builtin_less_equal:
625 return _ao_scheme_bool_false;
627 case builtin_greater_equal:
629 return _ao_scheme_bool_false;
633 return _ao_scheme_bool_false;
639 return _ao_scheme_bool_false;
643 return _ao_scheme_bool_true;
647 ao_scheme_do_equal(struct ao_scheme_cons *cons)
649 return ao_scheme_compare(cons, builtin_equal);
653 ao_scheme_do_less(struct ao_scheme_cons *cons)
655 return ao_scheme_compare(cons, builtin_less);
659 ao_scheme_do_greater(struct ao_scheme_cons *cons)
661 return ao_scheme_compare(cons, builtin_greater);
665 ao_scheme_do_less_equal(struct ao_scheme_cons *cons)
667 return ao_scheme_compare(cons, builtin_less_equal);
671 ao_scheme_do_greater_equal(struct ao_scheme_cons *cons)
673 return ao_scheme_compare(cons, builtin_greater_equal);
677 ao_scheme_do_list_to_string(struct ao_scheme_cons *cons)
679 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3estring, cons, 1, 1))
680 return AO_SCHEME_NIL;
681 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3estring, cons, 0, AO_SCHEME_CONS, 1))
682 return AO_SCHEME_NIL;
683 return ao_scheme_string_pack(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
687 ao_scheme_do_string_to_list(struct ao_scheme_cons *cons)
689 if (!ao_scheme_check_argc(_ao_scheme_atom_string2d3elist, cons, 1, 1))
690 return AO_SCHEME_NIL;
691 if (!ao_scheme_check_argt(_ao_scheme_atom_string2d3elist, cons, 0, AO_SCHEME_STRING, 0))
692 return AO_SCHEME_NIL;
693 return ao_scheme_string_unpack(ao_scheme_poly_string(ao_scheme_arg(cons, 0)));
697 ao_scheme_do_string_ref(struct ao_scheme_cons *cons)
701 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dref, cons, 2, 2))
702 return AO_SCHEME_NIL;
703 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dref, cons, 0, AO_SCHEME_STRING, 0))
704 return AO_SCHEME_NIL;
705 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dref, cons, 1);
706 if (ao_scheme_exception)
707 return AO_SCHEME_NIL;
708 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val;
709 while (*string && ref) {
714 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
715 _ao_scheme_atom_string2dref,
716 ao_scheme_arg(cons, 0),
717 ao_scheme_arg(cons, 1));
718 return ao_scheme_int_poly(*string);
722 ao_scheme_do_string_length(struct ao_scheme_cons *cons)
724 struct ao_scheme_string *string;
726 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dlength, cons, 1, 1))
727 return AO_SCHEME_NIL;
728 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dlength, cons, 0, AO_SCHEME_STRING, 0))
729 return AO_SCHEME_NIL;
730 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
731 return ao_scheme_integer_poly(strlen(string->val));
735 ao_scheme_do_string_copy(struct ao_scheme_cons *cons)
737 struct ao_scheme_string *string;
739 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dcopy, cons, 1, 1))
740 return AO_SCHEME_NIL;
741 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dcopy, cons, 0, AO_SCHEME_STRING, 0))
742 return AO_SCHEME_NIL;
743 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
744 return ao_scheme_string_poly(ao_scheme_string_copy(string));
748 ao_scheme_do_string_set(struct ao_scheme_cons *cons)
754 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dset21, cons, 3, 3))
755 return AO_SCHEME_NIL;
756 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dset21, cons, 0, AO_SCHEME_STRING, 0))
757 return AO_SCHEME_NIL;
758 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val;
759 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 1);
760 if (ao_scheme_exception)
761 return AO_SCHEME_NIL;
762 val = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 2);
763 if (ao_scheme_exception)
764 return AO_SCHEME_NIL;
767 while (*string && ref) {
774 return ao_scheme_int_poly(*string);
776 return ao_scheme_error(AO_SCHEME_INVALID, "%v: %v[%v] = %v invalid",
777 _ao_scheme_atom_string2dset21,
778 ao_scheme_arg(cons, 0),
779 ao_scheme_arg(cons, 1),
780 ao_scheme_arg(cons, 2));
784 ao_scheme_do_make_string(struct ao_scheme_cons *cons)
789 if (!ao_scheme_check_argc(_ao_scheme_atom_make2dstring, cons, 1, 2))
790 return AO_SCHEME_NIL;
791 len = ao_scheme_arg_int(_ao_scheme_atom_make2dstring, cons, 0);
792 if (ao_scheme_exception)
793 return AO_SCHEME_NIL;
794 fill = ao_scheme_opt_arg_int(_ao_scheme_atom_make2dstring, cons, 1, ' ');
795 if (ao_scheme_exception)
796 return AO_SCHEME_NIL;
797 return ao_scheme_string_poly(ao_scheme_make_string(len, fill));
801 ao_scheme_do_flush_output(struct ao_scheme_cons *cons)
803 if (!ao_scheme_check_argc(_ao_scheme_atom_flush2doutput, cons, 0, 0))
804 return AO_SCHEME_NIL;
805 ao_scheme_os_flush();
806 return _ao_scheme_bool_true;
810 ao_scheme_do_led(struct ao_scheme_cons *cons)
813 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
814 return AO_SCHEME_NIL;
815 led = ao_scheme_arg_int(_ao_scheme_atom_led, cons, 0);
816 if (ao_scheme_exception)
817 return AO_SCHEME_NIL;
818 led = ao_scheme_arg(cons, 0);
819 ao_scheme_os_led(ao_scheme_poly_int(led));
824 ao_scheme_do_delay(struct ao_scheme_cons *cons)
828 if (!ao_scheme_check_argc(_ao_scheme_atom_delay, cons, 1, 1))
829 return AO_SCHEME_NIL;
830 delay = ao_scheme_arg_int(_ao_scheme_atom_delay, cons, 0);
831 if (ao_scheme_exception)
832 return AO_SCHEME_NIL;
833 ao_scheme_os_delay(delay);
838 ao_scheme_do_eval(struct ao_scheme_cons *cons)
840 if (!ao_scheme_check_argc(_ao_scheme_atom_eval, cons, 1, 1))
841 return AO_SCHEME_NIL;
842 ao_scheme_stack->state = eval_sexpr;
847 ao_scheme_do_apply(struct ao_scheme_cons *cons)
849 if (!ao_scheme_check_argc(_ao_scheme_atom_apply, cons, 2, INT_MAX))
850 return AO_SCHEME_NIL;
851 ao_scheme_stack->state = eval_apply;
852 return ao_scheme_cons_poly(cons);
856 ao_scheme_do_read(struct ao_scheme_cons *cons)
858 if (!ao_scheme_check_argc(_ao_scheme_atom_read, cons, 0, 0))
859 return AO_SCHEME_NIL;
860 return ao_scheme_read();
864 ao_scheme_do_collect(struct ao_scheme_cons *cons)
868 free = ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
869 return ao_scheme_integer_poly(free);
873 ao_scheme_do_nullp(struct ao_scheme_cons *cons)
875 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
876 return AO_SCHEME_NIL;
877 if (ao_scheme_arg(cons, 0) == AO_SCHEME_NIL)
878 return _ao_scheme_bool_true;
880 return _ao_scheme_bool_false;
884 ao_scheme_do_not(struct ao_scheme_cons *cons)
886 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
887 return AO_SCHEME_NIL;
888 if (ao_scheme_arg(cons, 0) == _ao_scheme_bool_false)
889 return _ao_scheme_bool_true;
891 return _ao_scheme_bool_false;
895 ao_scheme_do_typep(int type, struct ao_scheme_cons *cons)
897 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
898 return AO_SCHEME_NIL;
899 if (ao_scheme_poly_type(ao_scheme_arg(cons, 0)) == type)
900 return _ao_scheme_bool_true;
901 return _ao_scheme_bool_false;
905 ao_scheme_do_pairp(struct ao_scheme_cons *cons)
908 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
909 return AO_SCHEME_NIL;
910 v = ao_scheme_arg(cons, 0);
911 if (ao_scheme_is_pair(v))
912 return _ao_scheme_bool_true;
913 return _ao_scheme_bool_false;
917 ao_scheme_do_integerp(struct ao_scheme_cons *cons)
919 #ifdef AO_SCHEME_FEATURE_BIGINT
920 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
921 return AO_SCHEME_NIL;
922 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
924 case AO_SCHEME_BIGINT:
925 return _ao_scheme_bool_true;
927 return _ao_scheme_bool_false;
930 return ao_scheme_do_typep(AO_SCHEME_INT, cons);
935 ao_scheme_do_numberp(struct ao_scheme_cons *cons)
937 #if defined(AO_SCHEME_FEATURE_BIGINT) || defined(AO_SCHEME_FEATURE_FLOAT)
938 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
939 return AO_SCHEME_NIL;
940 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
942 #ifdef AO_SCHEME_FEATURE_BIGINT
943 case AO_SCHEME_BIGINT:
945 #ifdef AO_SCHEME_FEATURE_FLOAT
946 case AO_SCHEME_FLOAT:
948 return _ao_scheme_bool_true;
950 return _ao_scheme_bool_false;
953 return ao_scheme_do_integerp(cons);
958 ao_scheme_do_stringp(struct ao_scheme_cons *cons)
960 return ao_scheme_do_typep(AO_SCHEME_STRING, cons);
964 ao_scheme_do_symbolp(struct ao_scheme_cons *cons)
966 return ao_scheme_do_typep(AO_SCHEME_ATOM, cons);
970 ao_scheme_do_booleanp(struct ao_scheme_cons *cons)
972 return ao_scheme_do_typep(AO_SCHEME_BOOL, cons);
976 ao_scheme_do_procedurep(struct ao_scheme_cons *cons)
978 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
979 return AO_SCHEME_NIL;
980 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
981 case AO_SCHEME_BUILTIN:
982 case AO_SCHEME_LAMBDA:
983 return _ao_scheme_bool_true;
985 return _ao_scheme_bool_false;
989 /* This one is special -- a list is either nil or
990 * a 'proper' list with only cons cells
993 ao_scheme_do_listp(struct ao_scheme_cons *cons)
996 if (!ao_scheme_check_argc(_ao_scheme_atom_list3f, cons, 1, 1))
997 return AO_SCHEME_NIL;
998 v = ao_scheme_arg(cons, 0);
1000 if (v == AO_SCHEME_NIL)
1001 return _ao_scheme_bool_true;
1002 if (!ao_scheme_is_cons(v))
1003 return _ao_scheme_bool_false;
1004 v = ao_scheme_poly_cons(v)->cdr;
1009 ao_scheme_do_set_car(struct ao_scheme_cons *cons)
1011 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
1012 return AO_SCHEME_NIL;
1013 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
1014 return AO_SCHEME_NIL;
1015 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->car = ao_scheme_arg(cons, 1);
1019 ao_scheme_do_set_cdr(struct ao_scheme_cons *cons)
1021 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
1022 return AO_SCHEME_NIL;
1023 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
1024 return AO_SCHEME_NIL;
1025 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->cdr = ao_scheme_arg(cons, 1);
1029 ao_scheme_do_symbol_to_string(struct ao_scheme_cons *cons)
1031 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1032 return AO_SCHEME_NIL;
1033 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_ATOM, 0))
1034 return AO_SCHEME_NIL;
1035 return ao_scheme_string_poly(ao_scheme_atom_to_string(ao_scheme_poly_atom(ao_scheme_arg(cons, 0))));
1039 ao_scheme_do_string_to_symbol(struct ao_scheme_cons *cons)
1041 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1042 return AO_SCHEME_NIL;
1043 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_STRING, 0))
1044 return AO_SCHEME_NIL;
1046 return ao_scheme_atom_poly(ao_scheme_string_to_atom(ao_scheme_poly_string(ao_scheme_arg(cons, 0))));;
1050 ao_scheme_do_read_char(struct ao_scheme_cons *cons)
1053 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1054 return AO_SCHEME_NIL;
1056 return ao_scheme_int_poly(c);
1060 ao_scheme_do_write_char(struct ao_scheme_cons *cons)
1062 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1063 return AO_SCHEME_NIL;
1064 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_INT, 0))
1065 return AO_SCHEME_NIL;
1066 putchar(ao_scheme_poly_integer(ao_scheme_arg(cons, 0), NULL));
1067 return _ao_scheme_bool_true;
1071 ao_scheme_do_exit(struct ao_scheme_cons *cons)
1073 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1074 return AO_SCHEME_NIL;
1075 ao_scheme_exception |= AO_SCHEME_EXIT;
1076 return _ao_scheme_bool_true;
1080 ao_scheme_do_current_jiffy(struct ao_scheme_cons *cons)
1084 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1085 return AO_SCHEME_NIL;
1086 jiffy = ao_scheme_os_jiffy();
1087 return (ao_scheme_int_poly(jiffy));
1091 ao_scheme_do_current_second(struct ao_scheme_cons *cons)
1095 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1096 return AO_SCHEME_NIL;
1097 second = ao_scheme_os_jiffy() / AO_SCHEME_JIFFIES_PER_SECOND;
1098 return (ao_scheme_int_poly(second));
1102 ao_scheme_do_jiffies_per_second(struct ao_scheme_cons *cons)
1104 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1105 return AO_SCHEME_NIL;
1106 return (ao_scheme_int_poly(AO_SCHEME_JIFFIES_PER_SECOND));
1109 #ifdef AO_SCHEME_FEATURE_VECTOR
1112 ao_scheme_do_vector(struct ao_scheme_cons *cons)
1114 return ao_scheme_vector_poly(ao_scheme_list_to_vector(cons));
1118 ao_scheme_do_make_vector(struct ao_scheme_cons *cons)
1122 if (!ao_scheme_check_argc(_ao_scheme_atom_make2dvector, cons, 2, 2))
1123 return AO_SCHEME_NIL;
1124 k = ao_scheme_arg_int(_ao_scheme_atom_make2dvector, cons, 0);
1125 if (ao_scheme_exception)
1126 return AO_SCHEME_NIL;
1127 return ao_scheme_vector_poly(ao_scheme_vector_alloc(k, ao_scheme_arg(cons, 1)));
1131 ao_scheme_do_vector_ref(struct ao_scheme_cons *cons)
1133 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dref, cons, 2, 2))
1134 return AO_SCHEME_NIL;
1135 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dref, cons, 0, AO_SCHEME_VECTOR, 0))
1136 return AO_SCHEME_NIL;
1137 return ao_scheme_vector_get(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
1141 ao_scheme_do_vector_set(struct ao_scheme_cons *cons)
1143 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dset21, cons, 3, 3))
1144 return AO_SCHEME_NIL;
1145 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dset21, cons, 0, AO_SCHEME_VECTOR, 0))
1146 return AO_SCHEME_NIL;
1147 return ao_scheme_vector_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1), ao_scheme_arg(cons, 2));
1151 ao_scheme_do_list_to_vector(struct ao_scheme_cons *cons)
1153 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3evector, cons, 1, 1))
1154 return AO_SCHEME_NIL;
1155 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3evector, cons, 0, AO_SCHEME_CONS, 0))
1156 return AO_SCHEME_NIL;
1157 return ao_scheme_vector_poly(ao_scheme_list_to_vector(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
1161 ao_scheme_do_vector_to_list(struct ao_scheme_cons *cons)
1165 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 3))
1166 return AO_SCHEME_NIL;
1167 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1168 return AO_SCHEME_NIL;
1169 start = ao_scheme_opt_arg_int(_ao_scheme_atom_vector2d3elist, cons, 1, ao_scheme_int_poly(0));
1170 if (ao_scheme_exception)
1171 return AO_SCHEME_NIL;
1172 end = ao_scheme_opt_arg_int(_ao_scheme_atom_vector2d3elist, cons, 2, ao_scheme_int_poly(-1));
1173 if (ao_scheme_exception)
1174 return AO_SCHEME_NIL;
1175 return ao_scheme_cons_poly(ao_scheme_vector_to_list(ao_scheme_poly_vector(ao_scheme_arg(cons, 0)),
1181 ao_scheme_do_vector_length(struct ao_scheme_cons *cons)
1183 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1))
1184 return AO_SCHEME_NIL;
1185 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1186 return AO_SCHEME_NIL;
1187 return ao_scheme_integer_poly(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))->length);
1191 ao_scheme_do_vectorp(struct ao_scheme_cons *cons)
1193 return ao_scheme_do_typep(AO_SCHEME_VECTOR, cons);
1196 #endif /* AO_SCHEME_FEATURE_VECTOR */
1198 #define AO_SCHEME_BUILTIN_FUNCS
1199 #include "ao_scheme_builtin.h"