aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-03-26 18:40:45 +0800
committerTeddy <ted.sybil@gmail.com>2014-03-26 18:40:45 +0800
commitd2f316adaeae270e6c4e9cba040e07de3d11e737 (patch)
tree4687ffb4cbfbc7654b02c0e1f7fa9106bc2073da
parent37aaf73ed35046e8d7b1bbbb95c899b224ccb606 (diff)
...
-rw-r--r--Makefile2
-rw-r--r--ast.c12
-rw-r--r--semantics.c38
-rw-r--r--semantics.h38
4 files changed, 59 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index cfb1849..35fe25f 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ cibic.tab.o: cibic.tab.c
main.o: main.c
gcc -c main.c -g -Wall -Wextra
ast.o: ast.c
- gcc -c ast.c -g -Wall -Wextra -DCNODE_DEBUG
+ gcc -c ast.c -g -Wall -Wextra -DCIBIC_DEBUG
lex.yy.c: cibic.l
flex cibic.l
cibic.tab.c: cibic.y
diff --git a/ast.c b/ast.c
index b07eca8..239cab6 100644
--- a/ast.c
+++ b/ast.c
@@ -45,7 +45,7 @@ CNode *cnode_create_general(int type, int subtype, int pnum, va_list ap) {
for (i = 0; i < pnum; i++)
{
CNode *subexp = va_arg(ap, CNode*);
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(subexp->next == NULL);
#endif
subexp->next = exp->chd;
@@ -145,7 +145,7 @@ CNode *cnode_create_initr(int initr_type, CNode *body) {
CNode *cnode_create_decl(CNode *type, CNode *init_declrs) {
CNode *decl = NEW_CNODE;
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(type->next == NULL);
assert(init_declrs->next == NULL);
#endif
@@ -158,7 +158,7 @@ CNode *cnode_create_decl(CNode *type, CNode *init_declrs) {
CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *stmt) {
CNode *func = NEW_CNODE;
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(type->next == NULL);
assert(plain_decl->next == NULL);
assert(params->next == NULL);
@@ -175,7 +175,7 @@ CNode *cnode_create_func(CNode *type, CNode *plain_decl, CNode *params, CNode *s
CNode *cnode_create_init_declr(CNode *declr, CNode *initr) {
CNode *init_declr = NEW_CNODE;
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(declr->next == NULL);
assert(initr->next == NULL);
#endif
@@ -188,7 +188,7 @@ CNode *cnode_create_init_declr(CNode *declr, CNode *initr) {
CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs) {
CNode *field = NEW_CNODE;
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(type_spec->next == NULL);
assert(declrs->next == NULL);
#endif
@@ -201,7 +201,7 @@ CNode *cnode_create_struct_field(CNode *type_spec, CNode *declrs) {
CNode *cnode_create_plain_decl(CNode *type_spec, CNode *declr) {
CNode *pdecl = NEW_CNODE;
-#ifdef CNODE_DEBUG
+#ifdef CIBIC_DEBUG
assert(type_spec->next == NULL);
assert(declr->next == NULL);
#endif
diff --git a/semantics.c b/semantics.c
index 865ae2a..9178316 100644
--- a/semantics.c
+++ b/semantics.c
@@ -3,24 +3,23 @@
#include "semantics.h"
#define NEW(type) ((type *)malloc(sizeof(type)))
-CTable_t ctable_create(Cmp_t cmp, Hashfunc_t hfunc) {
+CTable_t ctable_create(Hashfunc_t hfunc) {
CTable_t ct = NEW(CTable);
memset(ct->head, 0, sizeof(CTNode*) * MAX_TABLE_SIZE);
- ct->cmp = cmp;
ct->hfunc = hfunc;
return ct;
}
-void *ctable_lookup(CTable_t ct, char *key) {
+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 (ct->cmp(p->key, key))
+ if (strcmp(p->key, key))
return p->val;
return NULL; /* not found */
}
-void ctable_insert(CTable_t ct, char *key, void *val, int lvl) {
+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;
@@ -44,17 +43,24 @@ CScope_t cscope_create() {
CScope_t p = NEW(CScope);
p->lvl = 0;
p->top = NULL;
- p->tvar = ctable_create(var_cmp, var_hfunc);
- p->ttype = ctable_create(type_cmp, type_hfunc);
+ p->tvar = ctable_create(bkdr_hash);
+ p->ttype = ctable_create(bkdr_hash);
+ 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);
@@ -63,6 +69,8 @@ void cscope_push_type(CScope_t cs, CType *type) {
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++;
}
@@ -72,18 +80,26 @@ void cscope_exit(CScope_t cs) {
CVar *vp;
CType *tp;
for (vp = cs->top->vhead; vp; vp = vp->next)
- ctable_clip(cs->tvar, var_hfunc(vp->name), cs->lvl);
+ ctable_clip(cs->tvar, bkdr_hash(vp->name), cs->lvl);
for (tp = cs->top->thead; tp; tp = tp->next)
- ctable_clip(cs->ttype, type_hfunc(tp->name), cs->lvl);
+ ctable_clip(cs->ttype, bkdr_hash(tp->name), cs->lvl);
free(cs->top);
cs->top = lower;
cs->lvl--;
}
-CVar *cscope_lookup_var(CScope_t cs, char *name) {
+CVar *cscope_lookup_var(CScope_t cs, const char *name) {
return ctable_lookup(cs->tvar, name);
}
-CType *cscope_lookup_type(CScope_t cs, char *name) {
+CType *cscope_lookup_type(CScope_t cs, const char *name) {
return ctable_lookup(cs->ttype, name);
}
+
+unsigned int bkdr_hash(const char *str) {
+ unsigned int seed = 131;
+ unsigned int hv = 0;
+ while (*str)
+ hv = hv * seed + (unsigned)(*str++);
+ return hv;
+}
diff --git a/semantics.h b/semantics.h
index 59a7a81..b3d2942 100644
--- a/semantics.h
+++ b/semantics.h
@@ -9,23 +9,37 @@ typedef struct CVar{
char *name;
struct CVar *next; /* next in the linked list */
struct CType *type;
- int ref_lvl; /* reference level: >0 for pointers */
int offset;
} CVar;
typedef struct CType {
+ enum {
+ INT,
+ CHAR,
+ VOID,
+ STRUCT,
+ UNION,
+ ARR,
+ PTR
+ } type;
char *name;
struct CType *next;
- struct CType *fields; /* for a struct or union */
+ union {
+ struct CType *fields; /* for a struct or union */
+ struct CType *ref; /* for a pointer */
+ struct {
+ struct CType *elem;
+ int len;
+ } arr; /* for an array */
+ } rec;
int size; /* memory footprint */
} CType;
-typedef int (*Cmp_t)(void *, void *);
-typedef unsigned int (*Hashfunc_t) (char *);
+typedef unsigned int (*Hashfunc_t) (const char *);
typedef struct CTable *CTable_t;
typedef struct CTNode {
- char *key;
+ const char *key;
void *val;
struct CTNode *next;
int lvl;
@@ -33,14 +47,13 @@ typedef struct CTNode {
typedef struct CTable {
struct CTNode *head[MAX_TABLE_SIZE];
- Cmp_t cmp;
Hashfunc_t hfunc;
} CTable;
-CTable_t ctable_create(Cmp_t cmp, Hashfunc_t hfunc);
-void *ctable_lookup(CTable_t ct, char *key);
-void ctable_insert(CTable_t ct, char *key, void *val, int lvl);
+CTable_t ctable_create(Hashfunc_t hfunc);
+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);
typedef struct CSNode {
@@ -58,13 +71,12 @@ typedef struct CScope {
} CScope;
CScope_t cscope_create();
-CVar *cscope_lookup_var(CScope_t cs, char *name);
-CType *cscope_lookup_type(CScope_t cs, char *name);
+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);
void cscope_enter(CScope_t cs);
void cscope_exit(CScope_t cs);
-Cmp_t var_cmp, type_cmp;
-Hashfunc_t var_hfunc, type_hfunc;
+unsigned int bkdr_hash(const char *str);
#endif