roza/lib/sym.c

154 lines
3.5 KiB
C
Raw Normal View History

#include "sym.h"
2023-12-20 19:54:58 +00:00
#include "lib/node.h"
void sym_init(sym_t* sym, tysy_t* tysy, err_t* err)
{
assert(sym);
2023-12-23 20:17:12 +00:00
sym->parent = NULL;
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-23 20:17:12 +00:00
int sym_declare(sym_t* sym, int id, char* name, type_t* type,
2023-12-20 19:54:58 +00:00
int scope, int state_flag, node_t* node)
{
assert(sym);
assert(name);
sym_entry_t* res = sym_try_find_by_name(sym,
name,
scope,
state_flag,
2023-12-20 19:54:58 +00:00
node);
node_t* block = node_try_find_parent(node, NODE_BLOCK);
node_t* res_block;
if (res)
{
res_block = node_try_find_parent(res->node, NODE_BLOCK);
}
if (res && res_block == block)
{
return res->id;
}
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));
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;
sym->entries.data[sym->entries.size]->scope = scope;
sym->entries.data[sym->entries.size]->state = state_flag;
2023-12-20 19:54:58 +00:00
sym->entries.data[sym->entries.size]->node = node;
sym->entries.size++;
return id;
}
sym_entry_t* sym_try_find_by_name(sym_t* sym, char* name,
int scope, int state_flag,
2023-12-20 19:54:58 +00:00
node_t* node)
{
assert(sym);
sym_entry_t* res = NULL;
for (size_t i=0; i<sym->entries.size; i++)
{
sym_entry_t* entry = sym->entries.data[i];
2023-12-20 19:54:58 +00:00
node_t* itr = node_try_find_parent(node, NODE_BLOCK);
node_t* entry_block = node_try_find_parent(entry->node, NODE_BLOCK);
2023-12-20 19:54:58 +00:00
while (itr && itr != entry_block)
{
itr = (node_t*) itr->parent;
}
if (strcmp(entry->name, name) == 0
&& entry->scope == scope
&& (entry->state & state_flag) != 0
2023-12-20 19:54:58 +00:00
&& (entry_block == itr))
{
res = entry;
return res;
}
}
2023-12-23 20:17:12 +00:00
sym_entry_t* result = NULL;
if (scope > 0)
{
2023-12-23 20:17:12 +00:00
result = sym_try_find_by_name(sym, name, scope - 1, state_flag, node);
if (result) { return result; }
}
if (sym->parent)
{
result = sym_try_find_by_name(sym->parent, name, scope, state_flag, node);
if (result) { return result; }
}
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];
sz += snprintf(buffer + sz, size - sz, "(%d| %d %s ",
entry->id, entry->scope, entry->name);
sz += type_str(entry->type, buffer + sz, size - sz);
sz += snprintf(buffer + sz, size - sz, ")\n");
}
return sz;
}