shithub: scc

Download patch

ref: 1ab6ca3ad193716d021f635aaf38cfd2e1d07902
parent: ca11c7774accc8688b3614e5ec367a802ae7643d
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Mar 31 13:16:08 EDT 2014

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.

--- a/cc.h
+++ b/cc.h
@@ -213,7 +213,7 @@
 typedef void (*Inst)(Node *);
 
 enum {
-	OCAST, OPTR, OADD, OARY
+	OCAST, OPTR, OADD, OARY, OSIZE, OMUL
 };
 
 extern void
@@ -224,7 +224,8 @@
 	*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})
--- a/code.c
+++ b/code.c
@@ -6,7 +6,9 @@
 
 char *opcodes[] = {
 	[OADD] = "+",
+	[OMUL] = "*",
 	[OARY] = "'",
+	[OSIZE] = "#",
 	[OPTR] = "@"
 };
 
@@ -73,6 +75,12 @@
 }
 
 void
+emitsizeof(Node *np)
+{
+	printf("\t#%c", np->u.type->letter);
+}
+
+void
 emitexp(Node *np)
 {
 	(*np->code)(np);
@@ -122,3 +130,9 @@
 	np->childs[1] = np2;
 	return np;
 }
+
+Node *
+sizeofcode(Type *tp)
+{
+	return node(emitsizeof, inttype, TYP(tp), 0);
+}
\ No newline at end of file
--- a/expr.c
+++ b/expr.c
@@ -87,11 +87,14 @@
 		}
 		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;
--