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 | |
parent | 1f257ac91ef3813c563203eacb5320b210fc1aa7 (diff) |
new reader
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | com.c | 1 | ||||
-rw-r--r-- | next | 5 | ||||
-rw-r--r-- | read.c | 98 | ||||
-rw-r--r-- | read.h | 8 | ||||
-rw-r--r-- | util.h | 1 | ||||
-rw-r--r-- | val.c | 14 | ||||
-rw-r--r-- | val.h | 1 |
8 files changed, 131 insertions, 3 deletions
@@ -1,6 +1,6 @@ -CS=ast.c com.c dis.c ht.c lib.c mem.c prs.c state.c val.c vm.c -HS=ast.h chunk.h com.h dis.h ht.h lib.h mem.h prs.h state.h util.h val.h vm.h -CFLAGS=$(EXTRA_CFLAGS) -g -O3 -lm -Wall -Wpedantic -Werror=implicit-function-declaration +CS=ast.c com.c dis.c ht.c lib.c mem.c prs.c read.c state.c val.c vm.c +HS=ast.h chunk.h com.h dis.h ht.h lib.h mem.h prs.h read.h state.h util.h val.h vm.h +CFLAGS=$(EXTRA_CFLAGS) -g -lm -Wall -Wpedantic -Werror=implicit-function-declaration bth: $(CS) $(HS) Makefile $(CC) $(CFLAGS) -o bth $(CS) @@ -10,6 +10,7 @@ #include "util.h" #include "prs.h" #include "lib.h" +#include "read.h" #define BYTECODE(C) (C->ch->bc) @@ -0,0 +1,5 @@ +separate strings and symbols +quoting +ht literals +new parser +macros @@ -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); +} + @@ -0,0 +1,8 @@ +#ifndef _read_h +#define _read_h + +#include "state.h" +#include "val.h" +Val read_expr(State *S, char *str); + +#endif @@ -2,6 +2,7 @@ #define _util_h #include <stdio.h> +#include <stdlib.h> #define CHECK(cond, ...) do { if (!(cond)) { fprintf(stderr, __VA_ARGS__); putchar('\n'); exit(1); } } while(0) #define ERROR(...) CHECK(false, __VA_ARGS__) @@ -84,6 +84,20 @@ void objarr_put(State *S, ObjArr *arr, size_t ix, Val v) { arr->d[ix] = v; } } +void objarr_insert(State *S, ObjArr *arr, size_t ix, Val v) { + CHECK(ix <= arr->len, "array index out of bounds"); + if (ix == arr->len) { + objarr_append(S, arr, v); + } else { + if (arr->len == arr->cap) { + size_t newsz = (arr->cap == 0 ? 8 : arr->cap * 2); + arr->d = RENEW_ARR(S, arr->d, Val, arr->cap, newsz); + arr->cap = newsz; + } + memmove(&arr->d[ix+1], &arr->d[ix], (arr->len-ix)*sizeof(Val)); + arr->d[ix] = v; + } +} static void print_val_h(Val v, int depth); void print_val(Val v) { @@ -83,6 +83,7 @@ ObjArr *objarr_new(State *S); Val objarr_get(State *S, ObjArr *arr, size_t ix); void objarr_append(State *S, ObjArr *arr, Val v); void objarr_put(State *S, ObjArr *arr, size_t ix, Val v); +void objarr_insert(State *S, ObjArr *arr, size_t ix, Val v); #define IS_NIL(x) (x.ty == TY_NIL) #define IS_NUM(x) (x.ty == TY_NUM) |