shithub: scc

Download patch

ref: d56d3ae24cffaad777fcb4607e623e5bd5d34f8d
parent: a13c8cf6f4209b766a9491c57179647762756c19
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Apr 10 04:31:02 EDT 2014

Add relational and equality operands

--- a/cc.h
+++ b/cc.h
@@ -220,7 +220,7 @@
 enum {
 	OCAST, OPTR, OADD, OARY, OSIZE, OMUL, OSUB,
 	OINC, ODEC, OPINC, OPDEC, ODIV, OMOD, OSHL,
-	OSHR
+	OSHR, OLT, OGT, OGE, OLE, OEQ, ONE
 };
 
 extern void
--- a/code.c
+++ b/code.c
@@ -17,7 +17,13 @@
 	[OMOD] = "*",
 	[ODIV] = "/'",
 	[OSHL] = "l",
-	[OSHR]  = "r"
+	[OSHR]  = "r",
+	[OLT] = "<",
+	[OGT] = ">",
+	[OGE] = "]",
+	[OLE] =  "[",
+	[OEQ] = "=",
+	[ONE] = "!"
 };
 
 Node *
--- a/expr.c
+++ b/expr.c
@@ -94,19 +94,33 @@
 		break;
 	case PTR: case ARY:
 pointer:
-		if (!tp1->defined)
-			goto nocomplete;
-		if (op != OADD && op != OSUB)
+		switch (op) {
+		case OEQ: case ONE:
+			if (t1 == ARY)
+				tp1 = mktype(tp1->type, PTR, NULL, 0);
+			else if (t1 != PTR)
+				goto incorrect;
+			if (t2 == ARY)
+				tp2 = mktype(tp2->type, PTR, NULL, 0);
+			else if (t2 != PTR)
+				goto incorrect;
+			break;
+		case OADD: OSUB:
+			tp3 = tp1->type;
+			if (!tp3->defined)
+				goto nocomplete;
+			if (t1 == ARY)
+				tp1 = mktype(tp1->type, PTR, NULL, 0);
+			if (t2 != INT)
+				goto incorrect;
+			np2 = bincode(OMUL, tp1,
+			              castcode(np2, tp1),
+			              sizeofcode(tp3));
+			lvalue = 1;
+			break;
+		default:
 			goto incorrect;
-		tp3 = tp1->type;
-		if (t1 == ARY)
-			tp1 = mktype(tp1->type, PTR, NULL, 0);
-		if (t2 != INT)
-			goto incorrect;
-		np2 = bincode(OMUL, tp1,
-		              castcode(np2, tp1),
-		              sizeofcode(tp3));
-		lvalue = 1;
+		}
 		break;
 	default:
 		goto incorrect;
@@ -293,7 +307,7 @@
 	}
 }
 
-static struct node *
+static Node *
 shift(void)
 {
 	register char op;
@@ -311,6 +325,44 @@
 	}
 }
 
+static Node *
+relational(void)
+{
+	register char op;
+	register Node *np;
+
+	np = shift();
+	for (;;) {
+		switch (yytoken) {
+		case '<': op = OLT; break;
+		case '>': op = OGT; break;
+		case GE:  op = OGE; break;
+		case LE:  op = OLE; break;
+		default:  return np;
+		}
+		next();
+		np = bincode(op, inttype, np, shift());
+	}
+}
+
+static Node *
+eq(void)
+{
+	register char op;
+	register Node *np;
+
+	np = relational();
+	for (;;) {
+		switch (yytoken) {
+		case EQ: op = OEQ; break;
+		case NE: op = ONE; break;
+		default: return np;
+		}
+		next();
+		np = arithmetic(op, np, relational());
+	}
+}
+
 Node *
 expr(void)
 {
@@ -317,7 +369,7 @@
 	register Node *np;
 
 	do
-		np = shift();
+		np = eq();
 	while (yytoken == ',');
 	return np;
 }