diff options
author | ubq323 <ubq323@ubq323.website> | 2024-08-04 13:05:47 +0100 |
---|---|---|
committer | ubq323 <ubq323@ubq323.website> | 2024-08-04 13:05:47 +0100 |
commit | 000e8ca43f4968412ed5c8fc514bb6caa3e5c450 (patch) | |
tree | e82eddb3cb54f75f8468e9a80a17e8b14857aa45 /read.c | |
parent | 1f257ac91ef3813c563203eacb5320b210fc1aa7 (diff) |
new reader
Diffstat (limited to 'read.c')
-rw-r--r-- | read.c | 98 |
1 files changed, 98 insertions, 0 deletions
@@ -0,0 +1,98 @@ +#include "val.h" +#include "util.h" + +#include <string.h> + +typedef struct _reader { + char *c; + State *S; +} Reader; + + +static void next(Reader *R) { CHECK(*R->c != '\0',"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) { + switch(x) { + case '(': case ')': case '[': case ']': case '\'': case '"': + return true; break; + default: return false; break; + } +} +static bool is_normal(char x) { + return !(is_ws(x) || is_special(x)); +} +static void skipws(Reader *R) { while (is_ws(*R->c)) next(R); } + +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))) + +static Val expr(Reader *R) { + skipws(R); + switch (*R->c) { + case '"': + next(R); return string(R); + break; + case '(': + next(R); return list(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); + break; + default: return symbol(R); break; + } +} +static Val symbol(Reader *R) { + char *start = R->c; + int len = 0; + bool num = true; + while (is_normal(*R->c)) { num &= is_num(*R->c); len += 1; next(R); } + 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); + } +} +static Val string(Reader *R) { + char *start = R->c; + int len = 0; + // todo, escape sequences + 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); +} +static Val list(Reader *R, char closer) { + ObjArr *a = objarr_new(R->S); + while (true) { + skipws(R); + if (*R->c == closer) { + next(R); + return VAL_OBJ(a); + } + objarr_append(R->S, a, expr(R)); + } +} + + +Val read_expr(State *S, char *str) { + Reader r = (Reader){.S=S, .c=str}; + return expr(&r); +} + |