#include "sym.h" #include "lib/node.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; ientries.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; } int sym_declare(sym_t* sym, char* name, type_t* type, 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, 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)); 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; sym->entries.data[sym->entries.size]->scope = scope; sym->entries.data[sym->entries.size]->state = state_flag; 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, node_t* node) { assert(sym); sym_entry_t* res = NULL; for (size_t i=0; ientries.size; i++) { sym_entry_t* entry = sym->entries.data[i]; node_t* itr = node_try_find_parent(node, NODE_BLOCK); node_t* entry_block = node_try_find_parent(entry->node, NODE_BLOCK); while (itr && itr != entry_block) { itr = (node_t*) itr->parent; } 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, node); } 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; ientries.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; }