aboutsummaryrefslogtreecommitdiffstats
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
parent95709acb7f166b21f562ef3fcf8ba7cb5890d28a (diff)
downloadbdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.tar.gz
bdl-fbddf5e0c46778c1e403389ba557ef036b7b0fb5.zip
Revert "Deduplicate string/symbols text for fast equality checks"
This reverts commit 95709acb7f166b21f562ef3fcf8ba7cb5890d28a.
-rwxr-xr-xsrc/main.c6
-rw-r--r--src/parser.c103
-rwxr-xr-xsrc/parser.h24
3 files changed, 21 insertions, 112 deletions
diff --git a/src/main.c b/src/main.c
index d4fa2c2..c734916 100755
--- a/src/main.c
+++ b/src/main.c
@@ -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
52void 52void
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}
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 {
37typedef struct Parser { 37typedef 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
46typedef Object* Root; 42typedef Object* Root;
47 43
48typedef 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.
60Token next_token(Parser *parser); 45Token next_token(Parser *parser);
61Token previous_token(Parser *parser); 46Token previous_token(Parser *parser);
@@ -65,21 +50,20 @@ bool has_next_token(const Parser *parser);
65 50
66// Parsing operations. 51// Parsing operations.
67Object * parse_tree(Parser *parser, Errors *errors); 52Object * parse_tree(Parser *parser, Errors *errors);
68Object * parse_symbol(Parser *parser, Token tok); 53Object * parse_symbol(Token tok);
69Object * parse_string(Parser *parser, Token tok); 54Object * parse_string(Token tok);
70Object * parse_bool(Token tok); 55Object * parse_bool(Token tok);
71Object * parse_fixnum(Token tok); 56Object * parse_fixnum(Token tok);
72Object * parse_list(Parser *parser, Errors *errors); 57Object * parse_list(Parser *parser, Errors *errors);
73ParserResults parse(Token *tokens, Errors *errors); 58Root * parse(Token *tokens, Errors *errors);
74 59
75// Object operations. 60// Object operations.
76void object_display(Object *obj); 61void object_display(Object *obj);
77bool object_equal(Object *a, Object *b);
78 62
79// Manage resources. 63// Manage resources.
80Object * object_alloc(Token tok, ObjectType type); 64Object * object_alloc(Token tok, ObjectType type);
81void object_free(Object *node); 65void object_free(Object *node);
82void free_parser_results(ParserResults *pr); 66void free_roots(Root *roots);
83 67
84// 68//
85// Helper macros. 69// Helper macros.