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_arg(struct ao_scheme_cons *cons, int argc)
112 return AO_SCHEME_NIL;
115 return AO_SCHEME_NIL;
116 cons = ao_scheme_cons_cdr(cons);
122 ao_scheme_check_argt(ao_poly name, struct ao_scheme_cons *cons, int argc, int type, int nil_ok)
124 ao_poly car = ao_scheme_arg(cons, argc);
126 if ((!car && !nil_ok) || ao_scheme_poly_type(car) != type)
127 return ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, car);
128 return _ao_scheme_bool_true;
132 ao_scheme_arg_int(ao_poly name, struct ao_scheme_cons *cons, int argc)
134 ao_poly p = ao_scheme_arg(cons, argc);
136 int32_t i = ao_scheme_poly_integer(p, &fail);
139 (void) ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, p);
144 ao_scheme_do_car(struct ao_scheme_cons *cons)
146 if (!ao_scheme_check_argc(_ao_scheme_atom_car, cons, 1, 1))
147 return AO_SCHEME_NIL;
148 if (!ao_scheme_check_argt(_ao_scheme_atom_car, cons, 0, AO_SCHEME_CONS, 0))
149 return AO_SCHEME_NIL;
150 return ao_scheme_poly_cons(cons->car)->car;
154 ao_scheme_do_cdr(struct ao_scheme_cons *cons)
156 if (!ao_scheme_check_argc(_ao_scheme_atom_cdr, cons, 1, 1))
157 return AO_SCHEME_NIL;
158 if (!ao_scheme_check_argt(_ao_scheme_atom_cdr, cons, 0, AO_SCHEME_CONS, 0))
159 return AO_SCHEME_NIL;
160 return ao_scheme_poly_cons(cons->car)->cdr;
164 ao_scheme_do_cons(struct ao_scheme_cons *cons)
167 if(!ao_scheme_check_argc(_ao_scheme_atom_cons, cons, 2, 2))
168 return AO_SCHEME_NIL;
169 car = ao_scheme_arg(cons, 0);
170 cdr = ao_scheme_arg(cons, 1);
171 return ao_scheme_cons(car, cdr);
175 ao_scheme_do_last(struct ao_scheme_cons *cons)
177 struct ao_scheme_cons *list;
178 if (!ao_scheme_check_argc(_ao_scheme_atom_last, cons, 1, 1))
179 return AO_SCHEME_NIL;
180 if (!ao_scheme_check_argt(_ao_scheme_atom_last, cons, 0, AO_SCHEME_CONS, 1))
181 return AO_SCHEME_NIL;
182 for (list = ao_scheme_poly_cons(ao_scheme_arg(cons, 0));
184 list = ao_scheme_cons_cdr(list))
189 return AO_SCHEME_NIL;
193 ao_scheme_do_length(struct ao_scheme_cons *cons)
195 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
196 return AO_SCHEME_NIL;
197 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
198 return AO_SCHEME_NIL;
199 return ao_scheme_int_poly(ao_scheme_cons_length(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
203 ao_scheme_do_list_copy(struct ao_scheme_cons *cons)
205 struct ao_scheme_cons *new;
207 if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1))
208 return AO_SCHEME_NIL;
209 if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1))
210 return AO_SCHEME_NIL;
211 new = ao_scheme_cons_copy(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
212 return ao_scheme_cons_poly(new);
216 ao_scheme_do_quote(struct ao_scheme_cons *cons)
218 if (!ao_scheme_check_argc(_ao_scheme_atom_quote, cons, 1, 1))
219 return AO_SCHEME_NIL;
220 return ao_scheme_arg(cons, 0);
224 ao_scheme_do_set(struct ao_scheme_cons *cons)
226 if (!ao_scheme_check_argc(_ao_scheme_atom_set, cons, 2, 2))
227 return AO_SCHEME_NIL;
228 if (!ao_scheme_check_argt(_ao_scheme_atom_set, cons, 0, AO_SCHEME_ATOM, 0))
229 return AO_SCHEME_NIL;
231 return ao_scheme_atom_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
235 ao_scheme_do_def(struct ao_scheme_cons *cons)
237 if (!ao_scheme_check_argc(_ao_scheme_atom_def, cons, 2, 2))
238 return AO_SCHEME_NIL;
239 if (!ao_scheme_check_argt(_ao_scheme_atom_def, cons, 0, AO_SCHEME_ATOM, 0))
240 return AO_SCHEME_NIL;
242 return ao_scheme_atom_def(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
246 ao_scheme_do_setq(struct ao_scheme_cons *cons)
249 if (!ao_scheme_check_argc(_ao_scheme_atom_set21, cons, 2, 2))
250 return AO_SCHEME_NIL;
252 if (ao_scheme_poly_type(name) != AO_SCHEME_ATOM)
253 return ao_scheme_error(AO_SCHEME_INVALID, "set! of non-atom %v", name);
254 if (!ao_scheme_atom_ref(name, NULL))
255 return ao_scheme_error(AO_SCHEME_INVALID, "atom %v not defined", name);
256 return ao_scheme_cons(_ao_scheme_atom_set,
257 ao_scheme_cons(ao_scheme_cons(_ao_scheme_atom_quote,
258 ao_scheme_cons(name, AO_SCHEME_NIL)),
263 ao_scheme_do_cond(struct ao_scheme_cons *cons)
265 ao_scheme_set_cond(cons);
266 return AO_SCHEME_NIL;
270 ao_scheme_do_begin(struct ao_scheme_cons *cons)
272 ao_scheme_stack->state = eval_begin;
273 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
274 return AO_SCHEME_NIL;
278 ao_scheme_do_while(struct ao_scheme_cons *cons)
280 ao_scheme_stack->state = eval_while;
281 ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons);
282 return AO_SCHEME_NIL;
286 ao_scheme_do_write(struct ao_scheme_cons *cons)
288 ao_poly val = AO_SCHEME_NIL;
291 ao_scheme_poly_write(val, true);
292 cons = ao_scheme_cons_cdr(cons);
296 return _ao_scheme_bool_true;
300 ao_scheme_do_display(struct ao_scheme_cons *cons)
302 ao_poly val = AO_SCHEME_NIL;
305 ao_scheme_poly_write(val, false);
306 cons = ao_scheme_cons_cdr(cons);
308 return _ao_scheme_bool_true;
312 ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op)
314 struct ao_scheme_cons *cons;
315 ao_poly ret = AO_SCHEME_NIL;
317 for (cons = orig_cons; cons; cons = ao_scheme_cons_cdr(cons)) {
318 ao_poly car = cons->car;
319 uint8_t rt = ao_scheme_poly_type(ret);
320 uint8_t ct = ao_scheme_poly_type(car);
322 if (cons == orig_cons) {
324 ao_scheme_cons_stash(cons);
325 if (cons->cdr == AO_SCHEME_NIL) {
328 if (ao_scheme_integer_typep(ct))
329 ret = ao_scheme_integer_poly(-ao_scheme_poly_integer(ret, NULL));
330 #ifdef AO_SCHEME_FEATURE_FLOAT
331 else if (ct == AO_SCHEME_FLOAT)
332 ret = ao_scheme_float_get(-ao_scheme_poly_number(ret));
336 if (ao_scheme_poly_integer(ret, NULL) == 1) {
338 #ifdef AO_SCHEME_FEATURE_FLOAT
339 if (ao_scheme_number_typep(ct)) {
340 float v = ao_scheme_poly_number(ret);
341 ret = ao_scheme_float_get(1/v);
344 ret = ao_scheme_integer_poly(0);
352 cons = ao_scheme_cons_fetch();
353 } else if (ao_scheme_integer_typep(rt) && ao_scheme_integer_typep(ct)) {
354 int32_t r = ao_scheme_poly_integer(ret, NULL);
355 int32_t c = ao_scheme_poly_integer(car, NULL);
356 #ifdef AO_SCHEME_FEATURE_FLOAT
364 #ifdef AO_SCHEME_FEATURE_FLOAT
365 if (r < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < r)
374 #ifdef AO_SCHEME_FEATURE_FLOAT
375 t = (int64_t) r * (int64_t) c;
376 if (t < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < t)
384 #ifdef AO_SCHEME_FEATURE_FLOAT
385 if (c != 0 && (r % c) == 0)
393 case builtin_quotient:
395 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "quotient by zero");
398 case builtin_floor_quotient:
400 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "floor-quotient by zero");
401 if (r % c != 0 && (c < 0) != (r < 0))
406 case builtin_remainder:
408 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "remainder by zero");
413 return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "modulo by zero");
415 if ((r < 0) != (c < 0))
421 ao_scheme_cons_stash(cons);
422 ret = ao_scheme_integer_poly(r);
423 cons = ao_scheme_cons_fetch();
424 #ifdef AO_SCHEME_FEATURE_FLOAT
425 } else if (ao_scheme_number_typep(rt) && ao_scheme_number_typep(ct)) {
428 r = ao_scheme_poly_number(ret);
429 c = ao_scheme_poly_number(car);
443 case builtin_quotient:
444 case builtin_floor_quotient:
445 case builtin_remainder:
447 return ao_scheme_error(AO_SCHEME_INVALID, "non-integer value in integer divide");
451 ao_scheme_cons_stash(cons);
452 ret = ao_scheme_float_get(r);
453 cons = ao_scheme_cons_fetch();
456 else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus) {
457 ao_scheme_cons_stash(cons);
458 ret = ao_scheme_string_poly(ao_scheme_string_cat(ao_scheme_poly_string(ret),
459 ao_scheme_poly_string(car)));
460 cons = ao_scheme_cons_fetch();
465 return ao_scheme_error(AO_SCHEME_INVALID, "invalid args");
471 ao_scheme_do_plus(struct ao_scheme_cons *cons)
473 return ao_scheme_math(cons, builtin_plus);
477 ao_scheme_do_minus(struct ao_scheme_cons *cons)
479 return ao_scheme_math(cons, builtin_minus);
483 ao_scheme_do_times(struct ao_scheme_cons *cons)
485 return ao_scheme_math(cons, builtin_times);
489 ao_scheme_do_divide(struct ao_scheme_cons *cons)
491 return ao_scheme_math(cons, builtin_divide);
495 ao_scheme_do_quotient(struct ao_scheme_cons *cons)
497 return ao_scheme_math(cons, builtin_quotient);
501 ao_scheme_do_floor_quotient(struct ao_scheme_cons *cons)
503 return ao_scheme_math(cons, builtin_floor_quotient);
507 ao_scheme_do_modulo(struct ao_scheme_cons *cons)
509 return ao_scheme_math(cons, builtin_modulo);
513 ao_scheme_do_remainder(struct ao_scheme_cons *cons)
515 return ao_scheme_math(cons, builtin_remainder);
519 ao_scheme_compare(struct ao_scheme_cons *cons, enum ao_scheme_builtin_id op)
524 return _ao_scheme_bool_true;
527 for (cons = ao_scheme_cons_cdr(cons); cons; cons = ao_scheme_cons_cdr(cons)) {
528 ao_poly right = cons->car;
530 if (op == builtin_equal && left == right) {
533 uint8_t lt = ao_scheme_poly_type(left);
534 uint8_t rt = ao_scheme_poly_type(right);
535 if (ao_scheme_integer_typep(lt) && ao_scheme_integer_typep(rt)) {
536 int32_t l = ao_scheme_poly_integer(left, NULL);
537 int32_t r = ao_scheme_poly_integer(right, NULL);
542 return _ao_scheme_bool_false;
544 case builtin_greater:
546 return _ao_scheme_bool_false;
548 case builtin_less_equal:
550 return _ao_scheme_bool_false;
552 case builtin_greater_equal:
554 return _ao_scheme_bool_false;
558 return _ao_scheme_bool_false;
562 #ifdef AO_SCHEME_FEATURE_FLOAT
563 } else if (ao_scheme_number_typep(lt) && ao_scheme_number_typep(rt)) {
566 l = ao_scheme_poly_number(left);
567 r = ao_scheme_poly_number(right);
572 return _ao_scheme_bool_false;
574 case builtin_greater:
576 return _ao_scheme_bool_false;
578 case builtin_less_equal:
580 return _ao_scheme_bool_false;
582 case builtin_greater_equal:
584 return _ao_scheme_bool_false;
588 return _ao_scheme_bool_false;
592 #endif /* AO_SCHEME_FEATURE_FLOAT */
593 } else if (lt == AO_SCHEME_STRING && rt == AO_SCHEME_STRING) {
594 int c = strcmp(ao_scheme_poly_string(left)->val,
595 ao_scheme_poly_string(right)->val);
599 return _ao_scheme_bool_false;
601 case builtin_greater:
603 return _ao_scheme_bool_false;
605 case builtin_less_equal:
607 return _ao_scheme_bool_false;
609 case builtin_greater_equal:
611 return _ao_scheme_bool_false;
615 return _ao_scheme_bool_false;
621 return _ao_scheme_bool_false;
625 return _ao_scheme_bool_true;
629 ao_scheme_do_equal(struct ao_scheme_cons *cons)
631 return ao_scheme_compare(cons, builtin_equal);
635 ao_scheme_do_less(struct ao_scheme_cons *cons)
637 return ao_scheme_compare(cons, builtin_less);
641 ao_scheme_do_greater(struct ao_scheme_cons *cons)
643 return ao_scheme_compare(cons, builtin_greater);
647 ao_scheme_do_less_equal(struct ao_scheme_cons *cons)
649 return ao_scheme_compare(cons, builtin_less_equal);
653 ao_scheme_do_greater_equal(struct ao_scheme_cons *cons)
655 return ao_scheme_compare(cons, builtin_greater_equal);
659 ao_scheme_do_list_to_string(struct ao_scheme_cons *cons)
661 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3estring, cons, 1, 1))
662 return AO_SCHEME_NIL;
663 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3estring, cons, 0, AO_SCHEME_CONS, 1))
664 return AO_SCHEME_NIL;
665 return ao_scheme_string_pack(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)));
669 ao_scheme_do_string_to_list(struct ao_scheme_cons *cons)
671 if (!ao_scheme_check_argc(_ao_scheme_atom_string2d3elist, cons, 1, 1))
672 return AO_SCHEME_NIL;
673 if (!ao_scheme_check_argt(_ao_scheme_atom_string2d3elist, cons, 0, AO_SCHEME_STRING, 0))
674 return AO_SCHEME_NIL;
675 return ao_scheme_string_unpack(ao_scheme_poly_string(ao_scheme_arg(cons, 0)));
679 ao_scheme_do_string_ref(struct ao_scheme_cons *cons)
683 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dref, cons, 2, 2))
684 return AO_SCHEME_NIL;
685 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dref, cons, 0, AO_SCHEME_STRING, 0))
686 return AO_SCHEME_NIL;
687 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dref, cons, 1);
688 if (ao_scheme_exception)
689 return AO_SCHEME_NIL;
690 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val;
691 while (*string && ref) {
696 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
697 _ao_scheme_atom_string2dref,
698 ao_scheme_arg(cons, 0),
699 ao_scheme_arg(cons, 1));
700 return ao_scheme_int_poly(*string);
704 ao_scheme_do_string_length(struct ao_scheme_cons *cons)
706 struct ao_scheme_string *string;
708 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dlength, cons, 1, 1))
709 return AO_SCHEME_NIL;
710 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dlength, cons, 0, AO_SCHEME_STRING, 0))
711 return AO_SCHEME_NIL;
712 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
713 return ao_scheme_integer_poly(strlen(string->val));
717 ao_scheme_do_string_copy(struct ao_scheme_cons *cons)
719 struct ao_scheme_string *string;
721 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dcopy, cons, 1, 1))
722 return AO_SCHEME_NIL;
723 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dcopy, cons, 0, AO_SCHEME_STRING, 0))
724 return AO_SCHEME_NIL;
725 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0));
726 return ao_scheme_string_poly(ao_scheme_string_copy(string));
730 ao_scheme_do_string_set(struct ao_scheme_cons *cons)
736 if (!ao_scheme_check_argc(_ao_scheme_atom_string2dset21, cons, 3, 3))
737 return AO_SCHEME_NIL;
738 if (!ao_scheme_check_argt(_ao_scheme_atom_string2dset21, cons, 0, AO_SCHEME_STRING, 0))
739 return AO_SCHEME_NIL;
740 string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val;
741 ref = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 1);
742 if (ao_scheme_exception)
743 return AO_SCHEME_NIL;
744 val = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 2);
745 if (ao_scheme_exception)
746 return AO_SCHEME_NIL;
747 while (*string && ref) {
752 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
753 _ao_scheme_atom_string2dset21,
754 ao_scheme_arg(cons, 0),
755 ao_scheme_arg(cons, 1));
757 return ao_scheme_int_poly(*string);
761 ao_scheme_do_flush_output(struct ao_scheme_cons *cons)
763 if (!ao_scheme_check_argc(_ao_scheme_atom_flush2doutput, cons, 0, 0))
764 return AO_SCHEME_NIL;
765 ao_scheme_os_flush();
766 return _ao_scheme_bool_true;
770 ao_scheme_do_led(struct ao_scheme_cons *cons)
773 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
774 return AO_SCHEME_NIL;
775 led = ao_scheme_arg_int(_ao_scheme_atom_led, cons, 0);
776 if (ao_scheme_exception)
777 return AO_SCHEME_NIL;
778 led = ao_scheme_arg(cons, 0);
779 ao_scheme_os_led(ao_scheme_poly_int(led));
784 ao_scheme_do_delay(struct ao_scheme_cons *cons)
788 if (!ao_scheme_check_argc(_ao_scheme_atom_delay, cons, 1, 1))
789 return AO_SCHEME_NIL;
790 delay = ao_scheme_arg_int(_ao_scheme_atom_delay, cons, 0);
791 if (ao_scheme_exception)
792 return AO_SCHEME_NIL;
793 ao_scheme_os_delay(delay);
798 ao_scheme_do_eval(struct ao_scheme_cons *cons)
800 if (!ao_scheme_check_argc(_ao_scheme_atom_eval, cons, 1, 1))
801 return AO_SCHEME_NIL;
802 ao_scheme_stack->state = eval_sexpr;
807 ao_scheme_do_apply(struct ao_scheme_cons *cons)
809 if (!ao_scheme_check_argc(_ao_scheme_atom_apply, cons, 2, INT_MAX))
810 return AO_SCHEME_NIL;
811 ao_scheme_stack->state = eval_apply;
812 return ao_scheme_cons_poly(cons);
816 ao_scheme_do_read(struct ao_scheme_cons *cons)
818 if (!ao_scheme_check_argc(_ao_scheme_atom_read, cons, 0, 0))
819 return AO_SCHEME_NIL;
820 return ao_scheme_read();
824 ao_scheme_do_collect(struct ao_scheme_cons *cons)
828 free = ao_scheme_collect(AO_SCHEME_COLLECT_FULL);
829 return ao_scheme_integer_poly(free);
833 ao_scheme_do_nullp(struct ao_scheme_cons *cons)
835 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
836 return AO_SCHEME_NIL;
837 if (ao_scheme_arg(cons, 0) == AO_SCHEME_NIL)
838 return _ao_scheme_bool_true;
840 return _ao_scheme_bool_false;
844 ao_scheme_do_not(struct ao_scheme_cons *cons)
846 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
847 return AO_SCHEME_NIL;
848 if (ao_scheme_arg(cons, 0) == _ao_scheme_bool_false)
849 return _ao_scheme_bool_true;
851 return _ao_scheme_bool_false;
855 ao_scheme_do_typep(int type, struct ao_scheme_cons *cons)
857 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
858 return AO_SCHEME_NIL;
859 if (ao_scheme_poly_type(ao_scheme_arg(cons, 0)) == type)
860 return _ao_scheme_bool_true;
861 return _ao_scheme_bool_false;
865 ao_scheme_do_pairp(struct ao_scheme_cons *cons)
868 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
869 return AO_SCHEME_NIL;
870 v = ao_scheme_arg(cons, 0);
871 if (ao_scheme_is_pair(v))
872 return _ao_scheme_bool_true;
873 return _ao_scheme_bool_false;
877 ao_scheme_do_integerp(struct ao_scheme_cons *cons)
879 #ifdef AO_SCHEME_FEATURE_BIGINT
880 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
881 return AO_SCHEME_NIL;
882 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
884 case AO_SCHEME_BIGINT:
885 return _ao_scheme_bool_true;
887 return _ao_scheme_bool_false;
890 return ao_scheme_do_typep(AO_SCHEME_INT, cons);
895 ao_scheme_do_numberp(struct ao_scheme_cons *cons)
897 #if defined(AO_SCHEME_FEATURE_BIGINT) || defined(AO_SCHEME_FEATURE_FLOAT)
898 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
899 return AO_SCHEME_NIL;
900 switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) {
902 #ifdef AO_SCHEME_FEATURE_BIGINT
903 case AO_SCHEME_BIGINT:
905 #ifdef AO_SCHEME_FEATURE_FLOAT
906 case AO_SCHEME_FLOAT:
908 return _ao_scheme_bool_true;
910 return _ao_scheme_bool_false;
913 return ao_scheme_do_integerp(cons);
918 ao_scheme_do_stringp(struct ao_scheme_cons *cons)
920 return ao_scheme_do_typep(AO_SCHEME_STRING, cons);
924 ao_scheme_do_symbolp(struct ao_scheme_cons *cons)
926 return ao_scheme_do_typep(AO_SCHEME_ATOM, cons);
930 ao_scheme_do_booleanp(struct ao_scheme_cons *cons)
932 return ao_scheme_do_typep(AO_SCHEME_BOOL, cons);
936 ao_scheme_do_procedurep(struct ao_scheme_cons *cons)
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))) {
941 case AO_SCHEME_BUILTIN:
942 case AO_SCHEME_LAMBDA:
943 return _ao_scheme_bool_true;
945 return _ao_scheme_bool_false;
949 /* This one is special -- a list is either nil or
950 * a 'proper' list with only cons cells
953 ao_scheme_do_listp(struct ao_scheme_cons *cons)
956 if (!ao_scheme_check_argc(_ao_scheme_atom_list3f, cons, 1, 1))
957 return AO_SCHEME_NIL;
958 v = ao_scheme_arg(cons, 0);
960 if (v == AO_SCHEME_NIL)
961 return _ao_scheme_bool_true;
962 if (!ao_scheme_is_cons(v))
963 return _ao_scheme_bool_false;
964 v = ao_scheme_poly_cons(v)->cdr;
969 ao_scheme_do_set_car(struct ao_scheme_cons *cons)
971 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
972 return AO_SCHEME_NIL;
973 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
974 return AO_SCHEME_NIL;
975 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->car = ao_scheme_arg(cons, 1);
979 ao_scheme_do_set_cdr(struct ao_scheme_cons *cons)
981 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2))
982 return AO_SCHEME_NIL;
983 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0))
984 return AO_SCHEME_NIL;
985 return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->cdr = ao_scheme_arg(cons, 1);
989 ao_scheme_do_symbol_to_string(struct ao_scheme_cons *cons)
991 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
992 return AO_SCHEME_NIL;
993 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_ATOM, 0))
994 return AO_SCHEME_NIL;
995 return ao_scheme_string_poly(ao_scheme_atom_to_string(ao_scheme_poly_atom(ao_scheme_arg(cons, 0))));
999 ao_scheme_do_string_to_symbol(struct ao_scheme_cons *cons)
1001 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1002 return AO_SCHEME_NIL;
1003 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_STRING, 0))
1004 return AO_SCHEME_NIL;
1006 return ao_scheme_atom_poly(ao_scheme_string_to_atom(ao_scheme_poly_string(ao_scheme_arg(cons, 0))));;
1010 ao_scheme_do_read_char(struct ao_scheme_cons *cons)
1013 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1014 return AO_SCHEME_NIL;
1016 return ao_scheme_int_poly(c);
1020 ao_scheme_do_write_char(struct ao_scheme_cons *cons)
1022 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
1023 return AO_SCHEME_NIL;
1024 if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_INT, 0))
1025 return AO_SCHEME_NIL;
1026 putchar(ao_scheme_poly_integer(ao_scheme_arg(cons, 0), NULL));
1027 return _ao_scheme_bool_true;
1031 ao_scheme_do_exit(struct ao_scheme_cons *cons)
1033 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1034 return AO_SCHEME_NIL;
1035 ao_scheme_exception |= AO_SCHEME_EXIT;
1036 return _ao_scheme_bool_true;
1040 ao_scheme_do_current_jiffy(struct ao_scheme_cons *cons)
1044 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1045 return AO_SCHEME_NIL;
1046 jiffy = ao_scheme_os_jiffy();
1047 return (ao_scheme_int_poly(jiffy));
1051 ao_scheme_do_current_second(struct ao_scheme_cons *cons)
1055 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1056 return AO_SCHEME_NIL;
1057 second = ao_scheme_os_jiffy() / AO_SCHEME_JIFFIES_PER_SECOND;
1058 return (ao_scheme_int_poly(second));
1062 ao_scheme_do_jiffies_per_second(struct ao_scheme_cons *cons)
1064 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0))
1065 return AO_SCHEME_NIL;
1066 return (ao_scheme_int_poly(AO_SCHEME_JIFFIES_PER_SECOND));
1069 #ifdef AO_SCHEME_FEATURE_VECTOR
1072 ao_scheme_do_vector(struct ao_scheme_cons *cons)
1074 return ao_scheme_vector_poly(ao_scheme_list_to_vector(cons));
1078 ao_scheme_do_make_vector(struct ao_scheme_cons *cons)
1082 if (!ao_scheme_check_argc(_ao_scheme_atom_make2dvector, cons, 2, 2))
1083 return AO_SCHEME_NIL;
1084 k = ao_scheme_arg_int(_ao_scheme_atom_make2dvector, cons, 0);
1085 if (ao_scheme_exception)
1086 return AO_SCHEME_NIL;
1087 return ao_scheme_vector_poly(ao_scheme_vector_alloc(k, ao_scheme_arg(cons, 1)));
1091 ao_scheme_do_vector_ref(struct ao_scheme_cons *cons)
1093 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dref, cons, 2, 2))
1094 return AO_SCHEME_NIL;
1095 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dref, cons, 0, AO_SCHEME_VECTOR, 0))
1096 return AO_SCHEME_NIL;
1097 return ao_scheme_vector_get(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1));
1101 ao_scheme_do_vector_set(struct ao_scheme_cons *cons)
1103 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dset21, cons, 3, 3))
1104 return AO_SCHEME_NIL;
1105 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dset21, cons, 0, AO_SCHEME_VECTOR, 0))
1106 return AO_SCHEME_NIL;
1107 return ao_scheme_vector_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1), ao_scheme_arg(cons, 2));
1111 ao_scheme_do_list_to_vector(struct ao_scheme_cons *cons)
1113 if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3evector, cons, 1, 1))
1114 return AO_SCHEME_NIL;
1115 if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3evector, cons, 0, AO_SCHEME_CONS, 0))
1116 return AO_SCHEME_NIL;
1117 return ao_scheme_vector_poly(ao_scheme_list_to_vector(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))));
1121 ao_scheme_do_vector_to_list(struct ao_scheme_cons *cons)
1123 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1))
1124 return AO_SCHEME_NIL;
1125 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1126 return AO_SCHEME_NIL;
1127 return ao_scheme_cons_poly(ao_scheme_vector_to_list(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))));
1131 ao_scheme_do_vector_length(struct ao_scheme_cons *cons)
1133 if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1))
1134 return AO_SCHEME_NIL;
1135 if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0))
1136 return AO_SCHEME_NIL;
1137 return ao_scheme_integer_poly(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))->length);
1141 ao_scheme_do_vectorp(struct ao_scheme_cons *cons)
1143 return ao_scheme_do_typep(AO_SCHEME_VECTOR, cons);
1146 #endif /* AO_SCHEME_FEATURE_VECTOR */
1148 #define AO_SCHEME_BUILTIN_FUNCS
1149 #include "ao_scheme_builtin.h"