#include "symtable.h" void entry_init(struct entry* self, char const* name, size_t addr, bool is_local) { assert(self); self->name = strdup(name); self->addr = addr; self->is_local = is_local; } void entry_free(struct entry* self) { assert(self); free(self->name); } void env_init(struct env* self, struct env* parent) { assert(self); vec_init(&self->entries); self->parent = parent; } void env_free(struct env* self) { assert(self); if (self->parent) { env_free(self->parent); free(self->parent); self->parent = NULL; } vec_free_elements(&self->entries, (void*) entry_free); vec_free(&self->entries); } struct entry* env_try_get(struct env* self, char* name) { assert(self); assert(name); for (size_t i=0; ientries.size; i++) { struct entry* entry = self->entries.data[i]; if (strcmp(entry->name, name) == 0) { return entry; } } if (self->parent) { return env_try_get(self->parent, name); } return NULL; } void symtable_init(struct symtable* self) { assert(self); self->root = malloc(sizeof(struct env)); env_init(self->root, NULL); } void symtable_free(struct symtable* self) { assert(self); env_free(self->root); free(self->root); } void symtable_declare(struct symtable* self, char* name, size_t addr, bool is_local) { assert(self); assert(name); assert(self->root); struct entry* entry = malloc(sizeof(struct entry)); entry_init(entry, name, addr, is_local); vec_push(&self->root->entries, entry); } struct entry* symtable_try_get(struct symtable* self, char* name) { assert(self); assert(name); return env_try_get(self->root, name); } void symtable_open_scope(struct symtable* self) { struct env* env = malloc(sizeof(struct env)); env_init(env, self->root); self->root = env; } void symtable_close_scope(struct symtable* self) { assert(self); assert(self->root); struct env* env = self->root->parent; self->root->parent = NULL; env_free(self->root); free(self->root); self->root = env; }