commit 04a83e0
uint
·
2026-10-23 21:51:37 +0000 UTC
parent 0fbbdab
Merge string and atom -> value, use ptr to ptr for list
1 files changed,
+37,
-71
M
expl.c
M
expl.c
+37,
-71
1@@ -6,7 +6,7 @@
2 #include "expl.h"
3
4 #define current_char(p, c) ((p)->src[(p)->pos] == (c))
5-#define advance(p) ((p)->pos++) /* XXX */
6+#define advance(p) ((p)->pos++)
7
8 typedef struct {
9 const char* src;
10@@ -14,10 +14,9 @@ typedef struct {
11 expl_error err;
12 } parser;
13
14-static expl_node* atom(parser* p);
15 static expl_node* expression(parser* p);
16 static expl_node* list(parser* p);
17-static expl_node* string(parser* p);
18+static expl_node* value(parser* p, expl_type type);
19
20 static void skipspace(parser* p);
21 static char* _strndup(const char* src, size_t len);
22@@ -25,48 +24,13 @@ static char* _strndup(const char* src, size_t len);
23 static expl_node* newnode(expl_type type);
24 static void freenode(expl_node* node);
25
26-static expl_node*
27-atom(parser* p)
28-{
29- size_t start = p->pos;
30- expl_node* node = NULL;
31-
32- while (!current_char(p, '(') &&
33- !current_char(p, ')') &&
34- !current_char(p, '"') &&
35- !current_char(p, ';') &&
36- !current_char(p, '\0') &&
37- !isspace((unsigned char)p->src[p->pos]))
38- advance(p);
39-
40- if (start == p->pos) {
41- p->err = EXPL_ERR_EXPECTED_ATOM;
42- return NULL;
43- }
44-
45- node = newnode(EXPL_ATOM);
46- if (!node) {
47- p->err = EXPL_ERR_OUT_OF_MEMORY;
48- return NULL;
49- }
50-
51- node->value = _strndup(p->src + start, p->pos - start);
52- if (!node->value) {
53- freenode(node);
54- p->err = EXPL_ERR_OUT_OF_MEMORY;
55- return NULL;
56- }
57-
58- return node;
59-}
60-
61 static expl_node*
62 expression(parser* p)
63 {
64 skipspace(p);
65 switch (p->src[p->pos]) {
66 case '"':
67- return string(p);
68+ return value(p, EXPL_STRING);
69 case '(':
70 return list(p);
71 case ')':
72@@ -74,7 +38,7 @@ expression(parser* p)
73 p->err = EXPL_ERR_UNEXPECTED_TOKEN;
74 return NULL;
75 default:
76- return atom(p);
77+ return value(p, EXPL_ATOM);
78 }
79 }
80
81@@ -82,14 +46,7 @@ static expl_node*
82 list(parser* p)
83 {
84 expl_node* node = NULL;
85- expl_node* tail = NULL;
86- expl_node* subnode = NULL;
87-
88- skipspace(p);
89- if (!current_char(p, '(')) {
90- p->err = EXPL_ERR_EXPECTED_LIST;
91- return NULL;
92- }
93+ expl_node** next = NULL;
94
95 advance(p);
96
97@@ -99,26 +56,23 @@ list(parser* p)
98 return NULL;
99 }
100
101+ next = &node->child;
102+
103 skipspace(p);
104 while (!current_char(p, ')') && !current_char(p, '\0')) {
105- subnode = expression(p);
106- if (!subnode) {
107+ *next = expression(p);
108+ if (!*next) {
109 freenode(node);
110 return NULL;
111 }
112
113- if (tail)
114- tail->next = subnode;
115- else
116- node->child = subnode;
117-
118- tail = subnode;
119+ next = &(*next)->next;
120 skipspace(p);
121 }
122
123- if (!current_char(p, ')')) {
124- freenode(node);
125+ if (current_char(p, '\0')) {
126 p->err = EXPL_ERR_EXPECTED_LIST;
127+ freenode(node);
128 return NULL;
129 }
130
131@@ -127,44 +81,56 @@ list(parser* p)
132 }
133
134 static expl_node*
135-string(parser* p)
136+value(parser* p, expl_type type)
137 {
138 expl_node* node = NULL;
139 size_t start = 0;
140
141- if (!current_char(p, '"')) {
142- p->err = EXPL_ERR_EXPECTED_STRING;
143- return NULL;
144- }
145+ if (type == EXPL_STRING)
146+ advance(p);
147
148- advance(p); /* skip opening " */
149 start = p->pos;
150
151- while (!current_char(p, '"') && !current_char(p, '\0')) {
152- if (current_char(p, '\\') && p->src[p->pos + 1])
153+ if (type == EXPL_STRING) {
154+ while (!current_char(p, '"') && !current_char(p, '\0')) {
155+ if (current_char(p, '\\') && p->src[p->pos + 1])
156+ advance(p);
157+ advance(p);
158+ }
159+
160+ if (current_char(p, '\0')) {
161+ p->err = EXPL_ERR_EXPECTED_STRING;
162+ return NULL;
163+ }
164+ }
165+ else {
166+ while (p->src[p->pos] &&
167+ !strchr("();\"", p->src[p->pos]) &&
168+ !isspace((unsigned char)p->src[p->pos]))
169 advance(p);
170- advance(p);
171 }
172
173- if (current_char(p, '\0')) {
174- p->err = EXPL_ERR_EXPECTED_STRING;
175+ if (start == p->pos && type == EXPL_ATOM) {
176+ p->err = EXPL_ERR_EXPECTED_ATOM;
177 return NULL;
178 }
179
180- node = newnode(EXPL_STRING);
181+ node = newnode(type);
182 if (!node) {
183 p->err = EXPL_ERR_OUT_OF_MEMORY;
184 return NULL;
185 }
186
187 node->value = _strndup(p->src + start, p->pos - start);
188- advance(p); /* skip closing " */
189 if (!node->value) {
190 freenode(node);
191 p->err = EXPL_ERR_OUT_OF_MEMORY;
192 return NULL;
193 }
194
195+ if (type == EXPL_STRING)
196+ advance(p);
197+
198 return node;
199 }
200