#include #include #include "symtab.h" struct symtab* symtab_make() { struct symtab *symtab = malloc(sizeof(struct symtab)); symtab->parent = NULL; symtab->cap = 16; symtab->len = 0; symtab->syms = malloc(symtab->cap * sizeof(struct symbol*)); return symtab; } void symtab_delete_recursive(struct symtab *symtab) { free(symtab->syms); struct symtab *parent = symtab->parent; free(symtab); if (parent) symtab_delete_recursive(parent); } struct symbol* symtab_find(const struct symtab *symtab, const char *name) { struct symbol *sym = symtab_find_local(symtab, name); if (sym) return sym; else if (symtab->parent) return symtab_find(symtab->parent, name); else return NULL; } struct symbol* symtab_find_local(const struct symtab *symtab, const char *name) { for (int i = 0; i < symtab->len; i++) { if (strcmp(symtab->syms[i]->name, name) == 0) return symtab->syms[i]; } return NULL; } void symtab_insert(struct symtab *symtab, struct symbol *sym) { if (symtab->len == symtab->cap) { symtab->cap *= 2; symtab->syms = realloc(symtab->syms, symtab->cap * sizeof(struct symbol*)); } symtab->syms[symtab->len++] = sym; } struct symtab* symtab_root(struct symtab *symtab) { if (symtab->parent) return symtab_root(symtab->parent); else return symtab; } struct symtab* symtab_sub(struct symtab *symtab) { struct symtab *sub = symtab_make(); sub->parent = symtab; return sub; } struct symtab* symtab_delete_get_parent(struct symtab *symtab) { struct symtab *parent = symtab->parent; symtab->parent = NULL; symtab_delete_recursive(symtab); return parent; }