aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c4
-rw-r--r--semantics.c89
-rw-r--r--semantics.h70
-rw-r--r--semantics.h.gchbin0 -> 1528208 bytes
-rw-r--r--semantics.obin0 -> 4208 bytes
5 files changed, 161 insertions, 2 deletions
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 <stdlib.h>
+#include <string.h>
+#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
--- /dev/null
+++ b/semantics.h.gch
Binary files differ
diff --git a/semantics.o b/semantics.o
new file mode 100644
index 0000000..2baba92
--- /dev/null
+++ b/semantics.o
Binary files differ