From bef1e015f6db7b184b82280dac21e9fa92b7116d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind?= Date: Tue, 15 Mar 2022 22:29:45 +0100 Subject: [PATCH] Added scanning of global variables --- exercises/04/vslc/src/ir.c | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/exercises/04/vslc/src/ir.c b/exercises/04/vslc/src/ir.c index 6971119..2448e39 100644 --- a/exercises/04/vslc/src/ir.c +++ b/exercises/04/vslc/src/ir.c @@ -1,5 +1,8 @@ #include + + + // Externally visible, for the generator extern tlhash_t *global_names; extern char **string_list; @@ -14,8 +17,16 @@ static void bind_names ( symbol_t *function, node_t *root ); void create_symbol_table ( void ) { + + // Initialize string array + string_list = malloc(n_string_list * sizeof(char*)); + n_string_list = DEFAULT_STRING_LIST_SIZE; + stringc = 0; + + find_globals(); /* TODO: traverse the syntax tree and create the symbol table */ +/* // ! Example code solely to demonstrate usage of tlhash. Make sure to remove // ! or comment this out when implementing your solution. @@ -47,6 +58,7 @@ create_symbol_table ( void ) tlhash_finalize(my_table); free(my_table); free(keys); +*/ } @@ -54,6 +66,17 @@ void print_symbol_table ( void ) { /* TODO: output its contents */ + /* Get the number of symbols, size up a temporary list and fill it */ + uint64_t no_globals = tlhash_size(global_names); + symbol_t *global_list[no_globals]; + tlhash_values(global_names, (void **)&global_list ); + + /* Iterate over the temporary list, printing entries */ + for (uint64_t g = 0; g < no_globals; g++ ) + { + printf("global: %s\n", global_list[g]->name ); + + } } void @@ -62,10 +85,101 @@ destroy_symbol_table ( void ) /* TODO: release memory allocated to the symbol table */ } +void insert_symbol(tlhash_t *hash_table, symbol_t* symbol) +{ + tlhash_insert(hash_table, symbol->name, strlen(symbol->name), symbol); +} + void find_globals ( void ) { + tlhash_init(global_names = malloc(sizeof(tlhash_t)), GLOBAL_BUCKET_SIZE); /* TODO: Populate symbol table with global variables and functions */ + + uint64_t no_functions = 0; + node_t *global_list = root; + + // Check if not nullptr + if (!global_list) + return; + + symbol_t* global_symbol; + for (uint64_t global_i = 0; global_i < global_list->n_children; global_i++) + { + node_t *current_global = global_list->children[global_i]; + switch (current_global->type) + { + case VARIABLE_LIST: + + // Go through the variable list and get all the global variables + for (uint64_t var_i = 0; var_i < current_global->n_children; var_i++) + { + global_symbol = malloc(sizeof(symbol_t)); + *global_symbol = (symbol_t){ + .type = SYM_GLOBAL_VAR, + .name = current_global->children[var_i]->data, + .node = current_global->children[var_i], + .seq = 0, + .nparms = 0, + .locals = NULL + }; + insert_symbol(global_names, global_symbol); + } + break; + case FUNCTION: + node_t *function = current_global; + + // Function node allways have the same structure, + // [0] are the identifier + // [1] are the variable list, within a paramerer_list + if (!function->children[0]) + break; + + // Create the function symbol + global_symbol = malloc(sizeof(symbol_t)); + *global_symbol = (symbol_t){ + .type = SYM_FUNCTION, + .name = current_global->children[0]->data, + .node = current_global->children[0], + .seq = no_functions++, + .nparms = 0, + .locals = malloc(sizeof(tlhash_t)) + }; + + // Initialize the local variable table + tlhash_init(global_symbol->locals, LOCAL_BUCKET_SIZE); + + // Insert the pointer to the newly created symbol + insert_symbol(global_names, global_symbol); + + // If there are no parameters in function, break. + if (!current_global->children[1]->n_children) + break; + + + // Find all params and insert into hash table in global_symbol + symbol_t *param_sym; + node_t *param_list = current_global->children[1]->children[0]; + global_symbol->nparms = param_list->n_children; + + for (uint64_t param_i = 0; param_i < param_list->n_children; param_i++) + { + param_sym = malloc(sizeof(symbol_t)); + *param_sym = (symbol_t){ + .type = SYM_PARAMETER, + .name = param_list->children[param_i]->data, + .node = param_list->children[param_i], + .seq = param_i, + .nparms = 0, + .locals = NULL + }; + + insert_symbol(global_symbol->locals, param_sym); + } + break; + } + } + }