From 995f138c293a3db430ced10c688d07f0acf8baa8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 30 Oct 2021 11:33:15 +0200 Subject: Prepare for scope check --- src/parser.c | 57 +++++++++++++++++++++++++++++++++++++++++++++------------ src/parser.h | 5 +++-- 2 files changed, 48 insertions(+), 14 deletions(-) (limited to 'src') 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 @@ static Object **objects = NULL; static Root *roots = NULL; +static Environment **environments = NULL; +static char *builtins [] = { + "+", "-", "*", "/", "%", + "=", "<", ">", "<=", ">=", + "not", "and", "or", +}; uint64_t symbol_hash(const HashTable *table, void *key) { @@ -382,9 +388,16 @@ parse_tree(Parser *parser, Errors *errors) { return NULL; } +void +scope_check(Environment *env) { + // STUB +} + Root * parse(Token *tokens, Errors *errors) { array_init(roots, 0); + array_init(objects, 0); + array_init(environments, 0); Parser parser = { .tokens = tokens, .current = 0, @@ -400,27 +413,39 @@ parse(Token *tokens, Errors *errors) { array_push(roots, root); } - // TEST INSERTION/LOOKUP. - HashTable *table = ht_init(symbol_hash, object_equal); - ht_insert(table, &roots[0][0], &roots[1][0]); - ht_insert(table, &roots[2][0], &roots[3][0]); - Object *val = ht_lookup(table, &roots[2][0]); - object_display(val); - val = ht_lookup(table, &roots[0][0]); - object_display(val); - ht_free(table); + // Prepare global environment of builtin functions. + Environment *global_env = env_alloc(NULL); + size_t n_builtins = sizeof(builtins) / sizeof(char*); + for (size_t i = 0; i < n_builtins; i++) { + // Prepare builtin symbol. + char *str = builtins[i]; + size_t str_n = strlen(str); + Object *symbol = object_alloc((Token){0}, OBJ_TYPE_SYMBOL); + array_init(symbol->text, str_n); + array_insert(symbol->text, str, str_n); + + // Insert in global table. + ht_insert(global_env->table, symbol, symbol); + } // Perform semantic analysis. + scope_check(global_env); // TODO: Check that symbols are defined before usage. // TODO: Remove unnecessary statements. return roots; } +Environment * +env_alloc(Environment *parent) { + Environment *env = malloc(sizeof(Environment)); + env->table = ht_init(symbol_hash, (EqFunc*)object_equal); + env->parent = parent; + array_push(environments, env); + return env; +} + Object * object_alloc(Token tok, ObjectType type) { - if (objects == NULL) { - array_init(objects, 0); - } Object *node = malloc(sizeof(Object)); node->line = tok.line; node->col = tok.col; @@ -452,6 +477,14 @@ free_objects(void) { } array_free(objects); } + if (environments != NULL) { + for (size_t i = 0; i < array_size(environments); i++) { + Environment *env = environments[i]; + ht_free(env->table); + free(env); + } + array_free(environments); + } array_free(roots); } 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 { typedef struct Environment { HashTable *table; struct Environment *parent; -}; +} Environment; typedef struct Parser { Token *tokens; @@ -71,7 +71,7 @@ typedef struct Parser { typedef Object* Root; -// Mimics the functionality in the Scanner functions, but for tokens. +// Token scanner. Token next_token(Parser *parser); Token previous_token(Parser *parser); Token rewind_token(Parser *parser); @@ -95,6 +95,7 @@ void object_display(Object *obj); bool object_equal(Object *a, Object *b); // Manage resources. +Environment * env_alloc(Environment *parent); Object * object_alloc(Token tok, ObjectType type); void object_free(Object *node); void free_objects(void); -- cgit v1.2.1