2023-12-17 18:10:17 +00:00
|
|
|
#include "sym.h"
|
|
|
|
|
|
|
|
void sym_init(sym_t* sym, tysy_t* tysy, err_t* err)
|
|
|
|
{
|
|
|
|
assert(sym);
|
|
|
|
|
|
|
|
sym->tysy = tysy;
|
|
|
|
sym->err = err;
|
|
|
|
|
|
|
|
sym->entries.id_counter = 0;
|
|
|
|
sym->entries.size = 0;
|
|
|
|
sym->entries.cap = 0;
|
|
|
|
sym->entries.data = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sym_free(sym_t* sym)
|
|
|
|
{
|
|
|
|
assert(sym);
|
|
|
|
|
|
|
|
for (size_t i=0; i<sym->entries.size; i++)
|
|
|
|
{
|
|
|
|
sym_entry_t* entry = sym->entries.data[i];
|
|
|
|
free(entry->name);
|
|
|
|
free(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(sym->entries.data);
|
|
|
|
sym->entries.size = 0;
|
|
|
|
sym->entries.cap = 0;
|
|
|
|
}
|
|
|
|
|
2023-12-18 13:19:38 +00:00
|
|
|
int sym_declare(sym_t* sym, char* name, type_t* type,
|
|
|
|
int scope, int state_flag, node_t* block)
|
2023-12-17 18:10:17 +00:00
|
|
|
{
|
|
|
|
assert(sym);
|
|
|
|
assert(name);
|
|
|
|
|
2023-12-18 13:19:38 +00:00
|
|
|
sym_entry_t* res = sym_try_find_by_name(sym,
|
|
|
|
name,
|
|
|
|
scope,
|
|
|
|
state_flag,
|
|
|
|
block);
|
|
|
|
if (res && res->block == block)
|
|
|
|
{
|
|
|
|
return res->id;
|
|
|
|
}
|
|
|
|
|
2023-12-17 18:10:17 +00:00
|
|
|
if (sym->entries.data == NULL)
|
|
|
|
{
|
|
|
|
sym->entries.cap = 2;
|
|
|
|
sym->entries.data = malloc(sizeof(sym_entry_t*)
|
|
|
|
* sym->entries.cap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sym->entries.size >= sym->entries.cap)
|
|
|
|
{
|
|
|
|
sym->entries.cap *= 2;
|
|
|
|
sym->entries.data = realloc(sym->entries.data,
|
|
|
|
sizeof(sym_entry_t*) * sym->entries.cap);
|
|
|
|
}
|
|
|
|
|
|
|
|
sym->entries.data[sym->entries.size] = malloc(sizeof(sym_entry_t));
|
|
|
|
|
|
|
|
int id = sym->entries.id_counter;
|
|
|
|
sym->entries.id_counter++;
|
|
|
|
|
|
|
|
sym->entries.data[sym->entries.size]->name = strdup(name);
|
|
|
|
sym->entries.data[sym->entries.size]->id = id;
|
|
|
|
sym->entries.data[sym->entries.size]->type = type;
|
2023-12-18 13:19:38 +00:00
|
|
|
sym->entries.data[sym->entries.size]->scope = scope;
|
|
|
|
sym->entries.data[sym->entries.size]->state = state_flag;
|
|
|
|
sym->entries.data[sym->entries.size]->block = block;
|
2023-12-17 18:10:17 +00:00
|
|
|
|
|
|
|
sym->entries.size++;
|
|
|
|
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2023-12-18 13:19:38 +00:00
|
|
|
sym_entry_t* sym_try_find_by_name(sym_t* sym, char* name,
|
|
|
|
int scope, int state_flag,
|
|
|
|
node_t* block)
|
2023-12-17 18:10:17 +00:00
|
|
|
{
|
|
|
|
assert(sym);
|
|
|
|
|
2023-12-18 13:19:38 +00:00
|
|
|
sym_entry_t* res = NULL;
|
|
|
|
|
2023-12-17 18:10:17 +00:00
|
|
|
for (size_t i=0; i<sym->entries.size; i++)
|
|
|
|
{
|
2023-12-18 13:19:38 +00:00
|
|
|
sym_entry_t* entry = sym->entries.data[i];
|
|
|
|
|
|
|
|
node_t* itr = block;
|
|
|
|
|
|
|
|
while (itr && itr != entry->block)
|
2023-12-17 18:10:17 +00:00
|
|
|
{
|
2023-12-18 13:19:38 +00:00
|
|
|
itr = (node_t*) itr->parent;
|
2023-12-17 18:10:17 +00:00
|
|
|
}
|
2023-12-18 13:19:38 +00:00
|
|
|
|
|
|
|
if (strcmp(entry->name, name) == 0
|
|
|
|
&& entry->scope == scope
|
|
|
|
&& (entry->state & state_flag) != 0
|
|
|
|
&& (entry->block == itr))
|
|
|
|
{
|
|
|
|
res = entry;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scope > 0)
|
|
|
|
{
|
|
|
|
return sym_try_find_by_name(sym, name, scope - 1, state_flag, block);
|
2023-12-17 18:10:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t sym_str(sym_t* sym, char* buffer, size_t size)
|
|
|
|
{
|
|
|
|
assert(sym);
|
|
|
|
assert(buffer);
|
|
|
|
size_t sz = 0;
|
|
|
|
|
|
|
|
for (size_t i=0; i<sym->entries.size; i++)
|
|
|
|
{
|
|
|
|
sym_entry_t* entry = sym->entries.data[i];
|
2023-12-18 13:19:38 +00:00
|
|
|
sz += snprintf(buffer + sz, size - sz, "(%d| %d %s ",
|
|
|
|
entry->id, entry->scope, entry->name);
|
2023-12-17 18:10:17 +00:00
|
|
|
|
|
|
|
sz += type_str(entry->type, buffer + sz, size - sz);
|
|
|
|
|
|
|
|
sz += snprintf(buffer + sz, size - sz, ")\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return sz;
|
|
|
|
}
|