diff options
Diffstat (limited to 'read.c')
-rw-r--r-- | read.c | 57 |
1 files changed, 39 insertions, 18 deletions
@@ -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')); +} |