Added lookup of vars, start commenting

main
Øyvind Skaaden 2022-03-17 23:14:24 +01:00
parent 398bdc9487
commit fab7d8916e
1 changed files with 70 additions and 54 deletions

View File

@ -1,6 +1,6 @@
#include <vslc.h>
#define ERRPRT(format, args...) {fprintf(stderr, "[ERROR] "); fprintf(stderr ,format, ##args);}
// Externally visible, for the generator
@ -42,49 +42,13 @@ create_symbol_table ( void )
symbol_t **global_list = malloc(no_globals * sizeof(symbol_t));
tlhash_values(global_names, (void **)global_list );
/* Iterate over the temporary list, printing entries */
/* Iterate over the temporary list, bind names in each function */
for (uint64_t g = 0; g < no_globals; g++ )
{
if (global_list[g]->type == SYM_FUNCTION)
bind_names(global_list[g], global_list[g]->node);
}
free(global_list);
/* 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.
// Initialize table
tlhash_t *my_table = (tlhash_t*)malloc(sizeof(tlhash_t));
tlhash_init(my_table, 64);
char *my_key0 = "key"; // Keep in mind that these are stack allocated for simplicity, yours should not
char *my_val0 = "valuable"; // Also, I'm using strings as values, you will be using symbol_t pointers
char *my_key1 = "another_key";
char *my_val1 = "more valuable";
// Insert some values to the table. Remember that the length of a string
// interpreted as an array is the string length plus one '\0' character
tlhash_insert(my_table, my_key0, strlen(my_key0)+1, my_val0);
tlhash_insert(my_table, my_key1, strlen(my_key1)+1, my_val1);
// Iterate keys and lookup their values
size_t size = tlhash_size(my_table);
char **keys = (char **)malloc(size);
tlhash_keys(my_table, keys);
char *val;
for (int i = 0; i < size; i++) {
tlhash_lookup(my_table, keys[i], strlen(keys[i])+1, &val);
printf("my_table[%s] = \"%s\"\n", keys[i], val);
}
// Free allocated memory when done with the symbol table
tlhash_finalize(my_table);
free(my_table);
free(keys);
*/
}
@ -95,21 +59,28 @@ print_global_tree(symbol_t* global)
if (!global)
return;
printf("─%s(%s, %ld)\n", symbol_names[global->type], global->name, global->seq);
printf("─%s(%s, nparams=%ld, seq=%ld, node=%p)\n",
symbol_names[global->type],
global->name,
global->nparms,
global->seq,
global->node
);
if (!global->nparms && !global->locals)
return;
{putchar('\n');return;}
uint64_t no_locals = tlhash_size(global->locals);
symbol_t **locals_list = malloc(no_locals * sizeof(symbol_t));
tlhash_values(global->locals, (void **)locals_list );
for (int l = 0; l < no_locals; l++)
{
printf(" %s─%s(%s, %ld)\n",
printf(" %s─%s(%s, seq=%ld, node=%p)\n",
(l < (no_locals - 1)) ? "" : "",
symbol_names[locals_list[l]->type],
locals_list[l]->name,
locals_list[l]->seq
locals_list[l]->seq,
locals_list[l]->node
);
}
putchar('\n');
@ -176,27 +147,37 @@ destroy_global(symbol_t* global)
void
destroy_symbol_table ( void )
{
//return;
/* TODO: release memory allocated to the symbol table */
// FREE STRINGS
// Free all strings that are kept in the array
for (uint64_t c = 0; c < stringc; c++)
free(string_list[c]);
// Free the actual list
free(string_list);
// FREE SCOPES
// At the end of program, all scopes have to be popped
// Therefore only free the list
free(scopes);
// FREE GLOBAL NAMES
if (!global_names)
return;
// Fetch list of globals
uint64_t no_globals = tlhash_size(global_names);
symbol_t **global_list = malloc(no_globals * sizeof(symbol_t));
tlhash_values(global_names, (void **)global_list );
// Destroy all global elements
for (uint64_t g = 0; g < no_globals; g++)
destroy_global(global_list[g]);
// Destory the global hash table
tlhash_finalize(global_names);
// Free the global hash table
free(global_names);
// Free the temp list
free(global_list);
}
@ -210,7 +191,6 @@ 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;
@ -311,7 +291,7 @@ push_scope(void)
tlhash_t **new_scopes = realloc(scopes, no_scopes * sizeof(tlhash_t));
if (!new_scopes)
{
fprintf(stderr, "[ERROR] Could not realloc scopes!\n");
ERRPRT("Could not realloc scopes!\n");
exit(EXIT_FAILURE);
}
scopes = new_scopes;
@ -323,7 +303,6 @@ pop_scope(void)
{
tlhash_finalize(scopes[--cur_scope_depth]);
free(scopes[cur_scope_depth]);
//scopes[cur_scope_depth] = NULL;
}
void
@ -336,10 +315,10 @@ void
insert_local_to_func(symbol_t *function, symbol_t *root)
{
tlhash_insert(
function->locals, //! Insert local to the function var table
&root->seq, //! The key is a number, unique, strictly growing
sizeof(root->seq), //! Size of key
root //! The local symbol
function->locals, //! Insert local to the function var table
&root->seq, //! The key is a number, unique, strictly growing
sizeof(root->seq), //! Size of key
root //! The local symbol
);
}
@ -353,7 +332,7 @@ insert_local_var(symbol_t *function, node_t *root)
.type = SYM_LOCAL_VAR,
.name = root->data,
.node = root,
.seq = sequence, //! Use sequence as name in var list of function, strictly growing
.seq = sequence, //! Use sequence as name in var list of function, strictly growing
.nparms = 0,
.locals = NULL
};
@ -377,13 +356,43 @@ collect_string(node_t *root)
char **new_string_list = realloc(string_list, n_string_list * sizeof(char*));
if (!new_string_list)
{
fprintf(stderr, "[ERROR] Could not realloc string list!\n");
ERRPRT("Could not realloc string list!\n");
exit(EXIT_FAILURE);
}
string_list = new_string_list;
}
}
static symbol_t*
lookup_var(symbol_t *function, char* var)
{
// Symbol to store the stymbol to be found
symbol_t* symbol = NULL;
// Result stores the result of the hash lookups
int result;
// Try the local scopes first
for (int64_t d = cur_scope_depth - 1; d >= 0; d--)
{
result = tlhash_lookup(scopes[d], var, strlen(var), (void**)&symbol);
if (result == TLHASH_SUCCESS)
return symbol;
}
// Then move to parameters
result = tlhash_lookup(function->locals, var, strlen(var), (void**)&symbol);
if (result == TLHASH_SUCCESS)
return symbol;
// Last try global parameters
result = tlhash_lookup(global_names, var, strlen(var), (void**)&symbol);
if (result == TLHASH_SUCCESS)
return symbol;
// If nothing is found, return NULL
return NULL;
}
void
bind_names ( symbol_t *function, node_t *root )
{
@ -413,11 +422,18 @@ bind_names ( symbol_t *function, node_t *root )
for (uint64_t i = 0; i < declarations->n_children; i++)
// Insert each of the local variables in the declaration
insert_local_var(function, declarations->children[i]);
break;
case IDENTIFIER_DATA:
if (!root->data)
break;
if (!(root->entry = lookup_var(function, root->data)))
{
ERRPRT("Could not find %s in scope!\n", (char*)root->data)
exit(EXIT_FAILURE);
}
break;
case STRING_DATA: