summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/read.c b/read.c
index 047dfb9..b3fc5a3 100644
--- a/read.c
+++ b/read.c
@@ -4,12 +4,16 @@
#include <string.h>
typedef struct _reader {
- char *c;
State *S;
+ int len;
+ char *c;
} Reader;
-static void next(Reader *R) { CHECK(*R->c != '\0',"end of string reached"); R->c++; }
+static void next(Reader *R) {
+ if(*R->c == '\0')
+ ERROR("end of string reached");
+ R->c++; }
static bool is_ws(char x) { return x == ' ' || x == '\t' || x == '\n';}
static bool is_num(char x) { return '0' <= x && x <= '9'; }
static bool is_special(char x) {
@@ -28,7 +32,14 @@ static Val symbol(Reader *R);
static Val string(Reader *R);
static Val list(Reader *R, char closer);
-#define STR(S, s) (VAL_OBJ(objstring_copy_cstr(S, s)))
+// en("quote", x) -> (quote x) etc
+// i guess in the good universe this is just cons or whatver
+static Val en(Reader *R, char *sym, Val v) {
+ ObjArr *a = objarr_new(R->S);
+ objarr_append(R->S, a, VAL_OBJ(objstring_copy_cstr(R->S, sym)));
+ objarr_append(R->S, a, v);
+ return VAL_OBJ(a);
+}
static Val expr(Reader *R) {
skipws(R);
@@ -41,9 +52,11 @@ static Val expr(Reader *R) {
break;
case '[':
next(R);
- ObjArr *a = AS_ARR(list(R, ']'));
- objarr_insert(R->S, a, 0, STR(R->S, "arr"));
- return VAL_OBJ(a);
+ return en(R, "arrlit", list(R, ']'));
+ break;
+ case '\'':
+ next(R);
+ return en(R, "quote", expr(R));
break;
default: return symbol(R); break;
}
@@ -53,17 +66,24 @@ static Val symbol(Reader *R) {
int len = 0;
bool num = true;
while (is_normal(*R->c)) { num &= is_num(*R->c); len += 1; next(R); }
+
+ // i LOVE 0-terminated strings
+ char *tmp = malloc(len+1);
+ memcpy(tmp, start, len);
+ tmp[len] = 0;
+
if (num) {
- // c moment
- char *tmp = malloc(len+1);
- memcpy(tmp, start, len);
- tmp[len] = 0;
int x = atoi(tmp);
free(tmp);
return VAL_NUM((double)x);
} else {
- ObjString *o = objstring_copy(R->S, start, len);
- return VAL_OBJ(o);
+ Val v;
+ if (0 == strcmp(tmp, "nil")) v = VAL_NIL;
+ else if (0 == strcmp(tmp, "true")) v = VAL_TRUE;
+ else if (0 == strcmp(tmp, "false")) v = VAL_FALSE;
+ else v = VAL_OBJ(objstring_copy(R->S, start, len));
+ free(tmp);
+ return v;
}
}
static Val string(Reader *R) {
@@ -73,17 +93,14 @@ static Val string(Reader *R) {
while (*R->c != '"') { len += 1; next(R); }
next(R);
ObjString *s = objstring_copy(R->S, start, len);
- ObjArr *a = objarr_new(R->S);
- objarr_append(R->S, a, STR(R->S, "quote"));
- objarr_append(R->S, a, VAL_OBJ(s));
- return VAL_OBJ(a);
+ return en(R, "quote", VAL_OBJ(s));
}
static Val list(Reader *R, char closer) {
ObjArr *a = objarr_new(R->S);
while (true) {
skipws(R);
if (*R->c == closer) {
- next(R);
+ if (closer != '\0') next(R);
return VAL_OBJ(a);
}
objarr_append(R->S, a, expr(R));
@@ -91,8 +108,12 @@ static Val list(Reader *R, char closer) {
}
+// both need null terminated strings
Val read_expr(State *S, char *str) {
Reader r = (Reader){.S=S, .c=str};
return expr(&r);
}
-
+ObjArr *read_exprs(State *S, char *str) {
+ Reader r = (Reader){.S=S, .c=str};
+ return AS_ARR(list(&r, '\0'));
+}