diff options
-rw-r--r-- | semantics.c | 47 | ||||
-rw-r--r-- | semantics.h | 8 | ||||
-rw-r--r-- | test.c | 60 |
3 files changed, 92 insertions, 23 deletions
diff --git a/semantics.c b/semantics.c index 0f95d2c..b38b150 100644 --- a/semantics.c +++ b/semantics.c @@ -23,25 +23,32 @@ CTable_t ctable_create(Hashfunc_t hfunc) { #endif void *ctable_lookup(CTable_t ct, const char *key) { - unsigned int hv = (ct->hfunc(key)) % MAX_TABLE_SIZE; + unsigned int hv = ct->hfunc(key) % MAX_TABLE_SIZE; CTNode *p = ct->head[hv]; for (; p; p = p->next) - if (strcmp(p->key, key)) + 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); +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, unsigned int hv, int max_lvl) { +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) { @@ -66,22 +73,30 @@ CScope_t cscope_create() { return p; } -void cscope_push_var(CScope_t cs, CVar *var) { +int 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); + if (ctable_insert(cs->tvar, var->name, var, cs->lvl)) + { + var->next = cs->top->vhead; + cs->top->vhead = var; + return 1; + } + else return 0; /* naming conflict */ } -void cscope_push_type(CScope_t cs, CType *type) { +int 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); + if (ctable_insert(cs->ttype, type->name, type, cs->lvl)) + { + type->next = cs->top->thead; + cs->top->thead = type; + return 1; + } + else return 0; /* naming conflict */ } void cscope_enter(CScope_t cs) { @@ -100,9 +115,9 @@ void cscope_exit(CScope_t cs) { 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); + ctable_clip(cs->tvar, vp->name, cs->lvl); for (tp = top_o->thead; tp; tp = tp->next) - ctable_clip(cs->ttype, bkdr_hash(tp->name), cs->lvl); + ctable_clip(cs->ttype, tp->name, cs->lvl); free(top_o); } diff --git a/semantics.h b/semantics.h index 93ab787..166f9a8 100644 --- a/semantics.h +++ b/semantics.h @@ -70,8 +70,8 @@ CTable_t ctable_create(Hashfunc_t hfunc, Printfunc_t pfunc); CTable_t ctable_create(Hashfunc_t hfunc); #endif void *ctable_lookup(CTable_t ct, const char *key); -void ctable_insert(CTable_t ct, const char *key, void *val, int lvl); -void ctable_clip(CTable_t ct, unsigned int hv, int max_lvl); +int ctable_insert(CTable_t ct, const char *key, void *val, int lvl); +void ctable_clip(CTable_t ct, const char *key, int max_lvl); void ctable_debug_print(CTable_t ct); typedef struct CSNode { @@ -91,8 +91,8 @@ typedef struct CScope { CScope_t cscope_create(); CVar *cscope_lookup_var(CScope_t cs, const char *name); CType *cscope_lookup_type(CScope_t cs, const char *name); -void cscope_push_var(CScope_t cs, CVar *var); -void cscope_push_type(CScope_t cs, CType *type); +int cscope_push_var(CScope_t cs, CVar *var); +int cscope_push_type(CScope_t cs, CType *type); void cscope_enter(CScope_t cs); void cscope_exit(CScope_t cs); void cscope_debug_print(CScope_t cs); @@ -1,7 +1,23 @@ #include <stdlib.h> +#include <stdio.h> #include "semantics.h" -#define PV(str) cscope_push_var(scope, newvar(str)) -#define PT(str) cscope_push_type(scope, newtype(str)) +#define PV(str) \ + do \ + { \ + if (cscope_push_var(scope, newvar(str))) \ + fprintf(stderr, "Successfully pushed var: %s\n", str); \ + else \ + fprintf(stderr, "Naming conflicts deteced: %s\n", str); \ + } while(0) + +#define PT(str) \ + do \ + { \ + if (cscope_push_type(scope, newtype(str))) \ + fprintf(stderr, "Successfully pushed type: %s\n", str); \ + else \ + fprintf(stderr, "Naming conflicts deteced: %s\n", str); \ + } while(0) CVar_t newvar(const char *name) { return cvar_create(name, NULL); @@ -11,7 +27,7 @@ CType_t newtype(const char *name) { return ctype_create(name, 0); } -int main() { +void manual() { CScope_t scope = cscope_create(); PV("a"); PV("b"); @@ -29,10 +45,48 @@ int main() { PV("yay"); PV("world"); PT("CType"); + PV("a"); cscope_debug_print(scope); cscope_exit(scope); cscope_debug_print(scope); cscope_exit(scope); cscope_debug_print(scope); +} + +char *str_gen(int len) { + int i; + char *str = malloc(len); + for (i = 0; i < len; i++) + str[i] = rand() % 2 + 'a'; + return str; +} + +void autoforce() { + static const int max_lvl = 100, + max_push = 10; + int i, j; + CScope_t scope = cscope_create(); + for (i = 0; i < max_lvl; i++) + { + cscope_enter(scope); + int push = rand() % max_push; + for (j = 0; j < push; j++) + { + int len = rand() % 3 + 1; + int opt = rand() & 1; + if (opt) PV(str_gen(len)); + else PT(str_gen(len)); + } + } + for (i = 0; i < max_lvl; i++) + { + cscope_debug_print(scope); + cscope_exit(scope); + } +} + +int main() { +/* manual(); */ + autoforce(); return 0; } |