diff options
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 103 |
1 files changed, 14 insertions, 89 deletions
diff --git a/src/parser.c b/src/parser.c index 3c3b1af..2d70c9d 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -52,48 +52,18 @@ parse_bool(Token tok) { | |||
52 | } | 52 | } |
53 | 53 | ||
54 | Object * | 54 | Object * |
55 | parse_string(Parser *parser, Token tok) { | 55 | parse_string(Token tok) { |
56 | Object *ret = object_alloc(tok, OBJ_TYPE_STRING); | 56 | Object *ret = object_alloc(tok, OBJ_TYPE_STRING); |
57 | array_init(ret->text, tok.value.n); | 57 | array_init(ret->text, tok.value.n); |
58 | array_insert(ret->text, tok.value.start, tok.value.n); | 58 | array_insert(ret->text, tok.value.start, tok.value.n); |
59 | |||
60 | // Check if text was already present. | ||
61 | ssize_t idx = -1; | ||
62 | for (size_t i = 0; i < array_size(parser->strings); i++) { | ||
63 | if (object_equal(ret, parser->strings[i])) { | ||
64 | idx = i; | ||
65 | break; | ||
66 | } | ||
67 | } | ||
68 | if (idx != -1) { | ||
69 | array_free(ret->text); | ||
70 | ret->text = parser->strings[idx]->text; | ||
71 | } else { | ||
72 | array_push(parser->strings, ret); | ||
73 | } | ||
74 | return ret; | 59 | return ret; |
75 | } | 60 | } |
76 | 61 | ||
77 | Object * | 62 | Object * |
78 | parse_symbol(Parser *parser, Token tok) { | 63 | parse_symbol(Token tok) { |
79 | Object *ret = object_alloc(tok, OBJ_TYPE_SYMBOL); | 64 | Object *ret = object_alloc(tok, OBJ_TYPE_SYMBOL); |
80 | array_init(ret->text, tok.value.n); | 65 | array_init(ret->text, tok.value.n); |
81 | array_insert(ret->text, tok.value.start, tok.value.n); | 66 | array_insert(ret->text, tok.value.start, tok.value.n); |
82 | |||
83 | // Check if text was already present. | ||
84 | ssize_t idx = -1; | ||
85 | for (size_t i = 0; i < array_size(parser->symbols); i++) { | ||
86 | if (object_equal(ret, parser->symbols[i])) { | ||
87 | idx = i; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | if (idx != -1) { | ||
92 | array_free(ret->text); | ||
93 | ret->text = parser->symbols[idx]->text; | ||
94 | } else { | ||
95 | array_push(parser->symbols, ret); | ||
96 | } | ||
97 | return ret; | 67 | return ret; |
98 | } | 68 | } |
99 | 69 | ||
@@ -163,10 +133,10 @@ parse_tree(Parser *parser, Errors *errors) { | |||
163 | return parse_list(parser, errors); | 133 | return parse_list(parser, errors); |
164 | } break; | 134 | } break; |
165 | case TOKEN_STRING: { | 135 | case TOKEN_STRING: { |
166 | return parse_string(parser, tok); | 136 | return parse_string(tok); |
167 | } break; | 137 | } break; |
168 | case TOKEN_SYMBOL: { | 138 | case TOKEN_SYMBOL: { |
169 | return parse_symbol(parser, tok); | 139 | return parse_symbol(tok); |
170 | } break; | 140 | } break; |
171 | case TOKEN_NIL: { | 141 | case TOKEN_NIL: { |
172 | return object_alloc(tok, OBJ_TYPE_NIL); | 142 | return object_alloc(tok, OBJ_TYPE_NIL); |
@@ -184,7 +154,7 @@ parse_tree(Parser *parser, Errors *errors) { | |||
184 | return NULL; | 154 | return NULL; |
185 | } | 155 | } |
186 | 156 | ||
187 | ParserResults | 157 | Root * |
188 | parse(Token *tokens, Errors *errors) { | 158 | parse(Token *tokens, Errors *errors) { |
189 | Root *roots = NULL; | 159 | Root *roots = NULL; |
190 | array_init(roots, 0); | 160 | array_init(roots, 0); |
@@ -192,8 +162,6 @@ parse(Token *tokens, Errors *errors) { | |||
192 | .tokens = tokens, | 162 | .tokens = tokens, |
193 | .current = 0, | 163 | .current = 0, |
194 | }; | 164 | }; |
195 | array_init(parser.symbols, 0); | ||
196 | array_init(parser.strings, 0); | ||
197 | while (has_next_token(&parser)) { | 165 | while (has_next_token(&parser)) { |
198 | Object *root = parse_tree(&parser, errors); | 166 | Object *root = parse_tree(&parser, errors); |
199 | OBJ_PRINT(root); | 167 | OBJ_PRINT(root); |
@@ -202,11 +170,7 @@ parse(Token *tokens, Errors *errors) { | |||
202 | } | 170 | } |
203 | array_push(roots, root); | 171 | array_push(roots, root); |
204 | } | 172 | } |
205 | return (ParserResults){ | 173 | return roots; |
206 | .roots = roots, | ||
207 | .symbols = parser.symbols, | ||
208 | .strings = parser.strings, | ||
209 | }; | ||
210 | } | 174 | } |
211 | 175 | ||
212 | Object * | 176 | Object * |
@@ -223,6 +187,9 @@ object_free(Object *node) { | |||
223 | if (node == NULL) { | 187 | if (node == NULL) { |
224 | return; | 188 | return; |
225 | } | 189 | } |
190 | if (IS_STRING(node) || IS_SYMBOL(node)) { | ||
191 | array_free(node->text); | ||
192 | } | ||
226 | if (IS_PAIR(node)) { | 193 | if (IS_PAIR(node)) { |
227 | object_free(node->car); | 194 | object_free(node->car); |
228 | object_free(node->cdr); | 195 | object_free(node->cdr); |
@@ -231,24 +198,12 @@ object_free(Object *node) { | |||
231 | } | 198 | } |
232 | 199 | ||
233 | void | 200 | void |
234 | free_parser_results(ParserResults *pr) { | 201 | free_roots(Root *roots) { |
235 | if (pr->symbols != NULL) { | 202 | if (roots != NULL) { |
236 | for (size_t i = 0; i < array_size(pr->symbols); i++) { | 203 | for (size_t i = 0; i < array_size(roots); i++) { |
237 | array_free(pr->symbols[i]->text); | 204 | object_free(roots[i]); |
238 | } | 205 | } |
239 | array_free(pr->symbols); | 206 | array_free(roots); |
240 | } | ||
241 | if (pr->strings != NULL) { | ||
242 | for (size_t i = 0; i < array_size(pr->strings); i++) { | ||
243 | array_free(pr->strings[i]->text); | ||
244 | } | ||
245 | array_free(pr->strings); | ||
246 | } | ||
247 | if (pr->roots != NULL) { | ||
248 | for (size_t i = 0; i < array_size(pr->roots); i++) { | ||
249 | object_free(pr->roots[i]); | ||
250 | } | ||
251 | array_free(pr->roots); | ||
252 | } | 207 | } |
253 | } | 208 | } |
254 | 209 | ||
@@ -300,33 +255,3 @@ object_display(Object *obj) { | |||
300 | } | 255 | } |
301 | return; | 256 | return; |
302 | } | 257 | } |
303 | |||
304 | bool | ||
305 | object_equal(Object *a, Object *b) { | ||
306 | if (a->type != b->type) { | ||
307 | return false; | ||
308 | } | ||
309 | switch (a->type) { | ||
310 | case OBJ_TYPE_TRUE: | ||
311 | case OBJ_TYPE_FALSE: { | ||
312 | return true; | ||
313 | } break; | ||
314 | case OBJ_TYPE_FIXNUM: { | ||
315 | return a->fixnum == b->fixnum; | ||
316 | } break; | ||
317 | case OBJ_TYPE_SYMBOL: | ||
318 | case OBJ_TYPE_STRING: { | ||
319 | if (array_size(a->text) != array_size(b->text)) { | ||
320 | return false; | ||
321 | } | ||
322 | for (size_t i = 0; i < array_size(a->text); i++) { | ||
323 | if (a->text[i] != b->text[i]) { | ||
324 | return false; | ||
325 | } | ||
326 | } | ||
327 | return true; | ||
328 | } break; | ||
329 | default: break; | ||
330 | } | ||
331 | return a == b; | ||
332 | } | ||