aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--semantics.c47
-rw-r--r--semantics.h8
-rw-r--r--test.c60
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);
diff --git a/test.c b/test.c
index 3a80510..dc564d9 100644
--- a/test.c
+++ b/test.c
@@ -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;
}