ps4: fix
This commit is contained in:
@@ -26,7 +26,6 @@ void create_tables(void)
|
||||
symbol_t *symbol = global_symbols->symbols[i];
|
||||
if (symbol->type == SYMBOL_FUNCTION) {
|
||||
node_t *block = symbol->node->children[2];
|
||||
assert(block->type == BLOCK);
|
||||
bind_names(symbol->function_symtable, block->children[0]);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +103,7 @@ static void find_globals(void)
|
||||
break;
|
||||
case FUNCTION:
|
||||
symbol_table_t *function_symtable = symbol_table_init();
|
||||
node_t *parameters = top_level_node->children[1]->children[0];
|
||||
node_t *parameters = top_level_node->children[1];
|
||||
assert(parameters->type == LIST);
|
||||
for (int j = 0; j < parameters->n_children; j++) {
|
||||
node_t *p = parameters->children[j];
|
||||
@@ -136,53 +135,56 @@ static void find_globals(void)
|
||||
// where the data.string_list_index field is set to the string's index in the string list.
|
||||
static void bind_names(symbol_table_t* local_symbols, node_t* node)
|
||||
{
|
||||
symbol_hashmap_t *hashmap = symbol_hashmap_init();
|
||||
local_symbols->hashmap = hashmap;
|
||||
assert(node->type == LIST);
|
||||
for (int i = 0; i < node->n_children; i++) {
|
||||
node_t *statement_or_declaration = node->children[i];
|
||||
switch (statement_or_declaration->type) {
|
||||
case LOCAL_VARIABLE_DECLARATION:
|
||||
node_t *local_variables = statement_or_declaration->children[0];
|
||||
for (int j = 0; j < local_variables->n_children; j++) {
|
||||
node_t *var = local_variables->children[j];
|
||||
assert(var->type == LOCAL_VARIABLE);
|
||||
symbol_t *sym = create_symbol(var->children[0]->data.identifier, SYMBOL_LOCAL_VAR, var, NULL);
|
||||
if (symbol_table_insert(local_symbols, sym) != INSERT_OK) {
|
||||
fprintf(stderr, "bind_names: failed to insert local variable");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BLOCK:
|
||||
symbol_hashmap_t *inner = symbol_hashmap_init();
|
||||
inner->backup = local_symbols->hashmap;
|
||||
local_symbols->hashmap = inner;
|
||||
for (size_t i = 0; i < node->n_children; i++)
|
||||
bind_names(local_symbols, node->children[i]);
|
||||
local_symbols->hashmap = inner->backup;
|
||||
symbol_hashmap_destroy(inner);
|
||||
break;
|
||||
case PRINT_STATEMENT:
|
||||
node_t *print_list = statement_or_declaration->children[0];
|
||||
for (int j = 0; j < print_list->n_children; j++) {
|
||||
node_t *print_item = print_list->children[j];
|
||||
if (print_item->type != STRING_LITERAL) continue;
|
||||
size_t pos = add_string(print_item->data.string_literal);
|
||||
node_t *new = node_create(STRING_LIST_REFERENCE, 0);
|
||||
new->data.string_list_index = pos;
|
||||
node_finalize(print_item);
|
||||
print_list->children[j] = new;
|
||||
}
|
||||
break;
|
||||
case PRINTLN_STATEMENT:
|
||||
fprintf(stderr, "println encountered: this should've been handled last time...");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node == NULL) return;
|
||||
switch (node->type) {
|
||||
case BLOCK:
|
||||
symbol_hashmap_t *inner = symbol_hashmap_init();
|
||||
inner->backup = local_symbols->hashmap;
|
||||
local_symbols->hashmap = inner;
|
||||
for (size_t i = 0; i < node->n_children; i++)
|
||||
bind_names(local_symbols, node->children[i]);
|
||||
local_symbols->hashmap = inner->backup;
|
||||
symbol_hashmap_destroy(inner);
|
||||
return;
|
||||
case LOCAL_VARIABLE_DECLARATION:
|
||||
node_t *local_variables = node->children[0];
|
||||
for (int j = 0; j < local_variables->n_children; j++) {
|
||||
node_t *var = local_variables->children[j];
|
||||
assert(var->type == LOCAL_VARIABLE);
|
||||
symbol_t *sym = create_symbol(var->children[0]->data.identifier, SYMBOL_LOCAL_VAR, var, NULL);
|
||||
if (symbol_table_insert(local_symbols, sym) != INSERT_OK) {
|
||||
fprintf(stderr, "bind_names: failed to insert local variable");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PRINT_STATEMENT:
|
||||
node_t *print_list = node->children[0];
|
||||
for (int j = 0; j < print_list->n_children; j++) {
|
||||
node_t *print_item = print_list->children[j];
|
||||
if (print_item->type != STRING_LITERAL) continue;
|
||||
size_t pos = add_string(print_item->data.string_literal);
|
||||
node_t *new = node_create(STRING_LIST_REFERENCE, 0);
|
||||
new->data.string_list_index = pos;
|
||||
free(print_item->children);
|
||||
free(print_item);
|
||||
print_list->children[j] = new;
|
||||
}
|
||||
break;
|
||||
case PRINTLN_STATEMENT:
|
||||
fprintf(stderr, "println encountered: this should've been handled last time...");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case IDENTIFIER:
|
||||
symbol_t *sym = symbol_hashmap_lookup(local_symbols->hashmap, node->data.identifier);
|
||||
if (!sym) sym = symbol_hashmap_lookup(global_symbols->hashmap, node->data.identifier);
|
||||
node->symbol = sym;
|
||||
return;
|
||||
default:
|
||||
for (int i = 0; i < node->n_children; i++)
|
||||
bind_names(local_symbols, node->children[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the given symbol table, with sequence number, symbol names and types.
|
||||
|
||||
Reference in New Issue
Block a user