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; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 #include "ao_scheme.h"
20 static void string_mark(void *addr)
25 static int string_size(void *addr)
27 struct ao_scheme_string *string = addr;
30 return strlen(string->val) + 2;
33 static void string_move(void *addr)
38 const struct ao_scheme_type ao_scheme_string_type = {
45 static struct ao_scheme_string *
46 ao_scheme_string_alloc(int len)
48 struct ao_scheme_string *s;
52 s = ao_scheme_alloc(len + 2);
55 s->type = AO_SCHEME_STRING;
60 struct ao_scheme_string *
61 ao_scheme_string_new(char *a)
63 struct ao_scheme_string *r;
65 r = ao_scheme_string_alloc(strlen(a));
72 struct ao_scheme_string *
73 ao_scheme_atom_to_string(struct ao_scheme_atom *a)
75 int alen = strlen(a->name);
76 struct ao_scheme_string *r;
78 ao_scheme_atom_stash(a);
79 r = ao_scheme_string_alloc(alen);
80 a = ao_scheme_atom_fetch();
83 strcpy(r->val, a->name);
87 struct ao_scheme_string *
88 ao_scheme_string_cat(struct ao_scheme_string *a, struct ao_scheme_string *b)
90 int alen = strlen(a->val);
91 int blen = strlen(b->val);
92 struct ao_scheme_string *r;
94 ao_scheme_string_stash(a);
95 ao_scheme_string_stash(b);
96 r = ao_scheme_string_alloc(alen + blen);
97 b = ao_scheme_string_fetch();
98 a = ao_scheme_string_fetch();
101 strcpy(r->val, a->val);
102 strcpy(r->val+alen, b->val);
107 ao_scheme_string_pack(struct ao_scheme_cons *cons)
109 struct ao_scheme_string *string;
113 len = ao_scheme_cons_length(cons);
114 ao_scheme_cons_stash(cons);
115 string = ao_scheme_string_alloc(len);
116 cons = ao_scheme_cons_fetch();
118 return AO_SCHEME_NIL;
122 ao_poly car = cons->car;
124 if (!ao_scheme_is_integer(car) || (c = ao_scheme_poly_integer(car)) == 0)
125 return ao_scheme_error(AO_SCHEME_INVALID, "%v: Invalid %v", _ao_scheme_atom_list2d3estring, car);
127 cons = ao_scheme_cons_cdr(cons);
129 return ao_scheme_string_poly(string);
133 ao_scheme_string_unpack(struct ao_scheme_string *a)
135 ao_poly cons = AO_SCHEME_NIL;
138 for (i = strlen(a->val); --i >= 0;) {
139 ao_scheme_string_stash(a);
140 cons = ao_scheme_cons(ao_scheme_int_poly(a->val[i]), cons);
141 a = ao_scheme_string_fetch();
149 ao_scheme_string_write(FILE *out, ao_poly p, bool write)
151 struct ao_scheme_string *s = ao_scheme_poly_string(p);
157 while ((c = *sval++)) {
187 if ((uint8_t) c < ' ')
188 fprintf(out, "\\%03o", (uint8_t) c);
196 while ((c = *sval++))
202 ao_scheme_do_stringp(struct ao_scheme_cons *cons)
204 return ao_scheme_do_typep(_ao_scheme_atom_string3f, AO_SCHEME_STRING, cons);
208 ao_scheme_do_list_to_string(struct ao_scheme_cons *cons)
210 struct ao_scheme_cons *list;
212 if (!ao_scheme_parse_args(_ao_scheme_atom_list2d3estring, cons,
213 AO_SCHEME_CONS, &list,
215 return AO_SCHEME_NIL;
216 return ao_scheme_string_pack(list);
220 ao_scheme_do_string_to_list(struct ao_scheme_cons *cons)
222 struct ao_scheme_string *string;
224 if (!ao_scheme_parse_args(_ao_scheme_atom_string2d3elist, cons,
225 AO_SCHEME_STRING, &string,
227 return AO_SCHEME_NIL;
228 return ao_scheme_string_unpack(string);
232 ao_scheme_string_ref(struct ao_scheme_string *string, int32_t r)
234 char *s = string->val;
243 ao_scheme_do_string_ref(struct ao_scheme_cons *cons)
245 struct ao_scheme_string *string;
249 if (!ao_scheme_parse_args(_ao_scheme_atom_string2dref, cons,
250 AO_SCHEME_STRING, &string,
253 return AO_SCHEME_NIL;
255 s = ao_scheme_string_ref(string, ref);
257 return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
258 _ao_scheme_atom_string2dref,
260 ao_scheme_arg(cons, 1));
261 return ao_scheme_integer_poly(*s);
265 ao_scheme_do_string_length(struct ao_scheme_cons *cons)
267 struct ao_scheme_string *string;
269 if (!ao_scheme_parse_args(_ao_scheme_atom_string2dlength, cons,
270 AO_SCHEME_STRING, &string,
272 return AO_SCHEME_NIL;
273 return ao_scheme_integer_poly(strlen(string->val));
277 ao_scheme_do_string_set(struct ao_scheme_cons *cons)
279 struct ao_scheme_string *string;
284 if (!ao_scheme_parse_args(_ao_scheme_atom_string2dset21, cons,
285 AO_SCHEME_STRING, &string,
289 return AO_SCHEME_NIL;
292 s = ao_scheme_string_ref(string, ref);
296 return ao_scheme_integer_poly(val);
298 return ao_scheme_error(AO_SCHEME_INVALID, "%v: %v[%v] = %v invalid",
299 _ao_scheme_atom_string2dset21,
300 ao_scheme_arg(cons, 0),
301 ao_scheme_arg(cons, 1),
302 ao_scheme_arg(cons, 2));
306 ao_scheme_do_make_string(struct ao_scheme_cons *cons)
310 struct ao_scheme_string *string;
312 if (!ao_scheme_parse_args(_ao_scheme_atom_make2dstring, cons,
314 AO_SCHEME_INT|AO_SCHEME_ARG_OPTIONAL, ao_scheme_int_poly(' '), &fill,
316 return AO_SCHEME_NIL;
318 return ao_scheme_error(AO_SCHEME_INVALID, "%v: fill 0 invalid",
319 _ao_scheme_atom_make2dstring);
320 string = ao_scheme_string_alloc(len);
322 return AO_SCHEME_NIL;
323 memset(string->val, fill, len);
324 return ao_scheme_string_poly(string);
328 ao_scheme_do_symbol_to_string(struct ao_scheme_cons *cons)
330 struct ao_scheme_atom *atom;
332 if (!ao_scheme_parse_args(_ao_scheme_atom_symbol2d3estring, cons,
333 AO_SCHEME_ATOM, &atom,
335 return AO_SCHEME_NIL;
336 return ao_scheme_string_poly(ao_scheme_atom_to_string(atom));
340 ao_scheme_do_string_to_symbol(struct ao_scheme_cons *cons)
342 struct ao_scheme_string *string;
344 if (!ao_scheme_parse_args(_ao_scheme_atom_string2d3esymbol, cons,
345 AO_SCHEME_STRING, &string,
347 return AO_SCHEME_NIL;
348 return ao_scheme_atom_poly(ao_scheme_string_to_atom(string));