ref: 797ee1ebf6f6949ded2a493fcd0ebd844f4463db
parent: d44b54b7da692ae72927eba4b12f22ce0779d82b
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Apr 20 19:27:14 EDT 2014
Rewrite arithmetic() using new fields of Node It is a good idea split arithmetic(), and write a new function that handle the pointer operations.
--- a/code.c
+++ b/code.c
@@ -228,6 +228,8 @@
Node *
sizeofcode(Type *tp)
{
+ if (!tp->defined)
+ error("invalid use of indefined type");
return node(emitsizeof, inttype, TYP(tp), 0);
}
--- a/expr.c
+++ b/expr.c
@@ -3,7 +3,6 @@
#include "cc1.h"
-#define SWAP(x1, x2, t) (t = x1, x1 = x2, x2 = t)
#define GETBTYPE(n, tp, t) ((t) = (tp = UNQUAL(n->type))->op)
static Symbol *zero, *one;
@@ -113,7 +112,6 @@
np->utype = UNQUAL(tp);
return np;
}
- return NULL;
}
}
return NULL;
@@ -120,30 +118,46 @@
}
static Node *
-arithmetic(char op, Node *np1, Node *np2)
+parithmetic(char op, Node *np1, Node *np2)
{
+ Type *tp;
+ Node *size;
char *err;
- Node *naux;
- Type *tp1, *tp2, *tp3;
- uint8_t t1, t2, taux;
- np1 = promote(np1);
- np2 = promote(np2);
- GETBTYPE(np1, tp1, t1);
- GETBTYPE(np2, tp2, t2);
+ tp = np1->utype;
+ size = sizeofcode(tp->type);
+ if (np2->typeop == ARY)
+ np2 = addr2ptr(np2);
- switch (t1) {
+ if (op == OSUB && np2->typeop == PTR) {
+ if (tp != np2->utype)
+ goto incorrect;
+ np1 = bincode(OSUB, inttype, np1, np2);
+ return bincode(ODIV, inttype, np1, size);
+ }
+ if (np2->typeop != INT)
+ goto incorrect;
+ np2 = castcode(promote(np2), tp);
+ np2 = bincode(OMUL, tp, np2, size);
+ return bincode(op, tp, np1, np2);
+
+incorrect:
+ error("incorrect arithmetic operands");
+}
+
+static Node *
+arithmetic(char op, Node *np1, Node *np2)
+{
+ switch (np1->typeop) {
case INT: case FLOAT:
- switch (t2) {
+ switch (np2->typeop) {
case INT: case FLOAT:
- if (tp1 != tp2)
- typeconv(&np1, &np2);
- tp1 = np1->type;
+ typeconv(&np1, &np2);
break;
- case PTR: case ARY:
- SWAP(np1, np2, naux);
- SWAP(t1, t2, taux);
- goto pointer;
+ case ARY:
+ np2 = addr2ptr(np2);
+ case PTR:
+ return parithmetic(op, np2, np1);
default:
goto incorrect;
}
@@ -150,38 +164,14 @@
break;
case ARY:
np1 = addr2ptr(np1);
- tp1 = np1->type;
case PTR:
-pointer:
- /* TODO: substraction between pointers */
- switch (op) {
- case OADD: case OSUB:
- tp3 = tp1->type;
- if (!tp3->defined)
- goto nocomplete;
- if (t2 != INT)
- goto incorrect;
- np2 = bincode(OMUL, tp1,
- castcode(np2, tp1),
- sizeofcode(tp3));
- break;
- default:
- goto incorrect;
- }
- break;
+ return parithmetic(op, np1, np2);
default:
- goto incorrect;
+ incorrect:
+ error("incorrect arithmetic operands");
}
- return bincode(op, tp1, np1, np2);
-
-nocomplete:
- err = "invalid use of indefined type";
- goto error;
-incorrect:
- err = "incorrect arithmetic operands";
-error:
- error(err);
+ return bincode(op, np1->type, np1, np2);
}
static Node *