#include"vartable.h" #include"utils.h" #include #include 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; this->excludeParent = 1; } 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; 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); } }