From ef137d8acf0e48da2891066ba4bb2063e7bedbf5 Mon Sep 17 00:00:00 2001 From: Teddy Date: Wed, 26 Mar 2014 13:34:52 +0800 Subject: start to implement semantics part --- ast.c | 4 +-- semantics.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ semantics.h | 70 ++++++++++++++++++++++++++++++++++++++++++++ semantics.h.gch | Bin 0 -> 1528208 bytes semantics.o | Bin 0 -> 4208 bytes 5 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 semantics.c create mode 100644 semantics.h create mode 100644 semantics.h.gch create mode 100644 semantics.o diff --git a/ast.c b/ast.c index 6bbc176..b07eca8 100644 --- a/ast.c +++ b/ast.c @@ -306,7 +306,7 @@ char *cnode_debug_type_repr(CNode *ast) { case '~': type = "~"; break; case '!': type = "!"; break; case KW_SIZEOF: type = "sizeof"; break; - case EXP_POSTFIX: type = "pofix"; break; + case EXP_POSTFIX: type = "postfix"; break; case POSTFIX_ARR: type = "arr"; break; case POSTFIX_CALL: type = "call"; break; case POSTFIX_DOT: type = "dot"; break; @@ -367,7 +367,7 @@ char *cnode_debug_type_repr(CNode *ast) { assert(type); } if (aptr == abuff) - sprintf(buffer, "%s(%d,%d)", type, + sprintf(buffer, "%s(%d:%d)", type, ast->loc.row, ast->loc.col); else { diff --git a/semantics.c b/semantics.c new file mode 100644 index 0000000..865ae2a --- /dev/null +++ b/semantics.c @@ -0,0 +1,89 @@ +#include +#include +#include "semantics.h" +#define NEW(type) ((type *)malloc(sizeof(type))) + +CTable_t ctable_create(Cmp_t cmp, 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) { + 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)) + return p->val; + return NULL; /* not found */ +} + +void ctable_insert(CTable_t ct, 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 = 0; + p->top = NULL; + p->tvar = ctable_create(var_cmp, var_hfunc); + p->ttype = ctable_create(type_cmp, type_hfunc); +} + +void cscope_push_var(CScope_t cs, CVar *var) { + 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) { + 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; + cs->top = np; + cs->lvl++; +} + +void cscope_exit(CScope_t cs) { + CSNode *lower = cs->top->next; + CVar *vp; + CType *tp; + for (vp = cs->top->vhead; vp; vp = vp->next) + ctable_clip(cs->tvar, var_hfunc(vp->name), cs->lvl); + for (tp = cs->top->thead; tp; tp = tp->next) + ctable_clip(cs->ttype, type_hfunc(tp->name), cs->lvl); + free(cs->top); + cs->top = lower; + cs->lvl--; +} + +CVar *cscope_lookup_var(CScope_t cs, char *name) { + return ctable_lookup(cs->tvar, name); +} + +CType *cscope_lookup_type(CScope_t cs, char *name) { + return ctable_lookup(cs->ttype, name); +} diff --git a/semantics.h b/semantics.h new file mode 100644 index 0000000..59a7a81 --- /dev/null +++ b/semantics.h @@ -0,0 +1,70 @@ +#ifndef SEMANTICS_H +#define SEMANTICS_H + +#define MAX_TABLE_SIZE 1021 + +struct CTable; + +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 { + char *name; + struct CType *next; + struct CType *fields; /* for a struct or union */ + int size; /* memory footprint */ +} CType; + +typedef int (*Cmp_t)(void *, void *); +typedef unsigned int (*Hashfunc_t) (char *); +typedef struct CTable *CTable_t; + +typedef struct CTNode { + char *key; + void *val; + struct CTNode *next; + int lvl; +} 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); +void ctable_clip(CTable_t ct, unsigned int hv, int max_lvl); + +typedef struct CSNode { + struct CVar *vhead; + struct CType *thead; + struct CSNode *next; +} CSNode; + +typedef struct CScope *CScope_t; +typedef struct CScope { + int lvl; + struct CSNode *top; + struct CTable *tvar; + struct CTable *ttype; +} CScope; + +CScope_t cscope_create(); +CVar *cscope_lookup_var(CScope_t cs, char *name); +CType *cscope_lookup_type(CScope_t cs, 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; +#endif diff --git a/semantics.h.gch b/semantics.h.gch new file mode 100644 index 0000000..a1bff99 Binary files /dev/null and b/semantics.h.gch differ diff --git a/semantics.o b/semantics.o new file mode 100644 index 0000000..2baba92 Binary files /dev/null and b/semantics.o differ -- cgit v1.2.3