commit f0bad0d420fc126fa86c3e8a95f1783cc7032ed6
parent 3f1579403feed901243196776461d5f02035fac7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 11 Apr 2014 19:01:24 +0200
Add ternary operator
Diffstat:
M | cc.h | | | 3 | ++- |
M | code.c | | | 27 | +++++++++++++++++++++++++-- |
M | expr.c | | | 19 | ++++++++++++++++++- |
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/cc.h b/cc.h
@@ -235,7 +235,8 @@ extern Node
*unarycode(char op, Type *tp, Node *child),
*bincode(char op, Type *tp, Node *np1, Node *np2),
*castcode(Node *child, Type *tp),
- *sizeofcode(Type *tp);
+ *sizeofcode(Type *tp),
+ *ternarycode(Node *cond, Node *ifyes, Node *ifno);
#define SYM(s) ((union unode) {.sym = s})
#define OP(s) ((union unode) {.op = s})
diff --git a/code.c b/code.c
@@ -104,6 +104,20 @@ emitbin(Node *np)
}
void
+emitternary(Node *np)
+{
+ Node *cond, *ifyes, *ifno;
+
+ cond = np->childs[0];
+ ifyes = np->childs[1];
+ ifno = np->childs[2];
+ (*cond->code)(cond);
+ (*ifyes->code)(ifyes);
+ (*ifno->code)(ifno);
+ printf("\t?%c", np->type->letter);
+}
+
+void
emitsizeof(Node *np)
{
printf("\t#%c", np->u.type->letter);
@@ -164,4 +178,14 @@ Node *
sizeofcode(Type *tp)
{
return node(emitsizeof, inttype, TYP(tp), 0);
-}
-\ No newline at end of file
+}
+
+Node *
+ternarycode(Node *cond, Node *ifyes, Node *ifno)
+{
+ Node *np= node(emitternary, ifyes->type, OP(0), 3);
+ np->childs[0] = cond;
+ np->childs[1] = ifyes;
+ np->childs[2] = ifno;
+ return np;
+}
diff --git a/expr.c b/expr.c
@@ -445,9 +445,25 @@ bit_or(void)
}
static Node *
+ternary(void)
+{
+ register Node *cond, *ifyes, *ifno;
+
+ cond = bit_or();
+ while (accept('?')) {
+ ifyes = expr();
+ expect(':');
+ ifno = expr();
+ /* TODO: check the types of ifno and ifyes */
+ cond = ternarycode(cond, ifyes, ifno);
+ }
+ return cond;
+}
+
+static Node *
assign(void)
{
- register Node *np1 = bit_or(), *np2;
+ register Node *np1 = ternary(), *np2;
char *err;
for (;;) {
@@ -471,6 +487,7 @@ assign(void)
np2 = assign();
if (!np1->b.lvalue)
goto nolvalue;
+ /* TODO: if it necessary a 0 comparision? */
if ((np2 = convert(np1, np2)) == NULL)
goto incompatibles;
np1 = bincode(op, np1->type, np1, np2);