diff options
Diffstat (limited to 'read.c')
-rw-r--r-- | read.c | 35 |
1 files changed, 30 insertions, 5 deletions
@@ -1,4 +1,5 @@ #include "val.h" +#include "mem.h" #include "util.h" #include <string.h> @@ -87,12 +88,36 @@ static Val symbol(Reader *R) { } } static Val string(Reader *R) { - char *start = R->c; - int len = 0; - // todo, escape sequences - while (*R->c != '"') { len += 1; next(R); } + struct { + size_t len; + size_t cap; + char *d; + } str; + str.len = 0; + str.cap = 0; + str.d = NULL; + + #define append(c) do { ENSURE_CAP(R->S, str, char, str.cap+1); str.d[str.len++] = c; } while (0) + + while (*R->c != '"') { + if (*R->c == '\\') { + next(R); + switch (*R->c) { + case '\\': append('\\'); break; + case 't': append('\t'); break; + case 'n': append('\n'); break; + case '"': append('"'); break; + } + next(R); + } else { + append(*R->c); + next(R); + } + } + append('\0'); + #undef append next(R); - ObjString *s = objstring_copy(R->S, start, len); + ObjString *s = objstring_take(R->S, str.d, str.len-1); return en(R, "quote", VAL_OBJ(s)); } static Val list(Reader *R, char closer) { |