#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "semantics.h"
#include "ast.h"
#define NEW(type) ((type *)malloc(sizeof(type)))
#define CHECK_TYPE(p, _type) assert(p->type == _type)
#define ERROR(ast) print_error(err_buff, NULL, (ast)->loc.row, (ast)->loc.col, 0)
#define WARNING(ast) print_error(err_buff, NULL, (ast)->loc.row, (ast)->loc.col, 1)
#ifdef CIBIC_DEBUG
CTable_t ctable_create(Hashfunc_t hfunc, Printfunc_t pfunc) {
CTable_t ct = NEW(CTable);
memset(ct->head, 0, sizeof(CTNode*) * MAX_TABLE_SIZE);
ct->hfunc = hfunc;
ct->pfunc = pfunc;
return ct;
}
#else
CTable_t ctable_create(Hashfunc_t hfunc) {
CTable_t ct = NEW(CTable);
memset(ct->head, 0, sizeof(CTNode*) * MAX_TABLE_SIZE);
ct->hfunc = hfunc;
return ct;
}
#endif
extern void print_error(char *, char *, int, int, int);
extern char *load_line(int);
static char err_buff[MAX_ERROR_BUFF];
static CType_t basic_type_int;
static CType_t basic_type_char;
static CType_t basic_type_void;
void *ctable_lookup(CTable_t ct, const char *key) {
unsigned int hv = ct->hfunc(key) % MAX_TABLE_SIZE;
CTNode *p = ct->head[hv];
for (; p; p = p->next)
if (!strcmp(p->key, key))
return p->val;
return NULL; /* not found */
}
int ctable_insert(CTable_t ct, const char *key, void *val, int lvl) {
unsigned int hv = ct->hfunc(key) % MAX_TABLE_SIZE;
CTNode *p = ct->head[hv];
CTNode *np;
for (; p && p->lvl == lvl; p = p->next)
if (!strcmp(p->key, key))
return 0; /* conflict */
np = NEW(CTNode);
np->key = key;
np->val = val;
np->lvl = lvl;
np->next = ct->head[hv];
ct->head[hv] = np;
return 1;
}
void ctable_clip(CTable_t ct, const char *key, int max_lvl) {
unsigned int hv = ct->hfunc(key) % MAX_TABLE_SIZE;
CTNode *p = ct->head[hv], *np;
for (; p && p->lvl > max_lvl; p = np)
{
np = p->next;
free(p);
}
ct->head[hv] = p;
}
CScope_t cscope_create() {
CScope_t p = NEW(CScope);
p->lvl = -1;
p->top = NULL;
#ifdef CIBIC_DEBUG
p->tvar = ctable_create(bkdr_hash, ctable_cvar_print);
p->ttype = ctable_create(bkdr_hash, ctable_ctype_print);
#else
p->tvar = ctable_create(bkdr_hash);
p->ttype = ctable_create(bkdr_hash);
#endif
cscope_enter(p);
return p;
}
int cscope_push_var(CScope_t cs, CVar_t var) {
#ifdef CIBIC_DEBUG
assert(cs->top);
#endif
if (ctable_insert(cs->tvar, var->name, var, cs->lvl))
{
CSVar *csvar = NEW(CSVar);
csvar->var = var;
csvar->next = cs->top->vhead;
cs->top->vhead = csvar;
return 1;
}
else return 0; /* naming conflict */
}
int cscope_push_type(CScope_t cs, CType_t type) {
#ifdef CIBIC_DEBUG
assert(cs->top);
#endif
if (ctable_insert(cs->ttype, type->name, type, cs->lvl))
{
CSType *cstype = NEW(CSType);
cstype->type = type;
cstype->next = cs->top->thead;
cs->top->thead = cstype;
return 1;
}
else return 0; /* naming conflict */
}
void cscope_enter(CScope_t cs) {
CSNode *np = NEW(CSNode);
np->next = cs->top;
np->vhead = NULL;
np->thead = NULL;
cs->top = np;
cs->lvl++;
}
void cscope_exit(CScope_t cs) {
CSNode *top_o = cs->top;
CSVar *vp;
CSType *tp;
cs->lvl--;
cs->top = top_o->next;
for (vp = top_o->vhead; vp; vp = vp->next)