summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/read.c b/read.c
index 5b3f43e..26dcfd5 100644
--- a/read.c
+++ b/read.c
@@ -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) {