diff --git a/src/code_generator/symbol_table.c b/src/code_generator/symbol_table.c index 55177f44..1100f6d2 100644 --- a/src/code_generator/symbol_table.c +++ b/src/code_generator/symbol_table.c @@ -1,12 +1,12 @@ #include "code_generator/symbol_table.h" #include "code_generator/symbol_table_impl.h" -#include "stdstring.h" #include "utility.h" DEFINE_VECTOR(SymbolInfoRef) DEFINE_VECTOR(SymbolBlockRef) static SymbolTableRef g_symbol_table; +static const char g_separator = '$'; SymbolInfoRef symbol_info_ctor(StringRef name, LLVMTypeRef type, LLVMValueRef value) { @@ -84,3 +84,73 @@ void finalize_symbol_table(void) { assert(g_symbol_table); symbol_table_dtor(&g_symbol_table); } + +void symbol_table_push(StringRef name) { + const SymbolBlockRef block = symbol_block_ctor(name); + VECTORFUNC(SymbolBlockRef, push_back)(g_symbol_table->stack, block); + string_append(g_symbol_table->prefix, name); + string_push_back(g_symbol_table->prefix, g_separator); +} + +void symbol_table_pop(void) { + const size_t length = string_length(g_symbol_table->prefix); + assert(2 <= length); + assert(!VECTORFUNC(SymbolBlockRef, empty)(g_symbol_table->stack)); + { + SymbolBlockRef block = + VECTORFUNC(SymbolBlockRef, back)(g_symbol_table->stack); + symbol_block_dtor(&block); + VECTORFUNC(SymbolBlockRef, pop_back)(g_symbol_table->stack); + } + { + size_t i = length - 1; + for (; 0 < i; --i) { + if (string_at(g_symbol_table->prefix, i - 1) == g_separator) { + break; + } + } + string_erase(g_symbol_table->prefix, i, length - i); + } +} + +void register_symbol(StringRef name, LLVMTypeRef type, LLVMValueRef value) { + const SymbolInfoRef symbol = symbol_info_ctor(name, type, value); + const SymbolBlockRef block = + VECTORFUNC(SymbolBlockRef, back)(g_symbol_table->stack); + VECTORFUNC(SymbolInfoRef, push_back)(block->symbols, symbol); +} + +void append_prefix(StringRef name) { + string_insert(name, 0, g_symbol_table->prefix); +} + +static SymbolInfoRef find_symbol_in_block(StringRef name, + SymbolBlockRef block) { + const SymbolInfoRef* const begin = + VECTORFUNC(SymbolInfoRef, begin)(block->symbols); + const SymbolInfoRef* const end = + VECTORFUNC(SymbolInfoRef, end)(block->symbols); + const SymbolInfoRef* iter = begin; + for (; iter != end; ++iter) { + if (string_compare((*iter)->name, name) == 0) { + return *iter; + } + } + return NULL; +} + +SymbolInfoRef find_symbol(StringRef name) { + const SymbolBlockRef* const begin = + VECTORFUNC(SymbolBlockRef, begin)(g_symbol_table->stack); + const SymbolBlockRef* const end = + VECTORFUNC(SymbolBlockRef, end)(g_symbol_table->stack); + const SymbolBlockRef* iter = end; + for (; iter != begin; --iter) { + const SymbolInfoRef symbol = find_symbol_in_block(name, *(iter - 1)); + if (symbol) { + return symbol; + } + } + /* TODO: find global symbol */ + return NULL; +} diff --git a/src/code_generator/symbol_table.h b/src/code_generator/symbol_table.h index 25345a58..1d8b1e9b 100644 --- a/src/code_generator/symbol_table.h +++ b/src/code_generator/symbol_table.h @@ -1,11 +1,19 @@ #ifndef KMC_C90_COMPILER_CODE_GENERATOR_SYMBOL_TABLE_H #define KMC_C90_COMPILER_CODE_GENERATOR_SYMBOL_TABLE_H +#include +#include "stdstring.h" + typedef struct SymbolInfo* SymbolInfoRef; typedef struct SymbolBlock* SymbolBlockRef; typedef struct SymbolTable* SymbolTableRef; void initialize_symbol_table(StringRef name); void finalize_symbol_table(void); +void symbol_table_push(StringRef name); +void symbol_table_pop(void); +void register_symbol(StringRef name, LLVMTypeRef type, LLVMValueRef value); +void append_prefix(StringRef name); +SymbolInfoRef find_symbol(StringRef name); #endif /* KMC_C90_COMPILER_CODE_GENERATOR_SYMBOL_TABLE_H */