altos/scheme: add make-string builtin
authorKeith Packard <keithp@keithp.com>
Thu, 4 Jan 2018 10:23:40 +0000 (02:23 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 4 Jan 2018 10:23:40 +0000 (02:23 -0800)
Allocate a blank string.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/scheme/ao_scheme.h
src/scheme/ao_scheme_builtin.c
src/scheme/ao_scheme_builtin.txt
src/scheme/ao_scheme_string.c

index 34fb2e885b1b4b806a91b471c5e01cef568e1e3f..68803462841bcefb989fbb6a301e28bff380204a 100644 (file)
@@ -710,7 +710,10 @@ struct ao_scheme_string *
 ao_scheme_string_copy(struct ao_scheme_string *a);
 
 struct ao_scheme_string *
-ao_scheme_string_make(char *a);
+ao_scheme_string_new(char *a);
+
+struct ao_scheme_string *
+ao_scheme_make_string(int32_t len, char fill);
 
 struct ao_scheme_string *
 ao_scheme_atom_to_string(struct ao_scheme_atom *a);
index 0da68778eef7398164644e461d3bb3cbe93bd910..0b84a89a2b366bdb67f2cf337fa4dc2a34eac24f 100644 (file)
@@ -762,17 +762,39 @@ ao_scheme_do_string_set(struct ao_scheme_cons *cons)
        val = ao_scheme_arg_int(_ao_scheme_atom_string2dset21, cons, 2);
        if (ao_scheme_exception)
                return AO_SCHEME_NIL;
+       if (!val)
+               goto fail;
        while (*string && ref) {
                ++string;
                --ref;
        }
        if (!*string)
-               return ao_scheme_error(AO_SCHEME_INVALID, "%v: string %v ref %v invalid",
-                                      _ao_scheme_atom_string2dset21,
-                                      ao_scheme_arg(cons, 0),
-                                      ao_scheme_arg(cons, 1));
+               goto fail;
        *string = val;
        return ao_scheme_int_poly(*string);
+fail:
+       return ao_scheme_error(AO_SCHEME_INVALID, "%v: %v[%v] = %v invalid",
+                              _ao_scheme_atom_string2dset21,
+                              ao_scheme_arg(cons, 0),
+                              ao_scheme_arg(cons, 1),
+                              ao_scheme_arg(cons, 2));
+}
+
+ao_poly
+ao_scheme_do_make_string(struct ao_scheme_cons *cons)
+{
+       int32_t len;
+       char    fill;
+
+       if (!ao_scheme_check_argc(_ao_scheme_atom_make2dstring, cons, 1, 2))
+               return AO_SCHEME_NIL;
+       len = ao_scheme_arg_int(_ao_scheme_atom_make2dstring, cons, 0);
+       if (ao_scheme_exception)
+               return AO_SCHEME_NIL;
+       fill = ao_scheme_opt_arg_int(_ao_scheme_atom_make2dstring, cons, 1, ' ');
+       if (ao_scheme_exception)
+               return AO_SCHEME_NIL;
+       return ao_scheme_string_poly(ao_scheme_make_string(len, fill));
 }
 
 ao_poly
index bdadbd6ac6d3705aa3a92593a791f5e8ce8a36a6..4739f121cab359b07b2c8c5c28aa7e421e01c611 100644 (file)
@@ -63,6 +63,7 @@ all   f_lambda        string_ref      string-ref
 all    f_lambda        string_set      string-set!
 all    f_lambda        string_copy     string-copy
 all    f_lambda        string_length   string-length
+all    f_lambda        make_string     make-string
 all    f_lambda        procedurep      procedure?
 all    lambda          apply
 all    f_lambda        read_char       read-char
index dfc749663ed6b073b6756f2e837a22e5e04df845..2c636d7ae49aaba9f518de2f2eca7ecdc8a3d3d4 100644 (file)
@@ -51,6 +51,7 @@ ao_scheme_string_alloc(int len)
        if (!s)
                return NULL;
        s->type = AO_SCHEME_STRING;
+       s->val[len] = '\0';
        return s;
 }
 
@@ -70,7 +71,19 @@ ao_scheme_string_copy(struct ao_scheme_string *a)
 }
 
 struct ao_scheme_string *
-ao_scheme_string_make(char *a)
+ao_scheme_make_string(int32_t len, char fill)
+{
+       struct ao_scheme_string *r;
+
+       r = ao_scheme_string_alloc(len);
+       if (!r)
+               return NULL;
+       memset(r->val, fill, len);
+       return r;
+}
+
+struct ao_scheme_string *
+ao_scheme_string_new(char *a)
 {
        struct ao_scheme_string *r;
 
@@ -138,7 +151,6 @@ ao_scheme_string_pack(struct ao_scheme_cons *cons)
                        return ao_scheme_error(AO_SCHEME_INVALID, "non-int passed to pack");
                cons = ao_scheme_cons_cdr(cons);
        }
-       *rval++ = 0;
        return ao_scheme_string_poly(r);
 }
 
@@ -183,14 +195,32 @@ ao_scheme_string_write(ao_poly p, bool write)
                putchar('"');
                while ((c = *sval++)) {
                        switch (c) {
+                       case '\a':
+                               printf("\\a");
+                               break;
+                       case '\b':
+                               printf("\\b");
+                               break;
+                       case '\t':
+                               printf ("\\t");
+                               break;
                        case '\n':
                                printf ("\\n");
                                break;
                        case '\r':
                                printf ("\\r");
                                break;
-                       case '\t':
-                               printf ("\\t");
+                       case '\f':
+                               printf("\\f");
+                               break;
+                       case '\v':
+                               printf("\\v");
+                               break;
+                       case '\"':
+                               printf("\\\"");
+                               break;
+                       case '\\':
+                               printf("\\\\");
                                break;
                        default:
                                if (c < ' ')