diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-29 22:00:40 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-29 22:00:40 +0200 |
commit | fbddf5e0c46778c1e403389ba557ef036b7b0fb5 (patch) | |
tree | 01aa089934d1b49fe515fe86fffca01c471c69e9 | |
parent | 95709acb7f166b21f562ef3fcf8ba7cb5890d28a (diff) | |
download | bdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.tar.gz bdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.zip |
Revert "Deduplicate string/symbols text for fast equality checks"
This reverts commit 95709acb7f166b21f562ef3fcf8ba7cb5890d28a.
-rwxr-xr-x | src/main.c | 6 | ||||
-rw-r--r-- | src/parser.c | 103 | ||||
-rwxr-xr-x | src/parser.h | 24 |
3 files changed, 21 insertions, 112 deletions
@@ -32,10 +32,10 @@ process_source(const StringView *source, const char *file_name) { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | // Parser. | 34 | // Parser. |
35 | ParserResults pr = parse(tokens, &errors); | 35 | Root *roots = parse(tokens, &errors); |
36 | if (errors.n != 0) { | 36 | if (errors.n != 0) { |
37 | report_errors(&errors, file_name); | 37 | report_errors(&errors, file_name); |
38 | free_parser_results(&pr); | 38 | free_roots(roots); |
39 | array_free(tokens); | 39 | array_free(tokens); |
40 | exit(EXIT_FAILURE); | 40 | exit(EXIT_FAILURE); |
41 | } | 41 | } |
@@ -46,7 +46,7 @@ process_source(const StringView *source, const char *file_name) { | |||
46 | // TODO: Compilation. | 46 | // TODO: Compilation. |
47 | 47 | ||
48 | // Free resources. | 48 | // Free resources. |
49 | free_parser_results(&pr); | 49 | free_roots(roots); |
50 | } | 50 | } |
51 | 51 | ||
52 | void | 52 | void |
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 | } | ||
diff --git a/src/parser.h b/src/parser.h index f438863..ee5febe 100755 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -37,25 +37,10 @@ typedef struct Object { | |||
37 | typedef struct Parser { | 37 | typedef struct Parser { |
38 | Token *tokens; | 38 | Token *tokens; |
39 | size_t current; | 39 | size_t current; |
40 | |||
41 | // Unique symbols and strings. | ||
42 | Object **symbols; | ||
43 | Object **strings; | ||
44 | } Parser; | 40 | } Parser; |
45 | 41 | ||
46 | typedef Object* Root; | 42 | typedef Object* Root; |
47 | 43 | ||
48 | typedef struct ParserResults { | ||
49 | // All root statements. | ||
50 | Root *roots; | ||
51 | |||
52 | // Unique symbols (tracking only first occurence). | ||
53 | Object **symbols; | ||
54 | |||
55 | // Unique strings (tracking only first occurence). | ||
56 | Object **strings; | ||
57 | } ParserResults; | ||
58 | |||
59 | // Mimics the functionality in the Scanner functions, but for tokens. | 44 | // Mimics the functionality in the Scanner functions, but for tokens. |
60 | Token next_token(Parser *parser); | 45 | Token next_token(Parser *parser); |
61 | Token previous_token(Parser *parser); | 46 | Token previous_token(Parser *parser); |
@@ -65,21 +50,20 @@ bool has_next_token(const Parser *parser); | |||
65 | 50 | ||
66 | // Parsing operations. | 51 | // Parsing operations. |
67 | Object * parse_tree(Parser *parser, Errors *errors); | 52 | Object * parse_tree(Parser *parser, Errors *errors); |
68 | Object * parse_symbol(Parser *parser, Token tok); | 53 | Object * parse_symbol(Token tok); |
69 | Object * parse_string(Parser *parser, Token tok); | 54 | Object * parse_string(Token tok); |
70 | Object * parse_bool(Token tok); | 55 | Object * parse_bool(Token tok); |
71 | Object * parse_fixnum(Token tok); | 56 | Object * parse_fixnum(Token tok); |
72 | Object * parse_list(Parser *parser, Errors *errors); | 57 | Object * parse_list(Parser *parser, Errors *errors); |
73 | ParserResults parse(Token *tokens, Errors *errors); | 58 | Root * parse(Token *tokens, Errors *errors); |
74 | 59 | ||
75 | // Object operations. | 60 | // Object operations. |
76 | void object_display(Object *obj); | 61 | void object_display(Object *obj); |
77 | bool object_equal(Object *a, Object *b); | ||
78 | 62 | ||
79 | // Manage resources. | 63 | // Manage resources. |
80 | Object * object_alloc(Token tok, ObjectType type); | 64 | Object * object_alloc(Token tok, ObjectType type); |
81 | void object_free(Object *node); | 65 | void object_free(Object *node); |
82 | void free_parser_results(ParserResults *pr); | 66 | void free_roots(Root *roots); |
83 | 67 | ||
84 | // | 68 | // |
85 | // Helper macros. | 69 | // Helper macros. |