Added lookup of vars, start commenting
parent
398bdc9487
commit
fab7d8916e
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue