mips/masm/symtab.c

89 lines
1.8 KiB
C

#include <merror.h>
#include <netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}