diff options
Diffstat (limited to 'src/scheme/ao_scheme_builtin.c')
| -rw-r--r-- | src/scheme/ao_scheme_builtin.c | 1137 | 
1 files changed, 0 insertions, 1137 deletions
| diff --git a/src/scheme/ao_scheme_builtin.c b/src/scheme/ao_scheme_builtin.c deleted file mode 100644 index 81fd9010..00000000 --- a/src/scheme/ao_scheme_builtin.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Copyright © 2016 Keith Packard <keithp@keithp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * General Public License for more details. - */ - -#include "ao_scheme.h" -#include <limits.h> -#include <math.h> - -static int -builtin_size(void *addr) -{ -	(void) addr; -	return sizeof (struct ao_scheme_builtin); -} - -static void -builtin_mark(void *addr) -{ -	(void) addr; -} - -static void -builtin_move(void *addr) -{ -	(void) addr; -} - -const struct ao_scheme_type ao_scheme_builtin_type = { -	.size = builtin_size, -	.mark = builtin_mark, -	.move = builtin_move -}; - -#ifdef AO_SCHEME_MAKE_CONST - -#define AO_SCHEME_BUILTIN_CASENAME -#include "ao_scheme_builtin.h" - -char *ao_scheme_args_name(uint8_t args) { -	args &= AO_SCHEME_FUNC_MASK; -	switch (args) { -	case AO_SCHEME_FUNC_LAMBDA: return ao_scheme_poly_atom(_ao_scheme_atom_lambda)->name; -	case AO_SCHEME_FUNC_NLAMBDA: return ao_scheme_poly_atom(_ao_scheme_atom_nlambda)->name; -	case AO_SCHEME_FUNC_MACRO: return ao_scheme_poly_atom(_ao_scheme_atom_macro)->name; -	default: return (char *) "???"; -	} -} -#else - -#define AO_SCHEME_BUILTIN_ARRAYNAME -#include "ao_scheme_builtin.h" - -static char * -ao_scheme_builtin_name(enum ao_scheme_builtin_id b) { -	if (b < _builtin_last) -		return ao_scheme_poly_atom(builtin_names[b])->name; -	return (char *) "???"; -} - -static const ao_poly ao_scheme_args_atoms[] = { -	[AO_SCHEME_FUNC_LAMBDA] = _ao_scheme_atom_lambda, -	[AO_SCHEME_FUNC_NLAMBDA] = _ao_scheme_atom_nlambda, -	[AO_SCHEME_FUNC_MACRO] = _ao_scheme_atom_macro, -}; - -char * -ao_scheme_args_name(uint8_t args) -{ -	args &= AO_SCHEME_FUNC_MASK; -	if (args < sizeof ao_scheme_args_atoms / sizeof ao_scheme_args_atoms[0]) -		return ao_scheme_poly_atom(ao_scheme_args_atoms[args])->name; -	return (char *) "(unknown)"; -} -#endif - -void -ao_scheme_builtin_write(ao_poly b, bool write) -{ -	struct ao_scheme_builtin *builtin = ao_scheme_poly_builtin(b); -	(void) write; -	printf("%s", ao_scheme_builtin_name(builtin->func)); -} - -ao_poly -ao_scheme_check_argc(ao_poly name, struct ao_scheme_cons *cons, int min, int max) -{ -	int	argc = 0; - -	while (cons && argc <= max) { -		argc++; -		cons = ao_scheme_cons_cdr(cons); -	} -	if (argc < min || argc > max) -		return ao_scheme_error(AO_SCHEME_INVALID, "%s: invalid arg count", ao_scheme_poly_atom(name)->name); -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_arg(struct ao_scheme_cons *cons, int argc) -{ -	if (!cons) -		return AO_SCHEME_NIL; -	while (argc--) { -		if (!cons) -			return AO_SCHEME_NIL; -		cons = ao_scheme_cons_cdr(cons); -	} -	return cons->car; -} - -ao_poly -ao_scheme_check_argt(ao_poly name, struct ao_scheme_cons *cons, int argc, int type, int nil_ok) -{ -	ao_poly car = ao_scheme_arg(cons, argc); - -	if ((!car && !nil_ok) || ao_scheme_poly_type(car) != type) -		return ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, car); -	return _ao_scheme_bool_true; -} - -static int32_t -ao_scheme_arg_int(ao_poly name, struct ao_scheme_cons *cons, int argc) -{ -	ao_poly 	p = ao_scheme_arg(cons, argc); -	bool		fail = false; -	int32_t		i = ao_scheme_poly_integer(p, &fail); - -	if (fail) -		(void) ao_scheme_error(AO_SCHEME_INVALID, "%v: arg %d invalid type %v", name, argc, p); -	return i; -} - -ao_poly -ao_scheme_do_car(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_car, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_car, cons, 0, AO_SCHEME_CONS, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_poly_cons(cons->car)->car; -} - -ao_poly -ao_scheme_do_cdr(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_cdr, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_cdr, cons, 0, AO_SCHEME_CONS, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_poly_cons(cons->car)->cdr; -} - -ao_poly -ao_scheme_do_cons(struct ao_scheme_cons *cons) -{ -	ao_poly	car, cdr; -	if(!ao_scheme_check_argc(_ao_scheme_atom_cons, cons, 2, 2)) -		return AO_SCHEME_NIL; -	car = ao_scheme_arg(cons, 0); -	cdr = ao_scheme_arg(cons, 1); -	return ao_scheme_cons(car, cdr); -} - -ao_poly -ao_scheme_do_last(struct ao_scheme_cons *cons) -{ -	struct ao_scheme_cons	*list; -	if (!ao_scheme_check_argc(_ao_scheme_atom_last, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_last, cons, 0, AO_SCHEME_CONS, 1)) -		return AO_SCHEME_NIL; -	for (list = ao_scheme_poly_cons(ao_scheme_arg(cons, 0)); -	     list; -	     list = ao_scheme_cons_cdr(list)) -	{ -		if (!list->cdr) -			return list->car; -	} -	return AO_SCHEME_NIL; -} - -ao_poly -ao_scheme_do_length(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1)) -		return AO_SCHEME_NIL; -	return ao_scheme_int_poly(ao_scheme_cons_length(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)))); -} - -ao_poly -ao_scheme_do_list_copy(struct ao_scheme_cons *cons) -{ -	struct ao_scheme_cons *new; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_length, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_length, cons, 0, AO_SCHEME_CONS, 1)) -		return AO_SCHEME_NIL; -	new = ao_scheme_cons_copy(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))); -	return ao_scheme_cons_poly(new); -} - -ao_poly -ao_scheme_do_quote(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_quote, cons, 1, 1)) -		return AO_SCHEME_NIL; -	return ao_scheme_arg(cons, 0); -} - -ao_poly -ao_scheme_do_set(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_set, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_set, cons, 0, AO_SCHEME_ATOM, 0)) -		return AO_SCHEME_NIL; - -	return ao_scheme_atom_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1)); -} - -ao_poly -ao_scheme_do_def(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_def, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_def, cons, 0, AO_SCHEME_ATOM, 0)) -		return AO_SCHEME_NIL; - -	return ao_scheme_atom_def(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1)); -} - -ao_poly -ao_scheme_do_setq(struct ao_scheme_cons *cons) -{ -	ao_poly	name; -	if (!ao_scheme_check_argc(_ao_scheme_atom_set21, cons, 2, 2)) -		return AO_SCHEME_NIL; -	name = cons->car; -	if (ao_scheme_poly_type(name) != AO_SCHEME_ATOM) -		return ao_scheme_error(AO_SCHEME_INVALID, "set! of non-atom %v", name); -	if (!ao_scheme_atom_ref(name, NULL)) -		return ao_scheme_error(AO_SCHEME_INVALID, "atom %v not defined", name); -	return ao_scheme_cons(_ao_scheme_atom_set, -			      ao_scheme_cons(ao_scheme_cons(_ao_scheme_atom_quote, -							    ao_scheme_cons(name, AO_SCHEME_NIL)), -					     cons->cdr)); -} - -ao_poly -ao_scheme_do_cond(struct ao_scheme_cons *cons) -{ -	ao_scheme_set_cond(cons); -	return AO_SCHEME_NIL; -} - -ao_poly -ao_scheme_do_begin(struct ao_scheme_cons *cons) -{ -	ao_scheme_stack->state = eval_begin; -	ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons); -	return AO_SCHEME_NIL; -} - -ao_poly -ao_scheme_do_while(struct ao_scheme_cons *cons) -{ -	ao_scheme_stack->state = eval_while; -	ao_scheme_stack->sexprs = ao_scheme_cons_poly(cons); -	return AO_SCHEME_NIL; -} - -ao_poly -ao_scheme_do_write(struct ao_scheme_cons *cons) -{ -	ao_poly	val = AO_SCHEME_NIL; -	while (cons) { -		val = cons->car; -		ao_scheme_poly_write(val, true); -		cons = ao_scheme_cons_cdr(cons); -		if (cons) -			printf(" "); -	} -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_do_display(struct ao_scheme_cons *cons) -{ -	ao_poly	val = AO_SCHEME_NIL; -	while (cons) { -		val = cons->car; -		ao_scheme_poly_write(val, false); -		cons = ao_scheme_cons_cdr(cons); -	} -	return _ao_scheme_bool_true; -} - -static ao_poly -ao_scheme_math(struct ao_scheme_cons *orig_cons, enum ao_scheme_builtin_id op) -{ -	struct ao_scheme_cons *cons; -	ao_poly	ret = AO_SCHEME_NIL; - -	for (cons = orig_cons; cons; cons = ao_scheme_cons_cdr(cons)) { -		ao_poly		car = cons->car; -		uint8_t		rt = ao_scheme_poly_type(ret); -		uint8_t		ct = ao_scheme_poly_type(car); - -		if (cons == orig_cons) { -			ret = car; -			ao_scheme_cons_stash(cons); -			if (cons->cdr == AO_SCHEME_NIL) { -				switch (op) { -				case builtin_minus: -					if (ao_scheme_integer_typep(ct)) -						ret = ao_scheme_integer_poly(-ao_scheme_poly_integer(ret, NULL)); -#ifdef AO_SCHEME_FEATURE_FLOAT -					else if (ct == AO_SCHEME_FLOAT) -						ret = ao_scheme_float_get(-ao_scheme_poly_number(ret)); -#endif -					break; -				case builtin_divide: -					if (ao_scheme_poly_integer(ret, NULL) == 1) { -					} else { -#ifdef AO_SCHEME_FEATURE_FLOAT -						if (ao_scheme_number_typep(ct)) { -							float	v = ao_scheme_poly_number(ret); -							ret = ao_scheme_float_get(1/v); -						} -#else -						ret = ao_scheme_integer_poly(0); -#endif -					} -					break; -				default: -					break; -				} -			} -			cons = ao_scheme_cons_fetch(); -		} else if (ao_scheme_integer_typep(rt) && ao_scheme_integer_typep(ct)) { -			int32_t	r = ao_scheme_poly_integer(ret, NULL); -			int32_t	c = ao_scheme_poly_integer(car, NULL); -#ifdef AO_SCHEME_FEATURE_FLOAT -			int64_t t; -#endif - -			switch(op) { -			case builtin_plus: -				r += c; -			check_overflow: -#ifdef AO_SCHEME_FEATURE_FLOAT -				if (r < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < r) -					goto inexact; -#endif -				break; -			case builtin_minus: -				r -= c; -				goto check_overflow; -				break; -			case builtin_times: -#ifdef AO_SCHEME_FEATURE_FLOAT -				t = (int64_t) r * (int64_t) c; -				if (t < AO_SCHEME_MIN_BIGINT || AO_SCHEME_MAX_BIGINT < t) -					goto inexact; -				r = (int32_t) t; -#else -				r = r * c; -#endif -				break; -			case builtin_divide: -#ifdef AO_SCHEME_FEATURE_FLOAT -				if (c != 0 && (r % c) == 0) -					r /= c; -				else -					goto inexact; -#else -				r /= c; -#endif -				break; -			case builtin_quotient: -				if (c == 0) -					return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "quotient by zero"); -				if (r % c != 0 && (c < 0) != (r < 0)) -					r = r / c - 1; -				else -					r = r / c; -				break; -			case builtin_remainder: -				if (c == 0) -					return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "remainder by zero"); -				r %= c; -				break; -			case builtin_modulo: -				if (c == 0) -					return ao_scheme_error(AO_SCHEME_DIVIDE_BY_ZERO, "modulo by zero"); -				r %= c; -				if ((r < 0) != (c < 0)) -					r += c; -				break; -			default: -				break; -			} -			ao_scheme_cons_stash(cons); -			ret = ao_scheme_integer_poly(r); -			cons = ao_scheme_cons_fetch(); -#ifdef AO_SCHEME_FEATURE_FLOAT -		} else if (ao_scheme_number_typep(rt) && ao_scheme_number_typep(ct)) { -			float r, c; -		inexact: -			r = ao_scheme_poly_number(ret); -			c = ao_scheme_poly_number(car); -			switch(op) { -			case builtin_plus: -				r += c; -				break; -			case builtin_minus: -				r -= c; -				break; -			case builtin_times: -				r *= c; -				break; -			case builtin_divide: -				r /= c; -				break; -			case builtin_quotient: -			case builtin_remainder: -			case builtin_modulo: -				return ao_scheme_error(AO_SCHEME_INVALID, "non-integer value in integer divide"); -			default: -				break; -			} -			ao_scheme_cons_stash(cons); -			ret = ao_scheme_float_get(r); -			cons = ao_scheme_cons_fetch(); -#endif -		} -		else if (rt == AO_SCHEME_STRING && ct == AO_SCHEME_STRING && op == builtin_plus) { -			ao_scheme_cons_stash(cons); -			ret = ao_scheme_string_poly(ao_scheme_string_cat(ao_scheme_poly_string(ret), -									 ao_scheme_poly_string(car))); -			cons = ao_scheme_cons_fetch(); -			if (!ret) -				return ret; -		} -		else -			return ao_scheme_error(AO_SCHEME_INVALID, "invalid args"); -	} -	return ret; -} - -ao_poly -ao_scheme_do_plus(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_plus); -} - -ao_poly -ao_scheme_do_minus(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_minus); -} - -ao_poly -ao_scheme_do_times(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_times); -} - -ao_poly -ao_scheme_do_divide(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_divide); -} - -ao_poly -ao_scheme_do_quotient(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_quotient); -} - -ao_poly -ao_scheme_do_modulo(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_modulo); -} - -ao_poly -ao_scheme_do_remainder(struct ao_scheme_cons *cons) -{ -	return ao_scheme_math(cons, builtin_remainder); -} - -static ao_poly -ao_scheme_compare(struct ao_scheme_cons *cons, enum ao_scheme_builtin_id op) -{ -	ao_poly	left; - -	if (!cons) -		return _ao_scheme_bool_true; - -	left = cons->car; -	for (cons = ao_scheme_cons_cdr(cons); cons; cons = ao_scheme_cons_cdr(cons)) { -		ao_poly	right = cons->car; - -		if (op == builtin_equal && left == right) { -			; -		} else { -			uint8_t	lt = ao_scheme_poly_type(left); -			uint8_t	rt = ao_scheme_poly_type(right); -			if (ao_scheme_integer_typep(lt) && ao_scheme_integer_typep(rt)) { -				int32_t l = ao_scheme_poly_integer(left, NULL); -				int32_t r = ao_scheme_poly_integer(right, NULL); - -				switch (op) { -				case builtin_less: -					if (!(l < r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater: -					if (!(l > r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_less_equal: -					if (!(l <= r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater_equal: -					if (!(l >= r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_equal: -					if (!(l == r)) -						return _ao_scheme_bool_false; -				default: -					break; -				} -#ifdef AO_SCHEME_FEATURE_FLOAT -			} else if (ao_scheme_number_typep(lt) && ao_scheme_number_typep(rt)) { -				float l, r; - -				l = ao_scheme_poly_number(left); -				r = ao_scheme_poly_number(right); - -				switch (op) { -				case builtin_less: -					if (!(l < r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater: -					if (!(l > r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_less_equal: -					if (!(l <= r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater_equal: -					if (!(l >= r)) -						return _ao_scheme_bool_false; -					break; -				case builtin_equal: -					if (!(l == r)) -						return _ao_scheme_bool_false; -				default: -					break; -				} -#endif /* AO_SCHEME_FEATURE_FLOAT */ -			} else if (lt == AO_SCHEME_STRING && rt == AO_SCHEME_STRING) { -				int c = strcmp(ao_scheme_poly_string(left)->val, -					       ao_scheme_poly_string(right)->val); -				switch (op) { -				case builtin_less: -					if (!(c < 0)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater: -					if (!(c > 0)) -						return _ao_scheme_bool_false; -					break; -				case builtin_less_equal: -					if (!(c <= 0)) -						return _ao_scheme_bool_false; -					break; -				case builtin_greater_equal: -					if (!(c >= 0)) -						return _ao_scheme_bool_false; -					break; -				case builtin_equal: -					if (!(c == 0)) -						return _ao_scheme_bool_false; -					break; -				default: -					break; -				} -			} else -				return _ao_scheme_bool_false; -		} -		left = right; -	} -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_do_equal(struct ao_scheme_cons *cons) -{ -	return ao_scheme_compare(cons, builtin_equal); -} - -ao_poly -ao_scheme_do_less(struct ao_scheme_cons *cons) -{ -	return ao_scheme_compare(cons, builtin_less); -} - -ao_poly -ao_scheme_do_greater(struct ao_scheme_cons *cons) -{ -	return ao_scheme_compare(cons, builtin_greater); -} - -ao_poly -ao_scheme_do_less_equal(struct ao_scheme_cons *cons) -{ -	return ao_scheme_compare(cons, builtin_less_equal); -} - -ao_poly -ao_scheme_do_greater_equal(struct ao_scheme_cons *cons) -{ -	return ao_scheme_compare(cons, builtin_greater_equal); -} - -ao_poly -ao_scheme_do_list_to_string(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3estring, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3estring, cons, 0, AO_SCHEME_CONS, 1)) -		return AO_SCHEME_NIL; -	return ao_scheme_string_pack(ao_scheme_poly_cons(ao_scheme_arg(cons, 0))); -} - -ao_poly -ao_scheme_do_string_to_list(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_string2d3elist, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_string2d3elist, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_string_unpack(ao_scheme_poly_string(ao_scheme_arg(cons, 0))); -} - -ao_poly -ao_scheme_do_string_ref(struct ao_scheme_cons *cons) -{ -	char	*string; -	int32_t ref; -	if (!ao_scheme_check_argc(_ao_scheme_atom_string2dref, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_string2dref, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; -	ref = ao_scheme_arg_int(_ao_scheme_atom_string2dref, cons, 1); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val; -	while (*string && ref) { -		++string; -		--ref; -	} -	if (!*string) -		return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid", -				       _ao_scheme_atom_string2dref, -				       ao_scheme_arg(cons, 0), -				       ao_scheme_arg(cons, 1)); -	return ao_scheme_int_poly(*string); -} - -ao_poly -ao_scheme_do_string_length(struct ao_scheme_cons *cons) -{ -	struct ao_scheme_string *string; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_string2dlength, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_string2dlength, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; -	string = ao_scheme_poly_string(ao_scheme_arg(cons, 0)); -	return ao_scheme_integer_poly(strlen(string->val)); -} - -ao_poly -ao_scheme_do_string_copy(struct ao_scheme_cons *cons) -{ -	struct ao_scheme_string	*string; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_string2dcopy, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_string2dcopy, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; -	string = ao_scheme_poly_string(ao_scheme_arg(cons, 0)); -	return ao_scheme_string_poly(ao_scheme_string_copy(string)); -} - -ao_poly -ao_scheme_do_string_set(struct ao_scheme_cons *cons) -{ -	char	*string; -	int32_t ref; -	int32_t val; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_string2dset21, cons, 3, 3)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_string2dset21, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; -	string = ao_scheme_poly_string(ao_scheme_arg(cons, 0))->val; -	ref = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 1); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	val = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 2); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	while (*string && ref) { -		++string; -		--ref; -	} -	if (!*string) -		return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid", -				       _ao_scheme_atom_string2dset21, -				       ao_scheme_arg(cons, 0), -				       ao_scheme_arg(cons, 1)); -	*string = val; -	return ao_scheme_int_poly(*string); -} - -ao_poly -ao_scheme_do_flush_output(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_flush2doutput, cons, 0, 0)) -		return AO_SCHEME_NIL; -	ao_scheme_os_flush(); -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_do_led(struct ao_scheme_cons *cons) -{ -	int32_t led; -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	led = ao_scheme_arg_int(_ao_scheme_atom_led, cons, 0); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	led = ao_scheme_arg(cons, 0); -	ao_scheme_os_led(ao_scheme_poly_int(led)); -	return led; -} - -ao_poly -ao_scheme_do_delay(struct ao_scheme_cons *cons) -{ -	int32_t delay; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_delay, cons, 1, 1)) -		return AO_SCHEME_NIL; -	delay = ao_scheme_arg_int(_ao_scheme_atom_delay, cons, 0); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	ao_scheme_os_delay(delay); -	return delay; -} - -ao_poly -ao_scheme_do_eval(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_eval, cons, 1, 1)) -		return AO_SCHEME_NIL; -	ao_scheme_stack->state = eval_sexpr; -	return cons->car; -} - -ao_poly -ao_scheme_do_apply(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_apply, cons, 2, INT_MAX)) -		return AO_SCHEME_NIL; -	ao_scheme_stack->state = eval_apply; -	return ao_scheme_cons_poly(cons); -} - -ao_poly -ao_scheme_do_read(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_read, cons, 0, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_read(); -} - -ao_poly -ao_scheme_do_collect(struct ao_scheme_cons *cons) -{ -	int	free; -	(void) cons; -	free = ao_scheme_collect(AO_SCHEME_COLLECT_FULL); -	return ao_scheme_integer_poly(free); -} - -ao_poly -ao_scheme_do_nullp(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (ao_scheme_arg(cons, 0) == AO_SCHEME_NIL) -		return _ao_scheme_bool_true; -	else -		return _ao_scheme_bool_false; -} - -ao_poly -ao_scheme_do_not(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (ao_scheme_arg(cons, 0) == _ao_scheme_bool_false) -		return _ao_scheme_bool_true; -	else -		return _ao_scheme_bool_false; -} - -static ao_poly -ao_scheme_do_typep(int type, struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (ao_scheme_poly_type(ao_scheme_arg(cons, 0)) == type) -		return _ao_scheme_bool_true; -	return _ao_scheme_bool_false; -} - -ao_poly -ao_scheme_do_pairp(struct ao_scheme_cons *cons) -{ -	ao_poly	v; -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	v = ao_scheme_arg(cons, 0); -	if (ao_scheme_is_pair(v)) -		return _ao_scheme_bool_true; -	return _ao_scheme_bool_false; -} - -ao_poly -ao_scheme_do_integerp(struct ao_scheme_cons *cons) -{ -#ifdef AO_SCHEME_FEATURE_BIGINT -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) { -	case AO_SCHEME_INT: -	case AO_SCHEME_BIGINT: -		return _ao_scheme_bool_true; -	default: -		return _ao_scheme_bool_false; -	} -#else -	return ao_scheme_do_typep(AO_SCHEME_INT, cons); -#endif -} - -ao_poly -ao_scheme_do_numberp(struct ao_scheme_cons *cons) -{ -#if defined(AO_SCHEME_FEATURE_BIGINT) || defined(AO_SCHEME_FEATURE_FLOAT) -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) { -	case AO_SCHEME_INT: -#ifdef AO_SCHEME_FEATURE_BIGINT -	case AO_SCHEME_BIGINT: -#endif -#ifdef AO_SCHEME_FEATURE_FLOAT -	case AO_SCHEME_FLOAT: -#endif -		return _ao_scheme_bool_true; -	default: -		return _ao_scheme_bool_false; -	} -#else -	return ao_scheme_do_integerp(cons); -#endif -} - -ao_poly -ao_scheme_do_stringp(struct ao_scheme_cons *cons) -{ -	return ao_scheme_do_typep(AO_SCHEME_STRING, cons); -} - -ao_poly -ao_scheme_do_symbolp(struct ao_scheme_cons *cons) -{ -	return ao_scheme_do_typep(AO_SCHEME_ATOM, cons); -} - -ao_poly -ao_scheme_do_booleanp(struct ao_scheme_cons *cons) -{ -	return ao_scheme_do_typep(AO_SCHEME_BOOL, cons); -} - -ao_poly -ao_scheme_do_procedurep(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	switch (ao_scheme_poly_type(ao_scheme_arg(cons, 0))) { -	case AO_SCHEME_BUILTIN: -	case AO_SCHEME_LAMBDA: -		return _ao_scheme_bool_true; -	default: -	return _ao_scheme_bool_false; -	} -} - -/* This one is special -- a list is either nil or - * a 'proper' list with only cons cells - */ -ao_poly -ao_scheme_do_listp(struct ao_scheme_cons *cons) -{ -	ao_poly	v; -	if (!ao_scheme_check_argc(_ao_scheme_atom_list3f, cons, 1, 1)) -		return AO_SCHEME_NIL; -	v = ao_scheme_arg(cons, 0); -	for (;;) { -		if (v == AO_SCHEME_NIL) -			return _ao_scheme_bool_true; -		if (!ao_scheme_is_cons(v)) -			return _ao_scheme_bool_false; -		v = ao_scheme_poly_cons(v)->cdr; -	} -} - -ao_poly -ao_scheme_do_set_car(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->car = ao_scheme_arg(cons, 1); -} - -ao_poly -ao_scheme_do_set_cdr(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_CONS, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_poly_cons(ao_scheme_arg(cons, 0))->cdr = ao_scheme_arg(cons, 1); -} - -ao_poly -ao_scheme_do_symbol_to_string(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_ATOM, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_string_poly(ao_scheme_atom_to_string(ao_scheme_poly_atom(ao_scheme_arg(cons, 0)))); -} - -ao_poly -ao_scheme_do_string_to_symbol(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_STRING, 0)) -		return AO_SCHEME_NIL; - -	return ao_scheme_atom_poly(ao_scheme_string_to_atom(ao_scheme_poly_string(ao_scheme_arg(cons, 0))));; -} - -ao_poly -ao_scheme_do_read_char(struct ao_scheme_cons *cons) -{ -	int	c; -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0)) -		return AO_SCHEME_NIL; -	c = getchar(); -	return ao_scheme_int_poly(c); -} - -ao_poly -ao_scheme_do_write_char(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_led, cons, 0, AO_SCHEME_INT, 0)) -		return AO_SCHEME_NIL; -	putchar(ao_scheme_poly_integer(ao_scheme_arg(cons, 0), NULL)); -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_do_exit(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0)) -		return AO_SCHEME_NIL; -	ao_scheme_exception |= AO_SCHEME_EXIT; -	return _ao_scheme_bool_true; -} - -ao_poly -ao_scheme_do_current_jiffy(struct ao_scheme_cons *cons) -{ -	int	jiffy; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0)) -		return AO_SCHEME_NIL; -	jiffy = ao_scheme_os_jiffy(); -	return (ao_scheme_int_poly(jiffy)); -} - -ao_poly -ao_scheme_do_current_second(struct ao_scheme_cons *cons) -{ -	int	second; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0)) -		return AO_SCHEME_NIL; -	second = ao_scheme_os_jiffy() / AO_SCHEME_JIFFIES_PER_SECOND; -	return (ao_scheme_int_poly(second)); -} - -ao_poly -ao_scheme_do_jiffies_per_second(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 0, 0)) -		return AO_SCHEME_NIL; -	return (ao_scheme_int_poly(AO_SCHEME_JIFFIES_PER_SECOND)); -} - -#ifdef AO_SCHEME_FEATURE_VECTOR - -ao_poly -ao_scheme_do_vector(struct ao_scheme_cons *cons) -{ -	return ao_scheme_vector_poly(ao_scheme_list_to_vector(cons)); -} - -ao_poly -ao_scheme_do_make_vector(struct ao_scheme_cons *cons) -{ -	int32_t	k; - -	if (!ao_scheme_check_argc(_ao_scheme_atom_make2dvector, cons, 2, 2)) -		return AO_SCHEME_NIL; -	k = ao_scheme_arg_int(_ao_scheme_atom_make2dvector, cons, 0); -	if (ao_scheme_exception) -		return AO_SCHEME_NIL; -	return ao_scheme_vector_poly(ao_scheme_vector_alloc(k, ao_scheme_arg(cons, 1))); -} - -ao_poly -ao_scheme_do_vector_ref(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dref, cons, 2, 2)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dref, cons, 0, AO_SCHEME_VECTOR, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_vector_get(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1)); -} - -ao_poly -ao_scheme_do_vector_set(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_vector2dset21, cons, 3, 3)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_vector2dset21, cons, 0, AO_SCHEME_VECTOR, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_vector_set(ao_scheme_arg(cons, 0), ao_scheme_arg(cons, 1), ao_scheme_arg(cons, 2)); -} - -ao_poly -ao_scheme_do_list_to_vector(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_list2d3evector, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_list2d3evector, cons, 0, AO_SCHEME_CONS, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_vector_poly(ao_scheme_list_to_vector(ao_scheme_poly_cons(ao_scheme_arg(cons, 0)))); -} - -ao_poly -ao_scheme_do_vector_to_list(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_cons_poly(ao_scheme_vector_to_list(ao_scheme_poly_vector(ao_scheme_arg(cons, 0)))); -} - -ao_poly -ao_scheme_do_vector_length(struct ao_scheme_cons *cons) -{ -	if (!ao_scheme_check_argc(_ao_scheme_atom_vector2d3elist, cons, 1, 1)) -		return AO_SCHEME_NIL; -	if (!ao_scheme_check_argt(_ao_scheme_atom_vector2d3elist, cons, 0, AO_SCHEME_VECTOR, 0)) -		return AO_SCHEME_NIL; -	return ao_scheme_integer_poly(ao_scheme_poly_vector(ao_scheme_arg(cons, 0))->length); -} - -ao_poly -ao_scheme_do_vectorp(struct ao_scheme_cons *cons) -{ -	return ao_scheme_do_typep(AO_SCHEME_VECTOR, cons); -} - -#endif /* AO_SCHEME_FEATURE_VECTOR */ - -#define AO_SCHEME_BUILTIN_FUNCS -#include "ao_scheme_builtin.h" | 
