1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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);
}
|