implement find_globals
This commit is contained in:
+61
-13
@@ -51,25 +51,73 @@ void destroy_tables(void)
|
||||
|
||||
/* Internal matters */
|
||||
|
||||
symbol_t *create_symbol(symtype_t type, node_t *node, symbol_table_t *function_symtable) {
|
||||
symbol_t *new_symbol = malloc(sizeof(symbol_t));
|
||||
new_symbol->type = type;
|
||||
new_symbol->name = SYMBOL_TYPE_NAMES[type];
|
||||
new_symbol->node = node;
|
||||
new_symbol->function_symtable = function_symtable;
|
||||
return new_symbol;
|
||||
}
|
||||
|
||||
// Goes through all global declarations, adding them to the global symbol table.
|
||||
// When adding functions, a local symbol table with symbols for its parameters are created.
|
||||
static void find_globals(void)
|
||||
{
|
||||
global_symbols = symbol_table_init();
|
||||
|
||||
// TODO: Create symbols for all global defintions (global variables, arrays and functions),
|
||||
// and add them to the global symbol table. See the symtype_t enum in "symbols.h"
|
||||
|
||||
// When creating a symbol for a function, also create a local symbol_table_t for it.
|
||||
// Store this local symbol table in the function symbol's function_symtable field.
|
||||
// Any parameters the function may have should be added to this local symbol table.
|
||||
|
||||
// TIP: create symbols using malloc(sizeof(symbol_t)), and assigning the relevant fields.
|
||||
// Use symbol_table_insert() (from "symbol_table.h") to insert new symbols into tables.
|
||||
|
||||
// If a symbol already exists with the same name, the insertion will return INSERT_COLLISION.
|
||||
// Feel free to print an error message and abort using exit(EXIT_FAILURE),
|
||||
// but we will not be testing your compiler on invalid VSL.
|
||||
for (int i = 0; i < root->n_children; i++) {
|
||||
node_t *top_level_node = root->children[i];
|
||||
switch (top_level_node->type) {
|
||||
case GLOBAL_VARIABLE_DECLARATION:
|
||||
assert(top_level_node->n_children == 1);
|
||||
node_t *list = top_level_node->children[0];
|
||||
assert(list->type == LIST);
|
||||
for (int j = 0; j < list->n_children; j++) {
|
||||
node_t *global = list->children[j];
|
||||
switch (global->type) {
|
||||
case IDENTIFIER:
|
||||
symbol_t *identifier = create_symbol(SYMBOL_GLOBAL_VAR, global, NULL);
|
||||
if (symbol_table_insert(global_symbols, identifier) != INSERT_OK) {
|
||||
fprintf(stderr, "find_globals: insertion collision (identifier)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case ARRAY_INDEXING:
|
||||
symbol_t *array = create_symbol(SYMBOL_GLOBAL_ARRAY, global, NULL);
|
||||
if (symbol_table_insert(global_symbols, array) != INSERT_OK) {
|
||||
fprintf(stderr, "find_globals: insertion collision (array)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "find_globals: found global %d", global->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FUNCTION:
|
||||
symbol_table_t *function_symtable = symbol_table_init();
|
||||
node_t *parameters = top_level_node->children[1]->children[0];
|
||||
assert(parameters->type == LIST);
|
||||
for (int j = 0; j < parameters->n_children; j++) {
|
||||
symbol_t *param = create_symbol(SYMBOL_PARAMETER, parameters->children[j], NULL);
|
||||
if (symbol_table_insert(function_symtable, param) != INSERT_OK) {
|
||||
fprintf(stderr, "find_globals: insertion collision (parameter)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
symbol_t *new_symbol = create_symbol(SYMBOL_FUNCTION, top_level_node, function_symtable);
|
||||
if (symbol_table_insert(global_symbols, new_symbol) != INSERT_OK) {
|
||||
fprintf(stderr, "find_globals: insertion collision (function)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "find_globals: found top level %d", top_level_node->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A recursive function that traverses the body of a function doing the following:
|
||||
|
||||
Reference in New Issue
Block a user