diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-30 11:33:15 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-30 11:33:15 +0200 |
commit | 995f138c293a3db430ced10c688d07f0acf8baa8 (patch) | |
tree | 2f3c59bfd346ab28ead38c110e3af2c1c212984a | |
parent | af3f2ebc42bf9dc64fc581b9f8f79e98895cb417 (diff) | |
download | bdl-995f138c293a3db430ced10c688d07f0acf8baa8.tar.gz bdl-995f138c293a3db430ced10c688d07f0acf8baa8.zip |
Prepare for scope check
-rw-r--r-- | src/parser.c | 57 | ||||
-rwxr-xr-x | src/parser.h | 5 |
2 files changed, 48 insertions, 14 deletions
diff --git a/src/parser.c b/src/parser.c index e16fc4a..2429f68 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -3,7 +3,13 @@ | |||
3 | 3 | ||
4 | static Object **objects = NULL; | 4 | static Object **objects = NULL; |
5 | static Root *roots = NULL; | 5 | static Root *roots = NULL; |
6 | static Environment **environments = NULL; | ||
6 | 7 | ||
8 | static char *builtins [] = { | ||
9 | "+", "-", "*", "/", "%", | ||
10 | "=", "<", ">", "<=", ">=", | ||
11 | "not", "and", "or", | ||
12 | }; | ||
7 | 13 | ||
8 | uint64_t | 14 | uint64_t |
9 | symbol_hash(const HashTable *table, void *key) { | 15 | symbol_hash(const HashTable *table, void *key) { |
@@ -382,9 +388,16 @@ parse_tree(Parser *parser, Errors *errors) { | |||
382 | return NULL; | 388 | return NULL; |
383 | } | 389 | } |
384 | 390 | ||
391 | void | ||
392 | scope_check(Environment *env) { | ||
393 | // STUB | ||
394 | } | ||
395 | |||
385 | Root * | 396 | Root * |
386 | parse(Token *tokens, Errors *errors) { | 397 | parse(Token *tokens, Errors *errors) { |
387 | array_init(roots, 0); | 398 | array_init(roots, 0); |
399 | array_init(objects, 0); | ||
400 | array_init(environments, 0); | ||
388 | Parser parser = { | 401 | Parser parser = { |
389 | .tokens = tokens, | 402 | .tokens = tokens, |
390 | .current = 0, | 403 | .current = 0, |
@@ -400,27 +413,39 @@ parse(Token *tokens, Errors *errors) { | |||
400 | array_push(roots, root); | 413 | array_push(roots, root); |
401 | } | 414 | } |
402 | 415 | ||
403 | // TEST INSERTION/LOOKUP. | 416 | // Prepare global environment of builtin functions. |
404 | HashTable *table = ht_init(symbol_hash, object_equal); | 417 | Environment *global_env = env_alloc(NULL); |
405 | ht_insert(table, &roots[0][0], &roots[1][0]); | 418 | size_t n_builtins = sizeof(builtins) / sizeof(char*); |
406 | ht_insert(table, &roots[2][0], &roots[3][0]); | 419 | for (size_t i = 0; i < n_builtins; i++) { |
407 | Object *val = ht_lookup(table, &roots[2][0]); | 420 | // Prepare builtin symbol. |
408 | object_display(val); | 421 | char *str = builtins[i]; |
409 | val = ht_lookup(table, &roots[0][0]); | 422 | size_t str_n = strlen(str); |
410 | object_display(val); | 423 | Object *symbol = object_alloc((Token){0}, OBJ_TYPE_SYMBOL); |
411 | ht_free(table); | 424 | array_init(symbol->text, str_n); |
425 | array_insert(symbol->text, str, str_n); | ||
426 | |||
427 | // Insert in global table. | ||
428 | ht_insert(global_env->table, symbol, symbol); | ||
429 | } | ||
412 | 430 | ||
413 | // Perform semantic analysis. | 431 | // Perform semantic analysis. |
432 | scope_check(global_env); | ||
414 | // TODO: Check that symbols are defined before usage. | 433 | // TODO: Check that symbols are defined before usage. |
415 | // TODO: Remove unnecessary statements. | 434 | // TODO: Remove unnecessary statements. |
416 | return roots; | 435 | return roots; |
417 | } | 436 | } |
418 | 437 | ||
438 | Environment * | ||
439 | env_alloc(Environment *parent) { | ||
440 | Environment *env = malloc(sizeof(Environment)); | ||
441 | env->table = ht_init(symbol_hash, (EqFunc*)object_equal); | ||
442 | env->parent = parent; | ||
443 | array_push(environments, env); | ||
444 | return env; | ||
445 | } | ||
446 | |||
419 | Object * | 447 | Object * |
420 | object_alloc(Token tok, ObjectType type) { | 448 | object_alloc(Token tok, ObjectType type) { |
421 | if (objects == NULL) { | ||
422 | array_init(objects, 0); | ||
423 | } | ||
424 | Object *node = malloc(sizeof(Object)); | 449 | Object *node = malloc(sizeof(Object)); |
425 | node->line = tok.line; | 450 | node->line = tok.line; |
426 | node->col = tok.col; | 451 | node->col = tok.col; |
@@ -452,6 +477,14 @@ free_objects(void) { | |||
452 | } | 477 | } |
453 | array_free(objects); | 478 | array_free(objects); |
454 | } | 479 | } |
480 | if (environments != NULL) { | ||
481 | for (size_t i = 0; i < array_size(environments); i++) { | ||
482 | Environment *env = environments[i]; | ||
483 | ht_free(env->table); | ||
484 | free(env); | ||
485 | } | ||
486 | array_free(environments); | ||
487 | } | ||
455 | array_free(roots); | 488 | array_free(roots); |
456 | } | 489 | } |
457 | 490 | ||
diff --git a/src/parser.h b/src/parser.h index d1eddc7..dff40d8 100755 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -62,7 +62,7 @@ typedef struct Object { | |||
62 | typedef struct Environment { | 62 | typedef struct Environment { |
63 | HashTable *table; | 63 | HashTable *table; |
64 | struct Environment *parent; | 64 | struct Environment *parent; |
65 | }; | 65 | } Environment; |
66 | 66 | ||
67 | typedef struct Parser { | 67 | typedef struct Parser { |
68 | Token *tokens; | 68 | Token *tokens; |
@@ -71,7 +71,7 @@ typedef struct Parser { | |||
71 | 71 | ||
72 | typedef Object* Root; | 72 | typedef Object* Root; |
73 | 73 | ||
74 | // Mimics the functionality in the Scanner functions, but for tokens. | 74 | // Token scanner. |
75 | Token next_token(Parser *parser); | 75 | Token next_token(Parser *parser); |
76 | Token previous_token(Parser *parser); | 76 | Token previous_token(Parser *parser); |
77 | Token rewind_token(Parser *parser); | 77 | Token rewind_token(Parser *parser); |
@@ -95,6 +95,7 @@ void object_display(Object *obj); | |||
95 | bool object_equal(Object *a, Object *b); | 95 | bool object_equal(Object *a, Object *b); |
96 | 96 | ||
97 | // Manage resources. | 97 | // Manage resources. |
98 | Environment * env_alloc(Environment *parent); | ||
98 | Object * object_alloc(Token tok, ObjectType type); | 99 | Object * object_alloc(Token tok, ObjectType type); |
99 | void object_free(Object *node); | 100 | void object_free(Object *node); |
100 | void free_objects(void); | 101 | void free_objects(void); |