diff options
| author | Keith Packard <keithp@keithp.com> | 2018-01-06 17:29:10 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2018-01-06 17:31:43 -0800 | 
| commit | 16061947d4376b41e596d87f97ec53ec29d17644 (patch) | |
| tree | f7ad08f8810b0ea78cf282048eacb46d441a2ee1 /src/scheme/ao_scheme_cons.c | |
| parent | 39df849f0717d92a7d5bdf8aa5904bd4db1b467f (diff) | |
altos/scheme: Add ports. Split scheme code up.
And lots of other changes, including freeing unreferenced atoms.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/scheme/ao_scheme_cons.c')
| -rw-r--r-- | src/scheme/ao_scheme_cons.c | 184 | 
1 files changed, 175 insertions, 9 deletions
| diff --git a/src/scheme/ao_scheme_cons.c b/src/scheme/ao_scheme_cons.c index a9ff5acd..a6e697b2 100644 --- a/src/scheme/ao_scheme_cons.c +++ b/src/scheme/ao_scheme_cons.c @@ -124,7 +124,7 @@ ao_scheme_cons(ao_poly car, ao_poly cdr)  	return ao_scheme_cons_poly(ao_scheme_cons_cons(car, cdr));  } -struct ao_scheme_cons * +static struct ao_scheme_cons *  ao_scheme_cons_copy(struct ao_scheme_cons *cons)  {  	struct ao_scheme_cons	*head = NULL; @@ -175,7 +175,7 @@ ao_scheme_cons_free(struct ao_scheme_cons *cons)  }  void -ao_scheme_cons_write(ao_poly c, bool write) +ao_scheme_cons_write(FILE *out, ao_poly c, bool write)  {  	struct ao_scheme_cons	*cons = ao_scheme_poly_cons(c);  	struct ao_scheme_cons	*clear = cons; @@ -183,34 +183,34 @@ ao_scheme_cons_write(ao_poly c, bool write)  	int			written = 0;  	ao_scheme_print_start(); -	printf("("); +	fprintf(out, "(");  	while (cons) {  		if (written != 0) -			printf(" "); +			fprintf(out, " ");  		/* Note if there's recursion in printing. Not  		 * as good as actual references, but at least  		 * we don't infinite loop...  		 */  		if (ao_scheme_print_mark_addr(cons)) { -			printf("..."); +			fprintf(out, "...");  			break;  		} -		ao_scheme_poly_write(cons->car, write); +		ao_scheme_poly_write(out, cons->car, write);  		/* keep track of how many pairs have been printed */  		written++;  		cdr = cons->cdr;  		if (!ao_scheme_is_cons(cdr)) { -			printf(" . "); -			ao_scheme_poly_write(cdr, write); +			fprintf(out, " . "); +			ao_scheme_poly_write(out, cdr, write);  			break;  		}  		cons = ao_scheme_poly_cons(cdr);  	} -	printf(")"); +	fprintf(out, ")");  	if (ao_scheme_print_stop()) { @@ -234,3 +234,169 @@ ao_scheme_cons_length(struct ao_scheme_cons *cons)  	}  	return len;  } + +ao_poly +ao_scheme_do_car(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons *pair; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_car, cons, +				  AO_SCHEME_CONS, &pair, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	return pair->car; +} + +ao_poly +ao_scheme_do_cdr(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons *pair; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_cdr, cons, +				  AO_SCHEME_CONS, &pair, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	return pair->cdr; +} + +ao_poly +ao_scheme_do_cons(struct ao_scheme_cons *cons) +{ +	ao_poly	car, cdr; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_cons, cons, +				  AO_SCHEME_POLY, &car, +				  AO_SCHEME_POLY, &cdr, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	return ao_scheme_cons(car, cdr); +} + +ao_poly +ao_scheme_do_last(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons	*pair; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_last, cons, +				  AO_SCHEME_CONS | AO_SCHEME_ARG_NIL_OK, &pair, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	while (pair) { +		if (!pair->cdr) +			return pair->car; +		pair = ao_scheme_cons_cdr(pair); +	} +	return AO_SCHEME_NIL; +} + +ao_poly +ao_scheme_do_length(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons	*pair; +	if (!ao_scheme_parse_args(_ao_scheme_atom_length, cons, +				  AO_SCHEME_CONS | AO_SCHEME_ARG_NIL_OK, &pair, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	return ao_scheme_integer_poly(ao_scheme_cons_length(pair)); +} + +ao_poly +ao_scheme_do_list_copy(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons	*pair; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_list2dcopy, cons, +				  AO_SCHEME_CONS | AO_SCHEME_ARG_NIL_OK, &pair, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	return ao_scheme_cons_poly(ao_scheme_cons_copy(pair)); +} + +ao_poly +ao_scheme_do_list_tail(struct ao_scheme_cons *cons) +{ +	ao_poly			list; +	int32_t			v; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_list2dtail, cons, +				  AO_SCHEME_CONS | AO_SCHEME_ARG_NIL_OK | AO_SCHEME_ARG_RET_POLY, &list, +				  AO_SCHEME_INT, &v, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; + +	while (v > 0) { +		if (!list) +			return ao_scheme_error(AO_SCHEME_INVALID, "%v: ran off end", _ao_scheme_atom_list2dtail); +		if (!ao_scheme_is_cons(list)) +			return ao_scheme_error(AO_SCHEME_INVALID, "%v: invalid list", _ao_scheme_atom_list2dtail); +		list = ao_scheme_poly_cons(list)->cdr; +		v--; +	} +	return list; +} + +ao_poly +ao_scheme_do_pairp(struct ao_scheme_cons *cons) +{ +	ao_poly val; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_pair3f, cons, +				  AO_SCHEME_POLY, &val, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	if (ao_scheme_is_pair(val)) +		return _ao_scheme_bool_true; +	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 val; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_pair3f, cons, +				  AO_SCHEME_POLY, &val, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	for (;;) { +		if (val == AO_SCHEME_NIL) +			return _ao_scheme_bool_true; +		if (!ao_scheme_is_cons(val)) +			return _ao_scheme_bool_false; +		val = ao_scheme_poly_cons(val)->cdr; +	} +} + +ao_poly +ao_scheme_do_set_car(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons	*pair; +	ao_poly			val; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_set2dcar21, cons, +				  AO_SCHEME_CONS, &pair, +				  AO_SCHEME_POLY, &val, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	pair->car = val; +	return val; +} + +ao_poly +ao_scheme_do_set_cdr(struct ao_scheme_cons *cons) +{ +	struct ao_scheme_cons	*pair; +	ao_poly			val; + +	if (!ao_scheme_parse_args(_ao_scheme_atom_set2dcar21, cons, +				  AO_SCHEME_CONS, &pair, +				  AO_SCHEME_POLY, &val, +				  AO_SCHEME_ARG_END)) +		return AO_SCHEME_NIL; +	pair->cdr = val; +	return val; +} + | 
