commit 3da3eac
uint
·
2026-10-23 21:39:39 +0000 UTC
parent aef0e3d
Add expl_parse, expl_print
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