ref: e4d7773b6ee603349d12c0367518d356070b1135
parent: 4f82f8fcd6cccdf13be05aadf56f7939b01ab934
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Apr 18 05:27:25 EDT 2014
Split assign into two functions incdec() is an special case of an assigment, so it is a good idea to merge these two functions in only one. But the semantic actions of assign were done in assign(), so it was not possible share them with another rule.
--- a/expr.c
+++ b/expr.c
@@ -297,6 +297,32 @@
}
static Node *
+assignop(char op, Node *np1, Node *np2)
+{
+ char *err;
+
+ if (!np1->b.lvalue)
+ goto nolvalue;
+ if (isconst(np1->type->op))
+ goto const_mod;
+ np2 = eval(np2);
+ if ((np2 = convert(np2, np1->type, 0)) == NULL)
+ goto incompatibles;
+ return bincode(op, np1->type, np1, np2);
+
+const_mod:
+ err = "const value modified";
+ goto error;
+nolvalue:
+ err = "lvalue required as left operand of assignment";
+ goto error;
+incompatibles:
+ err = "incompatible types when assigning";
+error:
+ error(err);
+}
+
+static Node *
incdec(Node *np, char op)
{
Type *tp;
@@ -335,6 +361,9 @@
error(err);
}
+/*************************************************************
+ * grammar functions *
+ *************************************************************/
static Node *
primary(void)
{
@@ -679,10 +708,9 @@
static Node *
assign(void)
{
- register Node *np1, *np2;
- char *err;
+ register Node *np;
- np1 = ternary();
+ np = ternary();
for (;;) {
register char op;
@@ -698,31 +726,11 @@
case AND_EQ: op = OA_AND; break;
case XOR_EQ: op = OA_XOR; break;
case OR_EQ: op = OA_OR; break;
- default: return np1;
+ default: return np;
}
next();
- np2 = assign();
- if (!np1->b.lvalue)
- goto nolvalue;
- if (isconst(np1->type->op))
- goto const_mod;
- np2 = eval(np2);
- if ((np2 = convert(np2, np1->type, 0)) == NULL)
- goto incompatibles;
- np1 = bincode(op, np1->type, np1, np2);
+ np = assignop(op, np, assign());
}
- return np1;
-
-const_mod:
- err = "const value modified";
- goto error;
-nolvalue:
- err = "lvalue required as left operand of assignment";
- goto error;
-incompatibles:
- err = "incompatible types when assigning";
-error:
- error(err);
}
Node *