aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <ted.sybil@gmail.com>2014-04-16 18:51:07 +0800
committerTeddy <ted.sybil@gmail.com>2014-04-16 18:51:07 +0800
commit950dd4b0688dee3f7a90105a1225c8ba41123282 (patch)
treec39d3023f9ed311b5e59a9b4879d8bc24d0fa243
parent27205d8a475e3a8ddafacd4426635187735a35f5 (diff)
pointer offest calculate
-rw-r--r--Makefile1
-rw-r--r--ast.c4
-rw-r--r--semantics.c59
-rw-r--r--semantics.h2
4 files changed, 41 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 6323a21..b4bb524 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,7 @@ db:
cibic: lex.yy.o cibic.tab.o ast.o main.o semantics.o
mkdir -p bin
gcc -o bin/cibic lex.yy.o cibic.tab.o ast.o main.o semantics.o
+ cp bin/cibic cibic
lex.yy.o: lex.yy.c cibic.tab.c
gcc -c lex.yy.c
cibic.tab.o: cibic.tab.c
diff --git a/ast.c b/ast.c
index c02ab41..866588f 100644
--- a/ast.c
+++ b/ast.c
@@ -400,9 +400,9 @@ char *cnode_debug_type_repr(CNode *ast) {
}
head += sprintf(head, "(%d:%d)", ast->loc.row, ast->loc.col);
if (ast->ext.type)
- sprintf(head, "->(var:%lx type:%lx ic:%d cv:%d)",
+ sprintf(head, "->(var:%lx type:%lx ic:%d cv:%d off:%d)",
(size_t)ast->ext.var, (size_t)ast->ext.type,
- ast->ext.is_const, ast->ext.const_val);
+ ast->ext.is_const, ast->ext.const_val, ast->ext.offest);
}
return buffer;
}
diff --git a/semantics.c b/semantics.c
index 930a3cf..127783d 100644
--- a/semantics.c
+++ b/semantics.c
@@ -311,7 +311,7 @@ int calc_size(CType_t type) {
}
break;
case CVOID: return -1;
- case CFUNC: return 0;
+ case CFUNC: return 1;
}
return (type->size = size);
}
@@ -855,6 +855,12 @@ ExpType exp_check_add(ExpType op1, ExpType op2, CNode *p, char kind) {
ERROR((p, "invalid use of undefined type"));
if (t2 == CPTR && calc_size(op2.type->rec.ref) == -1)
ERROR((p, "invalid use of undefined type"));
+ if (t1 == CARR)
+ {
+ CType_t ptr = ctype_create("", CPTR, NULL);
+ ptr->rec.ref = op1.type->rec.arr.elem;
+ op1.type = ptr;
+ }
if (kind == '-')
{
if (IS_PTR(t2) && !IS_PTR(t1))
@@ -865,25 +871,32 @@ ExpType exp_check_add(ExpType op1, ExpType op2, CNode *p, char kind) {
if (!((IS_INT(t1) || IS_PTR(t1)) && IS_INT(t2)))
ERROR((p, "invalid operands to binary operator"));
}
- if ((p->ext.is_const = lch->ext.is_const && rch->ext.is_const))
+ if ((p->ext.is_const = rch->ext.is_const))
{
- int l = lch->ext.const_val,
- r = rch->ext.const_val,
- *a = &(p->ext.const_val);
+ int r = rch->ext.const_val;
if (IS_PTR(t1))
{
- /* TODO: constant pointer folding */
- if (t1 == CPTR)
- p->ext.const_val = op1.type->rec.ref->size * r;
- else /* array */
- p->ext.const_val = op1.type->rec.arr.elem->size * r;
+ CType_t type;
+ p->ext.var = p->chd->ext.var;
+ if (t1 == CPTR) type = op1.type->rec.ref;
+ else type = op1.type->rec.arr.elem;
+ p->ext.offest = p->chd->ext.offest + calc_size(type) * r;
}
- else
+ if ((p->ext.is_const &= lch->ext.is_const))
{
- switch (kind)
+ int l = lch->ext.const_val,
+ *a = &(p->ext.const_val);
+ if (IS_PTR(t1))
+ {
+ /* TODO: const pointer */
+ }
+ else
{
- case '+': *a = l + r; break;
- case '-': *a = l - r; break;
+ switch (kind)
+ {
+ case '+': *a = l + r; break;
+ case '-': *a = l - r; break;
+ }
}
}
}
@@ -1065,33 +1078,34 @@ ExpType exp_check_postfix(CNode *p, CScope_t scope) {
if (!IS_INT(t2))
ERROR((p, "array subscript is not an integer"));
if (t1 == CARR)
- {
op1.type = op1.type->rec.arr.elem;
- p->ext.is_const = p->chd->ext.is_const;
- }
else
- {
op1.type = op1.type->rec.ref;
+ if (post->chd->ext.is_const)
+ {
+ p->ext.offest = p->chd->ext.offest + \
+ calc_size(op1.type) * post->chd->ext.const_val;
+ p->ext.var = p->chd->ext.var;
}
+ p->ext.is_const = 0;
op1.lval = 1;
break;
case POSTFIX_CALL:
if (!(t1 == CPTR && op1.type->rec.ref->type == CFUNC))
ERROR((p, "called object is not a function"));
{
- CNode *arg = post->chd->chd;
+ CNode *arg = post->chd->chd, *t;
CType_t func = p->chd->ext.type;
CVar_t param;
/* pointer to function */
if (func->type == CPTR) func = func->rec.ref;
+ for (t = arg; t; t = t->next)
+ semantics_exp(t, scope);
if ((param = func->rec.func.params))
{
for (; arg && param;
arg = arg->next, param = param->next)
- {
- semantics_exp(arg, scope);
exp_check_aseq_(param->type, arg->ext.type, arg);
- }
if (arg || param)
ERROR((p, "too many/few arguments to the function"));
}
@@ -1155,6 +1169,7 @@ ExpType semantics_exp(CNode *p, CScope_t scope) {
else
{
p->ext.type = lu->rec.type;
+ p->ext.var = NULL;
res.type = p->ext.type;
res.lval = res.type->type == CFUNC;
POINTER_CONV(res.type, p);
diff --git a/semantics.h b/semantics.h
index d301ab0..ca97633 100644
--- a/semantics.h
+++ b/semantics.h
@@ -17,7 +17,7 @@ struct CVar {
const char *name;
CVar_t next; /* next in the linked list */
CType_t type;
- int offset;
+ int start;
CNode *ast;
};