#include #include #include #include #include #include #include "lex.h" #include "tab.h" #define SYMTBL_INIT_LEN 24 int symtab_init(struct symbol_table *symtab) { symtab->size = SYMTBL_INIT_LEN; symtab->len = 0; symtab->symbols = malloc(sizeof(struct symbol) * SYMTBL_INIT_LEN); if (symtab->symbols == NULL) { PERROR("cannot alloc"); return M_ERROR; } return M_SUCCESS; } void symtab_free(struct symbol_table *symtab) { for (uint32_t i = 0; i < symtab->len; i++) string_free(&symtab->symbols[i].name); free(symtab->symbols); } int symtab_push(struct symbol_table *symtab, struct symbol *sym) { if (symtab->len >= symtab->size) { symtab->size *= 2; symtab->symbols = realloc(symtab->symbols, sizeof(struct symbol) * symtab->size); if (symtab->symbols == NULL) { PERROR("cannot realloc"); return M_ERROR; } } sym->tabidx = symtab->len; symtab->symbols[symtab->len++] = *sym; return M_SUCCESS; } int symtab_find(struct symbol_table *symtab, struct symbol **res, const char *name) { for (uint32_t i = 0; i < symtab->len; i++) { struct symbol *sym = &symtab->symbols[i]; if (strcmp(sym->name.str, name) == 0) { if (res != NULL) *res = sym; return M_SUCCESS; } } return M_ERROR; } int symtab_find_or_stub(struct symbol_table *symtab, struct symbol **res, const struct string *const name) { if (symtab_find(symtab, res, name->str) == M_SUCCESS) return M_SUCCESS; struct symbol temp = { .offset = 0, .secidx = SYM_SEC_STUB, .type = SYM_LOCAL, }; if (string_clone(&temp.name, name)) return M_ERROR; if (symtab_push(symtab, &temp)) { string_free(&temp.name); return M_ERROR; } if (res != NULL) *res = &symtab->symbols[symtab->len - 1]; return M_SUCCESS; }