2024-03-27 10:49:10 +00:00
|
|
|
#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; i<self->entries.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);
|
|
|
|
|
|
|
|
}
|
2024-03-30 19:04:07 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|