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