2 * Copyright © 2017 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"
17 #ifdef AO_SCHEME_FEATURE_VECTOR
19 static void vector_mark(void *addr)
21 struct ao_scheme_vector *vector = addr;
24 for (i = 0; i < vector->length; i++) {
25 ao_poly v = vector->vals[i];
27 ao_scheme_poly_mark(v, 1);
31 static int vector_len_size(uint16_t length)
33 return sizeof (struct ao_scheme_vector) + length * sizeof (ao_poly);
36 static int vector_size(void *addr)
38 struct ao_scheme_vector *vector = addr;
40 return vector_len_size(vector->length);
43 static void vector_move(void *addr)
45 struct ao_scheme_vector *vector = addr;
48 for (i = 0; i < vector->length; i++)
49 (void) ao_scheme_poly_move(&vector->vals[i], 1);
52 const struct ao_scheme_type ao_scheme_vector_type = {
59 struct ao_scheme_vector *
60 ao_scheme_vector_alloc(uint16_t length, ao_poly fill)
62 struct ao_scheme_vector *vector;
65 vector = ao_scheme_alloc(vector_len_size(length));
68 vector->type = AO_SCHEME_VECTOR;
69 vector->length = length;
70 for (i = 0; i < length; i++)
71 vector->vals[i] = fill;
76 struct ao_scheme_vector *vector;
81 static unsigned int vd;
84 ao_scheme_vector_write(FILE *out, ao_poly v, bool write)
86 struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);
92 for (ve = vl; ve; ve = ve->prev)
93 if (ve->vector == vector)
96 ve = malloc(sizeof (struct vl));
101 ao_scheme_print_start();
102 was_marked = ao_scheme_print_mark_addr(vector);
107 for (i = 0; i < vector->length; i++) {
109 for (j = 0; j < vd; j++)
111 ao_scheme_poly_write(out, vector->vals[i], write);
115 for (j = 0; j < vd; j++)
119 if (ao_scheme_print_stop() && !was_marked)
120 ao_scheme_print_clear_addr(vector);
128 struct ao_scheme_vector *
129 ao_scheme_list_to_vector(struct ao_scheme_cons *cons)
133 struct ao_scheme_vector *vector;
135 length = (uint16_t) ao_scheme_cons_length (cons);
136 if (ao_scheme_exception)
139 ao_scheme_cons_stash(cons);
140 vector = ao_scheme_vector_alloc(length, AO_SCHEME_NIL);
141 cons = ao_scheme_cons_fetch();
146 vector->vals[i++] = cons->car;
147 cons = ao_scheme_cons_cdr(cons);
152 struct ao_scheme_cons *
153 ao_scheme_vector_to_list(struct ao_scheme_vector *vector, int start, int end)
156 uint16_t length = vector->length;
157 struct ao_scheme_cons *cons = NULL;
165 for (i = end; i-- > start;) {
166 ao_scheme_vector_stash(vector);
167 cons = ao_scheme_cons_cons(vector->vals[i], ao_scheme_cons_poly(cons));
168 vector = ao_scheme_vector_fetch();
176 ao_scheme_do_vector(struct ao_scheme_cons *cons)
178 return ao_scheme_vector_poly(ao_scheme_list_to_vector(cons));
182 ao_scheme_do_make_vector(struct ao_scheme_cons *cons)
187 if (!ao_scheme_parse_args(_ao_scheme_atom_make2dvector, cons,
189 AO_SCHEME_POLY|AO_SCHEME_ARG_OPTIONAL, _ao_scheme_bool_false, &val,
191 return AO_SCHEME_NIL;
192 return ao_scheme_vector_poly(ao_scheme_vector_alloc(len, val));
196 ao_scheme_check_vector(ao_poly proc, struct ao_scheme_vector *vector, int32_t offset)
198 if (offset < 0 || vector->length <= offset) {
199 (void) ao_scheme_error(AO_SCHEME_INVALID, "%v: vector index %d out of range (max %d)",
201 offset, vector->length);
208 ao_scheme_do_vector_ref(struct ao_scheme_cons *cons)
210 struct ao_scheme_vector *vector;
213 if (!ao_scheme_parse_args(_ao_scheme_atom_vector2dref, cons,
214 AO_SCHEME_VECTOR, &vector,
215 AO_SCHEME_INT, &offset,
217 return AO_SCHEME_NIL;
218 if (!ao_scheme_check_vector(_ao_scheme_atom_vector2dref, vector, offset))
219 return AO_SCHEME_NIL;
220 return vector->vals[offset];
224 ao_scheme_do_vector_set(struct ao_scheme_cons *cons)
226 struct ao_scheme_vector *vector;
230 if (!ao_scheme_parse_args(_ao_scheme_atom_vector2dset21, cons,
231 AO_SCHEME_VECTOR, &vector,
232 AO_SCHEME_INT, &offset,
233 AO_SCHEME_POLY, &val,
235 return AO_SCHEME_NIL;
236 if (!ao_scheme_check_vector(_ao_scheme_atom_vector2dset21, vector, offset))
237 return AO_SCHEME_NIL;
238 vector->vals[offset] = val;
243 ao_scheme_do_list_to_vector(struct ao_scheme_cons *cons)
245 struct ao_scheme_cons *pair;
247 if (!ao_scheme_parse_args(_ao_scheme_atom_list2d3evector, cons,
248 AO_SCHEME_CONS|AO_SCHEME_ARG_NIL_OK, &pair,
250 return AO_SCHEME_NIL;
251 return ao_scheme_vector_poly(ao_scheme_list_to_vector(pair));
255 ao_scheme_do_vector_to_list(struct ao_scheme_cons *cons)
257 struct ao_scheme_vector *vector;
260 if (!ao_scheme_parse_args(_ao_scheme_atom_vector2d3elist, cons,
261 AO_SCHEME_VECTOR, &vector,
262 AO_SCHEME_INT|AO_SCHEME_ARG_OPTIONAL, ao_scheme_int_poly(0), &start,
263 AO_SCHEME_INT|AO_SCHEME_ARG_OPTIONAL, ao_scheme_int_poly(-1), &end,
265 return AO_SCHEME_NIL;
267 end = vector->length;
268 return ao_scheme_cons_poly(ao_scheme_vector_to_list(vector, start, end));
272 ao_scheme_do_vector_length(struct ao_scheme_cons *cons)
274 struct ao_scheme_vector *vector;
276 if (!ao_scheme_parse_args(_ao_scheme_atom_vector2d3elist, cons,
277 AO_SCHEME_VECTOR, &vector,
279 return AO_SCHEME_NIL;
280 return ao_scheme_integer_poly(vector->length);
284 ao_scheme_do_vectorp(struct ao_scheme_cons *cons)
286 return ao_scheme_do_typep(_ao_scheme_atom_vector3f, AO_SCHEME_VECTOR, cons);
289 #endif /* AO_SCHEME_FEATURE_VECTOR */