Start bind_names and declarations

main
Øyvind Skaaden 2022-03-17 21:40:41 +01:00
parent 06bca1fa00
commit d80961ec56
1 changed files with 72 additions and 5 deletions

View File

@ -37,6 +37,19 @@ create_symbol_table ( void )
scopes = malloc(no_scopes * sizeof(tlhash_t));
find_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 );
/* Iterate over the temporary list, printing entries */
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 */
/*
@ -93,13 +106,13 @@ print_global_tree(symbol_t* global)
for (int l = 0; l < no_locals; l++)
{
printf(" %s─%s(%s, %ld)\n",
(l < (global->nparms - 1)) ? "" : "",
(l < (no_locals - 1)) ? "" : "",
symbol_names[locals_list[l]->type],
locals_list[l]->name,
locals_list[l]->seq
);
}
//putchar('\n');
putchar('\n');
free(locals_list);
}
@ -156,6 +169,8 @@ destroy_symbol_table ( void )
free(string_list[c]);
free(string_list);
free(scopes);
if (!global_names)
return;
@ -220,6 +235,7 @@ find_globals ( void )
// Function node allways have the same structure,
// [0] are the identifier
// [1] are the variable list, within a paramerer_list
// [2] are the actual block
if (!function->children[0])
break;
@ -228,7 +244,7 @@ find_globals ( void )
*global_symbol = (symbol_t){
.type = SYM_FUNCTION,
.name = current_global->children[0]->data,
.node = current_global->children[0],
.node = current_global->children[2],
.seq = no_functions++,
.nparms = 0,
.locals = malloc(sizeof(tlhash_t))
@ -276,6 +292,7 @@ push_scope(void)
scopes[cur_scope_depth] = malloc(sizeof(tlhash_t));
tlhash_init(scopes[cur_scope_depth++], LOCAL_BUCKET_SIZE);
// Grow the amount of scopes
if (cur_scope_depth >= no_scopes)
{
no_scopes *= 2;
@ -297,6 +314,46 @@ pop_scope(void)
//scopes[cur_scope_depth] = NULL;
}
void
insert_local_to_scope(symbol_t *local)
{
insert_symbol(scopes[cur_scope_depth - 1], local);
/*tlhash_insert(
scopes[cur_scope_depth - 1], //! Insert local to topmost scope
local->name, //! Key is name, this is used to do lookup
strlen(local->name), //! Length of key
local //! The local symbol
);*/
}
void
insert_local_to_func(symbol_t *function, symbol_t *local)
{
tlhash_insert(
function->locals, //! Insert local to the function var table
&local->seq, //! The key is a number, unique, strictly growing
sizeof(local->seq), //! Size of key
local //! The local symbol
);
}
void
insert_local_var(symbol_t *function, node_t *local)
{
size_t sequence = tlhash_size(function->locals);
symbol_t *variable = malloc(sizeof(symbol_t));
*variable = (symbol_t){
.type = SYM_LOCAL_VAR,
.name = local->data,
.node = local,
.seq = sequence, //! Use sequence as name in var list of function, strictly growing
.nparms = 0,
.locals = NULL
};
insert_local_to_scope(variable);
insert_local_to_func(function, variable);
}
void
bind_names ( symbol_t *function, node_t *root )
@ -306,7 +363,10 @@ bind_names ( symbol_t *function, node_t *root )
return;
if (!root)
return;
// Can't declare variables inside switch unless
// it is in a new scope
node_t *declarations;
// We want do top to bottom traverse, so do not
// call recusivly unless we need to go deeper
switch (root->type)
@ -316,9 +376,16 @@ bind_names ( symbol_t *function, node_t *root )
for (uint64_t i = 0; i < root->n_children; i++)
bind_names(function, root->children[i]);
pop_scope();
break;
case DECLARATION_LIST:
if (!root->children[0])
break;
/* code */
declarations = root->children[0];
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: