aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-29 22:00:40 +0200
committerBad Diode <bd@badd10de.dev>2021-10-29 22:00:40 +0200
commitfbddf5e0c46778c1e403389ba557ef036b7b0fb5 (patch)
tree01aa089934d1b49fe515fe86fffca01c471c69e9 /src/parser.c
parent95709acb7f166b21f562ef3fcf8ba7cb5890d28a (diff)
downloadbdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.tar.gz
bdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.zip
Revert "Deduplicate string/symbols text for fast equality checks"
This reverts commit 95709acb7f166b21f562ef3fcf8ba7cb5890d28a.
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c103
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
54Object * 54Object *
55parse_string(Parser *parser, Token tok) { 55parse_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
77Object * 62Object *
78parse_symbol(Parser *parser, Token tok) { 63parse_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
187ParserResults 157Root *
188parse(Token *tokens, Errors *errors) { 158parse(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
212Object * 176Object *
@@ -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
233void 200void
234free_parser_results(ParserResults *pr) { 201free_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
304bool
305object_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}