scc

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

commit f9656a52f74f06992b576510bb52ed4b6f66b787
parent 3eae8536814569284d81bae4e5bdae82b1b9b3e8
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  4 Sep 2015 19:57:05 +0200

Remove eval()

This function was added to transform comparision or logic
expressions in arithmetic expressions using ternary
operations. This transformation is needed in a z80,
but not in a amd64, and it makes difficult to apply
algebraic transformations.

Diffstat:
Mcc1/cc1.h | 3++-
Mcc1/expr.c | 52++++++++++++++++++----------------------------------
Mcc1/stmt.c | 2+-
Mcc1/tests/test004.c | 8++++----
Mcc1/tests/test005.c | 4++--
Mcc1/tests/test018.c | 4++--
6 files changed, 29 insertions(+), 44 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -367,10 +367,11 @@ extern Node *castcode(Node *np, Type *newtp); /* expr.c */ extern Node *expr(void), *negate(Node *np), *constexpr(void); extern Node *convert(Node *np, Type *tp1, char iscast); -extern Node *eval(Node *np), *iconstexpr(void), *condexpr(void); +extern Node *iconstexpr(void), *condexpr(void); extern bool isnodecmp(int op); extern int negop(int op); extern bool cmpnode(Node *np, TUINT val); +extern Node *decay(Node *np); /* cpp.c */ extern void icpp(void); diff --git a/cc1/expr.c b/cc1/expr.c @@ -94,7 +94,7 @@ chklvalue(Node *np, Type *tp) error("invalid use of void expression"); } -static Node * +Node * decay(Node *np) { Type *tp = np->type; @@ -115,26 +115,9 @@ decay(Node *np) } } -Node * -eval(Node *np) -{ - Node *p; - - if (!np) - return NULL; - - np = decay(np); - if (!isnodecmp(np->op)) - return np; - p = node(OCOLON, inttype, constnode(one), constnode(zero)); - return node(OASK, inttype, np, p); -} - static Node * integerop(char op, Node *lp, Node *rp) { - lp = eval(lp); - rp = eval(rp); if (BTYPE(lp) != INT || BTYPE(rp) != INT) error("operator requires integer operands"); typeconv(&lp, &rp); @@ -144,7 +127,6 @@ integerop(char op, Node *lp, Node *rp) static Node * numericaluop(char op, Node *np) { - np = eval(np); switch (BTYPE(np)) { case INT: case FLOAT: @@ -161,9 +143,9 @@ numericaluop(char op, Node *np) static Node * integeruop(char op, Node *np) { - np = eval(np); if (BTYPE(np) != INT) error("unary operator requires integer operand"); + np = promote(np); if (op == OCPL && np->op == OCPL) return np->left; return simplify(op, np->type, np, NULL); @@ -256,8 +238,6 @@ incorrect: static Node * arithmetic(char op, Node *lp, Node *rp) { - lp = eval(lp); - rp = eval(rp); switch (BTYPE(lp)) { case INT: case FLOAT: @@ -304,8 +284,8 @@ pcompare(char op, Node *lp, Node *rp) static Node * compare(char op, Node *lp, Node *rp) { - lp = eval(lp); - rp = eval(rp); + lp = promote(decay(lp)); + rp = promote(decay(rp)); switch (BTYPE(lp)) { case INT: case FLOAT: @@ -401,6 +381,7 @@ field(Node *np) static Node * content(char op, Node *np) { + np = decay(np); switch (BTYPE(np)) { case ARY: case FTN: @@ -428,7 +409,7 @@ array(Node *lp, Node *rp) if (BTYPE(lp) != INT && BTYPE(rp) != INT) error("array subscript is not an integer"); - np = arithmetic(OADD, lp, rp); + np = arithmetic(OADD, decay(lp), decay(rp)); tp = np->type; if (tp->op != PTR) errorp("subscripted value is neither array nor pointer"); @@ -438,13 +419,18 @@ array(Node *lp, Node *rp) static Node * assignop(char op, Node *lp, Node *rp) { - lp = eval(lp); - rp = eval(rp); + int force = 0; + Type *tp = lp->type; - if (BTYPE(rp) == INT && BTYPE(lp) == PTR && cmpnode(rp, 0)) - rp = convert(rp, pvoidtype, 1); - else if ((rp = convert(rp, lp->type, 0)) == NULL) + rp = decay(rp); + if (BTYPE(rp) == INT && tp->op == PTR && cmpnode(rp, 0)) { + tp = pvoidtype; + force = 1; + } + if ((rp = convert(rp, tp, force)) == NULL) { errorp("incompatible types when assigning"); + return lp; + } return node(op, lp->type, lp, rp); } @@ -560,7 +546,7 @@ arguments(Node *np) toomany = 0; do { - arg = eval(assign()); + arg = decay(assign()); if (--n < 0 && !toomany) { errorp("too many arguments in function call"); toomany = 1; @@ -704,9 +690,7 @@ cast(void) error("cast specify a function type"); default: expect(')'); - if ((lp = eval(cast())) == NULL) - unexpected(); - if ((rp = convert(lp, tp, 1)) == NULL) + if ((rp = convert(cast(), tp, 1)) == NULL) error("bad type convertion requested"); rp->lvalue = lp->lvalue; } diff --git a/cc1/stmt.c b/cc1/stmt.c @@ -143,7 +143,7 @@ Return(Symbol *lbreak, Symbol *lcont, Caselist *lswitch) Type *tp = curfun->type->type; expect(RETURN); - np = (yytoken != ';') ? eval(expr()) : NULL; + np = (yytoken != ';') ? decay(expr()) : NULL; expect(';'); if (!np) { if (tp != voidtype) diff --git a/cc1/tests/test004.c b/cc1/tests/test004.c @@ -18,10 +18,10 @@ A2 I x A2 A2 #IFF |I :I A2 A2 #I3 &I :I A2 A2 #I1 ^I :I - A2 A2 A2 #I1 >I #I1 #I0 ?I +I :I - A2 A2 A2 #I3 <I #I1 #I0 ?I +I :I - A2 A2 A2 #I1 >I #I1 #I0 ?I +I :I - A2 A2 A2 #I4 <I #I1 #I0 ?I +I :I + A2 A2 A2 #I1 >I +I :I + A2 A2 A2 #I3 <I +I :I + A2 A2 A2 #I1 >I +I :I + A2 A2 A2 #I4 <I +I :I j L3 A2 #I4 =I y #I1 L3 diff --git a/cc1/tests/test005.c b/cc1/tests/test005.c @@ -8,8 +8,8 @@ G1 F1 main - A2 I x A2 #I3 :I - A2 A2 #I0 =I #I1 #I0 ?I :I - A2 A2 #I0 =I #I1 #I0 ?I :I + A2 A2 #I0 =I :I + A2 A2 #I0 =I :I A2 A2 ~I :I A2 A2 _I :I j L3 A2 #I2 =I diff --git a/cc1/tests/test018.c b/cc1/tests/test018.c @@ -16,7 +16,7 @@ A10 V9 v A6 A4 'P :P A8 A4 'P #P4 +P #P3 +P :P A4 'P #P4 +P #P3 +P @M #M2 :M - A10 'P @I #I2 :I + A10 #I2 :I j L12 A4 'P #P4 +P #P3 +P @M MI #I2 =I y #I1 L12 @@ -26,7 +26,7 @@ L13 j L14 A8 @M MI #I2 =I y #I1 L14 - j L15 A10 @I #I2 =I + j L15 A10 #I2 =I y #I1 L15 y #I0