2025-12-02 06:54:32 +01:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
#include "symbol_table.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2025-12-03 15:01:02 +01:00
|
|
|
static inline uint32_t _rava_symbol_hash(const char *name) {
|
|
|
|
|
uint32_t hash = 5381;
|
|
|
|
|
while (*name) {
|
|
|
|
|
hash = ((hash << 5) + hash) ^ (uint32_t)*name++;
|
|
|
|
|
}
|
|
|
|
|
return hash & (RAVA_SYMBOL_HASH_SIZE - 1);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 06:54:32 +01:00
|
|
|
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;
|
2025-12-03 15:01:02 +01:00
|
|
|
|
|
|
|
|
uint32_t h = _rava_symbol_hash(symbol->name);
|
|
|
|
|
symbol->hash_next = table->current_scope->hash_table[h];
|
|
|
|
|
table->current_scope->hash_table[h] = symbol;
|
|
|
|
|
|
2025-12-02 06:54:32 +01:00
|
|
|
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;
|
|
|
|
|
|
2025-12-03 15:01:02 +01:00
|
|
|
uint32_t h = _rava_symbol_hash(name);
|
|
|
|
|
RavaSymbol_t *symbol = scope->hash_table[h];
|
2025-12-02 06:54:32 +01:00
|
|
|
while (symbol) {
|
|
|
|
|
if (strcmp(symbol->name, name) == 0) {
|
|
|
|
|
return symbol;
|
|
|
|
|
}
|
2025-12-03 15:01:02 +01:00
|
|
|
symbol = symbol->hash_next;
|
2025-12-02 06:54:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|