scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 1ab6ca3ad193716d021f635aaf38cfd2e1d07902
parent ca11c7774accc8688b3614e5ec367a802ae7643d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 31 Mar 2014 17:16:08 +0200

Multiply index by array element size in array index expression

The offset of an element of an array is the index value multiply
by the size of the elements of the array, and it is how this new
patch makes it.

Diffstat:
Mcc.h | 5+++--
Mcode.c | 15+++++++++++++++
Mexpr.c | 7+++++--
3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/cc.h b/cc.h @@ -213,7 +213,7 @@ typedef struct node { typedef void (*Inst)(Node *); enum { - OCAST, OPTR, OADD, OARY + OCAST, OPTR, OADD, OARY, OSIZE, OMUL }; extern void @@ -224,7 +224,8 @@ extern Node *node(Inst code, Type *tp, union unode u, uint8_t nchilds), *unarycode(char op, Type *tp, Node *child), *bincode(char op, Type *tp, Node *np1, Node *np2), - *castcode(Node *child, Type *tp); + *castcode(Node *child, Type *tp), + *sizeofcode(Type *tp); #define SYM(s) ((union unode) {.sym = s}) #define OP(s) ((union unode) {.op = s}) diff --git a/code.c b/code.c @@ -6,7 +6,9 @@ char *opcodes[] = { [OADD] = "+", + [OMUL] = "*", [OARY] = "'", + [OSIZE] = "#", [OPTR] = "@" }; @@ -73,6 +75,12 @@ emitbin(Node *np) } void +emitsizeof(Node *np) +{ + printf("\t#%c", np->u.type->letter); +} + +void emitexp(Node *np) { (*np->code)(np); @@ -122,3 +130,9 @@ bincode(char op, Type *tp, Node *np1, Node *np2) np->childs[1] = np2; return np; } + +Node * +sizeofcode(Type *tp) +{ + return node(emitsizeof, inttype, TYP(tp), 0); +} +\ No newline at end of file diff --git a/expr.c b/expr.c @@ -87,11 +87,14 @@ int_float: np2 = castcode(np2, np1->type); } break; case PTR: case FTN: case ARY: -pointer: if (t1 == ARY) +pointer: tp3 = tp1->type; + if (t1 == ARY) tp1 = mktype(tp1->type, PTR, NULL, 0); if (t2 != INT) goto incorrect; - np2 = castcode(np2, tp1); + np2 = bincode(OMUL, tp1, + castcode(np2, tp1), + sizeofcode(tp3)); break; default: goto incorrect;