altos/scheme: Rework display/write code
[fw/altos] / src / scheme / ao_scheme_string.c
index e25306cbea087d6a0964c346266ce552472d0c76..b00ef276815be1b04f6476603b1924ce56a1eaa4 100644 (file)
@@ -24,9 +24,10 @@ static void string_mark(void *addr)
 
 static int string_size(void *addr)
 {
+       struct ao_scheme_string *string = addr;
        if (!addr)
                return 0;
-       return strlen(addr) + 1;
+       return strlen(string->val) + 2;
 }
 
 static void string_move(void *addr)
@@ -41,69 +42,119 @@ const struct ao_scheme_type ao_scheme_string_type = {
        .name = "string",
 };
 
-char *
-ao_scheme_string_copy(char *a)
+static struct ao_scheme_string *
+ao_scheme_string_alloc(int len)
 {
-       int     alen = strlen(a);
+       struct ao_scheme_string *s;
+
+       s = ao_scheme_alloc(len + 2);
+       if (!s)
+               return NULL;
+       s->type = AO_SCHEME_STRING;
+       return s;
+}
+
+struct ao_scheme_string *
+ao_scheme_string_copy(struct ao_scheme_string *a)
+{
+       int                     alen = strlen(a->val);
+       struct ao_scheme_string *r;
 
        ao_scheme_string_stash(0, a);
-       char    *r = ao_scheme_alloc(alen + 1);
+       r = ao_scheme_string_alloc(alen);
        a = ao_scheme_string_fetch(0);
        if (!r)
                return NULL;
-       strcpy(r, a);
+       strcpy(r->val, a->val);
+       return r;
+}
+
+struct ao_scheme_string *
+ao_scheme_string_make(char *a)
+{
+       struct ao_scheme_string *r;
+
+       r = ao_scheme_string_alloc(strlen(a));
+       if (!r)
+               return NULL;
+       strcpy(r->val, a);
+       return r;
+}
+
+struct ao_scheme_string *
+ao_scheme_atom_to_string(struct ao_scheme_atom *a)
+{
+       int                     alen = strlen(a->name);
+       struct ao_scheme_string *r;
+
+       ao_scheme_poly_stash(0, ao_scheme_atom_poly(a));
+       r = ao_scheme_string_alloc(alen);
+       a = ao_scheme_poly_atom(ao_scheme_poly_fetch(0));
+       if (!r)
+               return NULL;
+       strcpy(r->val, a->name);
        return r;
 }
 
-char *
-ao_scheme_string_cat(char *a, char *b)
+struct ao_scheme_string *
+ao_scheme_string_cat(struct ao_scheme_string *a, struct ao_scheme_string *b)
 {
-       int     alen = strlen(a);
-       int     blen = strlen(b);
+       int                             alen = strlen(a->val);
+       int                             blen = strlen(b->val);
+       struct ao_scheme_string         *r;
 
        ao_scheme_string_stash(0, a);
        ao_scheme_string_stash(1, b);
-       char    *r = ao_scheme_alloc(alen + blen + 1);
+       r = ao_scheme_string_alloc(alen + blen);
        a = ao_scheme_string_fetch(0);
        b = ao_scheme_string_fetch(1);
        if (!r)
                return NULL;
-       strcpy(r, a);
-       strcpy(r+alen, b);
+       strcpy(r->val, a->val);
+       strcpy(r->val+alen, b->val);
        return r;
 }
 
 ao_poly
 ao_scheme_string_pack(struct ao_scheme_cons *cons)
 {
-       int     len = ao_scheme_cons_length(cons);
+       struct ao_scheme_string *r;
+       char                    *rval;
+       int                     len;
+
+       len = ao_scheme_cons_length(cons);
        ao_scheme_cons_stash(0, cons);
-       char    *r = ao_scheme_alloc(len + 1);
+       r = ao_scheme_string_alloc(len);
        cons = ao_scheme_cons_fetch(0);
-       char    *s = r;
+       if (!r)
+               return AO_SCHEME_NIL;
+       rval = r->val;
 
        while (cons) {
-               if (!ao_scheme_integer_typep(ao_scheme_poly_type(cons->car)))
+               bool fail = false;
+               ao_poly car = cons->car;
+               *rval++ = ao_scheme_poly_integer(car, &fail);
+               if (fail)
                        return ao_scheme_error(AO_SCHEME_INVALID, "non-int passed to pack");
-               *s++ = ao_scheme_poly_integer(cons->car);
-               cons = ao_scheme_poly_cons(cons->cdr);
+               cons = ao_scheme_cons_cdr(cons);
        }
-       *s++ = 0;
+       *rval++ = 0;
        return ao_scheme_string_poly(r);
 }
 
 ao_poly
-ao_scheme_string_unpack(char *a)
+ao_scheme_string_unpack(struct ao_scheme_string *a)
 {
        struct ao_scheme_cons   *cons = NULL, *tail = NULL;
        int                     c;
        int                     i;
 
-       for (i = 0; (c = a[i]); i++) {
+       for (i = 0; (c = a->val[i]); i++) {
+               struct ao_scheme_cons   *n;
                ao_scheme_cons_stash(0, cons);
                ao_scheme_cons_stash(1, tail);
                ao_scheme_string_stash(0, a);
-               struct ao_scheme_cons   *n = ao_scheme_cons_cons(ao_scheme_int_poly(c), AO_SCHEME_NIL);
+               n = ao_scheme_cons_cons(ao_scheme_int_poly(c), AO_SCHEME_NIL);
                a = ao_scheme_string_fetch(0);
                cons = ao_scheme_cons_fetch(0);
                tail = ao_scheme_cons_fetch(1);
@@ -122,40 +173,36 @@ ao_scheme_string_unpack(char *a)
 }
 
 void
-ao_scheme_string_write(ao_poly p)
+ao_scheme_string_write(ao_poly p, bool write)
 {
-       char    *s = ao_scheme_poly_string(p);
-       char    c;
-
-       putchar('"');
-       while ((c = *s++)) {
-               switch (c) {
-               case '\n':
-                       printf ("\\n");
-                       break;
-               case '\r':
-                       printf ("\\r");
-                       break;
-               case '\t':
-                       printf ("\\t");
-                       break;
-               default:
-                       if (c < ' ')
-                               printf("\\%03o", c);
-                       else
-                               putchar(c);
-                       break;
+       struct ao_scheme_string *s = ao_scheme_poly_string(p);
+       char                    *sval = s->val;
+       char                    c;
+
+       if (write) {
+               putchar('"');
+               while ((c = *sval++)) {
+                       switch (c) {
+                       case '\n':
+                               printf ("\\n");
+                               break;
+                       case '\r':
+                               printf ("\\r");
+                               break;
+                       case '\t':
+                               printf ("\\t");
+                               break;
+                       default:
+                               if (c < ' ')
+                                       printf("\\%03o", c);
+                               else
+                                       putchar(c);
+                               break;
+                       }
                }
+               putchar('"');
+       } else {
+               while ((c = *sval++))
+                       putchar(c);
        }
-       putchar('"');
-}
-
-void
-ao_scheme_string_display(ao_poly p)
-{
-       char    *s = ao_scheme_poly_string(p);
-       char    c;
-
-       while ((c = *s++))
-               putchar(c);
 }