shithub: scc

Download patch

ref: f0bad0d420fc126fa86c3e8a95f1783cc7032ed6
parent: 3f1579403feed901243196776461d5f02035fac7
author: Roberto E. Vargas Caballero <[email protected]>
date: Fri Apr 11 15:01:24 EDT 2014

Add ternary operator

--- a/cc.h
+++ b/cc.h
@@ -235,7 +235,8 @@
 	*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})
--- a/code.c
+++ b/code.c
@@ -104,6 +104,20 @@
 }
 
 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 @@
 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;
+}
--- a/expr.c
+++ b/expr.c
@@ -445,9 +445,25 @@
 }
 
 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 @@
 		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);