shithub: scc

Download patch

ref: 7a353b8e7e4bfa7b9f9ad26d33f9863489e4b84c
parent: 3fdd8924237466b84005f844aaec040a6f5edc90
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Apr 15 04:08:42 EDT 2014

Add + unary, - unary and bit complement

These are unary operators with similar behaviour (from
compiler point of view).

--- a/cc.h
+++ b/cc.h
@@ -224,7 +224,8 @@
 	OSHR, OLT, OGT, OGE, OLE, OEQ, ONE, OBAND,
 	OBXOR, OBOR, OASSIGN, OA_MUL, OA_DIV,
 	OA_MOD, OA_ADD, OA_SUB, OA_SHL, OA_SHR,
-	OA_AND, OA_XOR, OA_OR, OADDR, OAND, OOR
+	OA_AND, OA_XOR, OA_OR, OADDR, OAND, OOR,
+	ONEG, OCPL,
 };
 
 extern void
--- a/code.c
+++ b/code.c
@@ -38,7 +38,9 @@
 	[OA_AND] = ":&",
 	[OA_XOR] = ":^",
 	[OA_OR] = ":|",
-	[OADDR] = "a"
+	[OADDR] = "a",
+	[ONEG] = "_",
+	[OCPL] = "~",
 };
 
 Node *
--- a/expr.c
+++ b/expr.c
@@ -333,12 +333,15 @@
 	}
 }
 
+static Node *cast(void);
+
 static Node *
 unary(void)
 {
 	register Node *np;
 	Type *tp;
-	char paren;
+	char paren, op;
+	uint8_t t;
 
 	switch (yytoken) {
 	case SIZEOF:
@@ -356,15 +359,40 @@
 		}
 		if (paren)
 			expect(')');
-		np = sizeofcode(tp);
-		break;
+		return sizeofcode(tp);
 	case INC: case DEC:
-		np = incdec(unary(), (yytoken == INC) ? OINC : ODEC);
+		op = (yytoken == INC) ? OINC : ODEC;
 		next();
-		break;
-	default:
-		return postfix();
+		return incdec(unary(), op);
+	/* TODO: case '!': */
+	/* TODO: case '&': */
+	/* TODO: case '*': */
+	case '+': op = 0; break;
+	case '~': op = OCPL; break;
+	case '-':  op = ONEG; break;
+	default: return postfix();
 	}
+
+	next();
+	np = cast();
+	t = BTYPE(np->type);
+
+	switch (op) {
+	case OCPL:
+		if (t != INT)
+			goto bad_complement;
+	case ONEG:
+		if (!isarith(t))
+			goto bad_arithm;
+		np = unarycode(op, np->type, np);
+	case 0:
+		return np;
+	}
+
+bad_complement:
+	error("bad operand in bit-complement");
+bad_arithm:
+	error("bad arithmetic operand in unary expression");
 }
 
 static Node *