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 ao_scheme_vector_write(ao_poly v)
78 struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);
82 for (i = 0; i < vector->length; i++) {
85 if (vector->vals[i] == v)
88 ao_scheme_poly_write(vector->vals[i]);
94 ao_scheme_vector_display(ao_poly v)
96 struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);
99 for (i = 0; i < vector->length; i++) {
100 if (vector->vals[i] == v)
103 ao_scheme_poly_display(vector->vals[i]);
108 ao_scheme_vector_offset(struct ao_scheme_vector *vector, ao_poly i)
110 int32_t offset = ao_scheme_poly_integer(i);
112 if (offset == AO_SCHEME_NOT_INTEGER)
113 ao_scheme_error(AO_SCHEME_INVALID, "vector index %v not integer", i);
114 if (offset < 0 || vector->length <= offset) {
115 ao_scheme_error(AO_SCHEME_INVALID, "vector index %v out of range (max %d)",
117 offset = AO_SCHEME_NOT_INTEGER;
123 ao_scheme_vector_get(ao_poly v, ao_poly i)
125 struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);
126 int32_t offset = ao_scheme_vector_offset(vector, i);
128 if (offset == AO_SCHEME_NOT_INTEGER)
129 return AO_SCHEME_NIL;
130 return vector->vals[offset];
134 ao_scheme_vector_set(ao_poly v, ao_poly i, ao_poly p)
136 struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);
137 int32_t offset = ao_scheme_vector_offset(vector, i);
139 if (offset == AO_SCHEME_NOT_INTEGER)
140 return AO_SCHEME_NIL;
141 return vector->vals[offset] = p;
144 struct ao_scheme_vector *
145 ao_scheme_list_to_vector(struct ao_scheme_cons *cons)
149 struct ao_scheme_vector *vector;
151 length = (uint16_t) ao_scheme_cons_length (cons);
152 if (ao_scheme_exception)
155 ao_scheme_cons_stash(0, cons);
156 vector = ao_scheme_vector_alloc(length, AO_SCHEME_NIL);
157 cons = ao_scheme_cons_fetch(0);
162 vector->vals[i++] = cons->car;
163 cons = ao_scheme_cons_cdr(cons);
168 struct ao_scheme_cons *
169 ao_scheme_vector_to_list(struct ao_scheme_vector *vector)
172 uint16_t length = vector->length;
173 struct ao_scheme_cons *cons = NULL;
175 for (i = length; i-- > 0;) {
176 ao_scheme_poly_stash(2, ao_scheme_vector_poly(vector));
177 cons = ao_scheme_cons_cons(vector->vals[i], ao_scheme_cons_poly(cons));
178 vector = ao_scheme_poly_vector(ao_scheme_poly_fetch(2));
185 #endif /* AO_SCHEME_FEATURE_VECTOR */