113 lines
2.8 KiB
C
113 lines
2.8 KiB
C
#include"vartable.h"
|
|
|
|
#include"utils.h"
|
|
#include<stdlib.h>
|
|
#include<string.h>
|
|
#include<assert.h>
|
|
#include<stdio.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;
|
|
this->excludeParent = 1;
|
|
}
|
|
|
|
Scope *scope_new(Scope *parent) {
|
|
Scope *ret = calloc(1, sizeof(*ret));
|
|
ret->parent = parent;
|
|
ret->count = 0;
|
|
ret->names = NULL;
|
|
ret->data = NULL;
|
|
|
|
return ret;
|
|
}
|
|
|
|
ScopeItem *scope_get(Scope *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;
|
|
}
|
|
|
|
ScopeItem *scope_find(Scope *this, const char *name) {
|
|
Scope *tbl = this;
|
|
while(tbl) {
|
|
ScopeItem *entry = scope_get(tbl, name);
|
|
if(entry) {
|
|
return entry;
|
|
}
|
|
tbl = tbl->parent;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
ScopeItem *scope_set(Scope *this, const char *name, ScopeItem *e) {
|
|
name = strdup(name);
|
|
|
|
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 == SCOPEITEM_VAR) e->data.var.name = name;
|
|
e->owner = this;
|
|
return e;
|
|
}
|
|
|
|
ScopeItem *scope_find_int(Scope *scope, intmax_t val, const char *suffix) {
|
|
char buf[64];
|
|
snprintf(buf, sizeof(buf), "%li%s", val, suffix ? suffix : "");
|
|
|
|
return scope_find(scope, buf);
|
|
}
|
|
|
|
Scope *scope_merge(Scope *child) {
|
|
Scope *parent = child->parent;
|
|
|
|
parent->names = realloc(parent->names, sizeof(*parent->names) * (parent->count + child->count));
|
|
parent->data = realloc(parent->data, sizeof(*parent->data) * (parent->count + child->count));
|
|
|
|
for(size_t i = 0; i < child->count; i++) {
|
|
child->data[i]->owner = parent;
|
|
|
|
parent->names[parent->count] = child->names[i];
|
|
parent->data[parent->count] = child->data[i];
|
|
|
|
parent->count++;
|
|
}
|
|
|
|
//free(child->names);
|
|
//free(child->data);
|
|
//free(child);
|
|
|
|
return parent;
|
|
}
|
|
|
|
void vte_precolor(ScopeItem *vte, int class, int color) {
|
|
assert(vte->kind == SCOPEITEM_VAR && "vte must be var");
|
|
assert(!vte->data.var.precolored && "already precolored");
|
|
|
|
vte->data.var.precolored = true;
|
|
vte->data.var.registerClass = class;
|
|
vte->data.var.color = color;
|
|
}
|