From f0689ae844245b80605c02dcb95d982ae863bed3 Mon Sep 17 00:00:00 2001 From: Fredrik Robertsen Date: Thu, 26 Mar 2026 20:44:37 +0100 Subject: [PATCH] ps4: fix --- ps4/src/symbols.c | 100 +++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/ps4/src/symbols.c b/ps4/src/symbols.c index ae9c5d3..289ee0b 100644 --- a/ps4/src/symbols.c +++ b/ps4/src/symbols.c @@ -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.