nctref/src/vartable.c

93 lines
2.5 KiB
C
Raw Normal View History

2023-08-27 19:48:06 +03:00
#include"vartable.h"
#include"utils.h"
#include<stdlib.h>
#include<string.h>
struct ReachingDefs *reachingdefs_push(struct ReachingDefs *this) {
struct ReachingDefs *ret = calloc(1, sizeof(*ret));
ret->parent = this;
return ret;
}
struct ReachingDefs *reachingdefs_coalesce(struct ReachingDefs *this) {
struct ReachingDefs *parent = this->parent;
if(parent) {
parent->defs = realloc(parent->defs, sizeof(*parent->defs) * (parent->defCount + this->defCount));
memcpy(&parent->defs[parent->defCount], this->defs, sizeof(*this->defs) * this->defCount);
parent->defCount += this->defCount;
}
free(this->defs);
free(this);
return parent;
}
void reachingdefs_set(struct ReachingDefs *this, union AST *def) {
this->defCount = 1;
this->defs = realloc(this->defs, sizeof(*this->defs) * this->defCount);
this->defs[0] = def;
}
2023-08-27 19:48:06 +03:00
VarTable *vartable_new(VarTable *parent) {
VarTable *ret = malloc(sizeof(*ret));
ret->parent = parent;
ret->count = 0;
ret->names = NULL;
ret->data = NULL;
return ret;
}
VarTableEntry *vartable_get(VarTable *this, const char *name) {
for(size_t v = 0; v < this->count; v++) {
if(!strcmp(name, this->names[v])) return this->data[v];
}
return NULL;
}
VarTableEntry *vartable_find(VarTable *this, const char *name) {
VarTable *tbl = this;
while(tbl) {
VarTableEntry *entry = vartable_get(tbl, name);
if(entry) {
return entry;
}
tbl = tbl->parent;
}
return NULL;
}
VarTableEntry *vartable_set(VarTable *this, const char *name, VarTableEntry *e) {
this->names = realloc(this->names, sizeof(*this->names) * (this->count + 1));
this->data = realloc(this->data, sizeof(*this->data) * (this->count + 1));
this->names[this->count] = name;
this->data[this->count] = e;
this->count++;
if(e->kind == VARTABLEENTRY_VAR) e->data.var.name = name;
2023-08-27 19:48:06 +03:00
return e;
}
void vartable_new_reachingdefs_for_all_vars(VarTable *this) {
for(size_t i = 0; i < this->count; i++) {
if(this->data[i]->kind == VARTABLEENTRY_VAR) {
this->data[i]->data.var.reachingDefs = reachingdefs_push(this->data[i]->data.var.reachingDefs);
}
}
if(this->parent) {
vartable_new_reachingdefs_for_all_vars(this->parent);
}
}
void vartable_coalesce_reachingdefs_for_all_vars(VarTable *this) {
for(size_t i = 0; i < this->count; i++) {
if(this->data[i]->kind == VARTABLEENTRY_VAR) {
this->data[i]->data.var.reachingDefs = reachingdefs_coalesce(this->data[i]->data.var.reachingDefs);
}
}
if(this->parent) {
vartable_coalesce_reachingdefs_for_all_vars(this->parent);
}
}