commit 3da3eac

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