aboutsummaryrefslogblamecommitdiff
path: root/semantics.c
blob: cb12c29681e6cf332d1a6248de49ea63c9f3a4b2 (plain) (tree)
1
2
3
4
5
6
7
                   
                   
                   
                  


                                                








                                                             
                                          

                                                          


                      
      
 
                                                   


                                                        
                                



                                
                                                                      




















                                                             
                
                  



                                                     

                                        

                    
             


                                              


                    





                                                     


                    







                                                        

                     




                               
                            

              


                                              
                                                            
                                              
                                                             
                

 

                                      
                                        





                                                 
                                                                        

                                  
                                        




                                      
                                                
















                                              
                                                

 
                                                        


                                         
                                                          

                                          





                                            


























                                                   
 
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "semantics.h"
#define NEW(type) ((type *)malloc(sizeof(type)))

#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

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 */
}

void ctable_insert(CTable_t ct, const char *key, void *val, int lvl) {
    unsigned int hv = (ct->hfunc(key)) % MAX_TABLE_SIZE;
    CTNode *np = NEW(CTNode);
    np->key = key;
    np->val = val;
    np->lvl = lvl;
    np->next = ct->head[hv];
    ct->head[hv] = np;
}

void ctable_clip(CTable_t ct, unsigned int hv, int max_lvl) {
    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, cvar_print);
    p->ttype = ctable_create(bkdr_hash, ctype_print);
#else
    p->tvar = ctable_create(bkdr_hash);
    p->ttype = ctable_create(bkdr_hash);
#endif
    cscope_enter(p);
    return p;
}

void cscope_push_var(CScope_t cs, CVar *var) {
#ifdef CIBIC_DEBUG
    assert(cs->top);
#endif
    var->next = cs->top->vhead;
    cs->top->vhead = var;
    ctable_insert(cs->tvar, var->name, var, cs->lvl);
}

void cscope_push_type(CScope_t cs, CType *type) {
#ifdef CIBIC_DEBUG
    assert(cs->top);
#endif
    type->next = cs->top->thead;
    cs->top->thead = type;
    ctable_insert(cs->ttype, type->name, type, cs->lvl);
}

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;
    CVar *vp;
    CType *tp;
    cs->lvl--;
    cs->top = top_o->next;
    for (vp = top_o->vhead; vp; vp = vp->next)
        ctable_clip(cs->tvar, bkdr_hash(vp->name), cs->lvl);
    for (tp = top_o->thead; tp; tp = tp->next)
        ctable_clip(cs->ttype, bkdr_hash(tp->name), cs->lvl);
    free(top_o);
}

void ctable_debug_print(CTable_t ct) {
    int i;
    fprintf(stderr, "*** CTable ***\n");
    for (i = 0; i < MAX_TABLE_SIZE; i++)
        if (ct->head[i])
        {
            CTNode *p;
            fprintf(stderr, "[%04d]", i);
            for (p = ct->head[i]; p; p = p->next)
                fprintf(stderr, "->[%s:%d]", ct->pfunc(p->val), p->lvl);
            fprintf(stderr, "\n");
        }
    fprintf(stderr, "*** CTable ***\n");
}

void cscope_debug_print(CScope_t cs) {
    int lvl = cs->lvl;
    CSNode *p;
    fprintf(stderr, "