#define _POSIX_C_SOURCE 200809L #include "symbol_table.h" #include #include RavaSymbolTable_t* rava_symbol_table_create() { RavaSymbolTable_t *table = malloc(sizeof(RavaSymbolTable_t)); table->global_scope = rava_scope_create("global", NULL); table->current_scope = table->global_scope; return table; } void rava_symbol_table_destroy(RavaSymbolTable_t *table) { if (!table) return; rava_scope_destroy(table->global_scope); free(table); } RavaScope_t* rava_scope_create(const char *name, RavaScope_t *parent) { RavaScope_t *scope = calloc(1, sizeof(RavaScope_t)); scope->name = strdup(name); scope->symbols = NULL; scope->parent = parent; scope->children = NULL; scope->children_count = 0; scope->children_capacity = 0; return scope; } void rava_scope_destroy(RavaScope_t *scope) { if (!scope) return; free(scope->name); RavaSymbol_t *symbol = scope->symbols; while (symbol) { RavaSymbol_t *next = symbol->next; rava_symbol_destroy(symbol); symbol = next; } for (size_t i = 0; i < scope->children_count; i++) { rava_scope_destroy(scope->children[i]); } free(scope->children); free(scope); } void rava_symbol_table_enter_scope(RavaSymbolTable_t *table, const char *scope_name) { RavaScope_t *new_scope = rava_scope_create(scope_name, table->current_scope); if (table->current_scope->children_count >= table->current_scope->children_capacity) { size_t new_capacity = table->current_scope->children_capacity == 0 ? 4 : table->current_scope->children_capacity * 2; table->current_scope->children = realloc(table->current_scope->children, sizeof(RavaScope_t*) * new_capacity); table->current_scope->children_capacity = new_capacity; } table->current_scope->children[table->current_scope->children_count++] = new_scope; table->current_scope = new_scope; } void rava_symbol_table_exit_scope(RavaSymbolTable_t *table) { if (table->current_scope->parent) { table->current_scope = table->current_scope->parent; } } RavaSymbol_t* rava_symbol_create(RavaSymbolKind_e kind, const char *name, RavaType_t *type) { RavaSymbol_t *symbol = calloc(1, sizeof(RavaSymbol_t)); symbol->kind = kind; symbol->name = strdup(name); symbol->type = type; symbol->modifiers = NULL; symbol->modifiers_count = 0; symbol->declaration = NULL; symbol->next = NULL; return symbol; } void rava_symbol_destroy(RavaSymbol_t *symbol) { if (!symbol) return; free(symbol->name); rava_type_destroy(symbol->type); free(symbol); } bool rava_symbol_table_define(RavaSymbolTable_t *table, RavaSymbol_t *symbol) { if (!table || !symbol) return false; if (rava_symbol_table_resolve_in_scope(table->current_scope, symbol->name)) { return false; } symbol->next = table->current_scope->symbols; table->current_scope->symbols = symbol; return true; } RavaSymbol_t* rava_symbol_table_resolve(RavaSymbolTable_t *table, const char *name) { if (!table || !name) return NULL; RavaScope_t *scope = table->current_scope; while (scope) { RavaSymbol_t *symbol = rava_symbol_table_resolve_in_scope(scope, name); if (symbol) return symbol; scope = scope->parent; } return NULL; } RavaSymbol_t* rava_symbol_table_resolve_in_scope(RavaScope_t *scope, const char *name) { if (!scope || !name) return NULL; RavaSymbol_t *symbol = scope->symbols; while (symbol) { if (strcmp(symbol->name, name) == 0) { return symbol; } symbol = symbol->next; } return NULL; } bool rava_symbol_has_modifier(RavaSymbol_t *symbol, RavaModifier_e modifier) { if (!symbol) return false; for (size_t i = 0; i < symbol->modifiers_count; i++) { if (symbol->modifiers[i] == modifier) { return true; } } return false; }