shithub: scc

Download patch

ref: ef05ad6ff2560acd1364b1d90cf52ec95603bc9e
parent: 9e40c0c4f8f15b13a2a39bab393f5a921ec83275
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Apr 15 07:18:54 EDT 2014

Add logical negation

Logical negation are transformed into ternary operators.

--- a/cc.h
+++ b/cc.h
@@ -225,7 +225,7 @@
 	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,
-	ONEG, OCPL,
+	ONEG, OCPL, OEXC
 };
 
 extern void
--- a/expr.c
+++ b/expr.c
@@ -5,8 +5,22 @@
 
 #define SWAP(x1, x2, t) (t = x1, x1 = x2, x2 = t)
 
+static Symbol *zero, *one;
+
 Node *expr(void);
 
+void
+init_expr(void)
+{
+	static Symbol zdummy, odummy;
+
+	zdummy.type = odummy.type = inttype;
+	zdummy.u.i = 0;
+	odummy.u.i = 1;
+	zero = &zdummy;
+	one = &odummy;
+}
+
 static Node *
 promote(Node *np)
 {
@@ -243,6 +257,20 @@
 }
 
 static Node *
+eval(Node *np, char neg)
+{
+	Node *ifyes, *ifno, *cmp;
+	char op;
+
+	ifyes = node(emitconst, inttype, SYM(one), 0);
+	ifno = node(emitconst, inttype, SYM(zero), 0);
+	cmp = node(emitconst, inttype, SYM(zero), 0);
+	op = (neg) ?  OEQ : ONE;
+
+	return ternarycode(compare(op, np, cmp), ifyes, ifno);
+}
+
+static Node *
 incdec(Node *np, char op)
 {
 	Type *tp;
@@ -365,11 +393,11 @@
 	case INC: case DEC:
 		op = (yytoken == INC) ? OINC : ODEC;
 		next();
-		return incdec(unary(), op);
-	/* TODO: case '!': */
+		return incdec(unary(), op); /* TODO: unary or cast? */
+	case '!': op = OEXC; break;
 	/* TODO: case '&': */
 	/* TODO: case '*': */
-	case '+': op = 0; break;
+	case '+': op = OADD; break;
 	case '~': op = OCPL; break;
 	case '-':  op = ONEG; break;
 	default: return postfix();
@@ -380,21 +408,32 @@
 	t = BTYPE(np->type);
 
 	switch (op) {
-	case OCPL:
+	case OEXC:
+		switch (t) {
+		case FTN: case ARY:
+			np = addr2ptr(np);
+		case INT: case FLOAT: case PTR:
+			np = eval(np, 1);
+			break;
+		default:
+			goto bad_operand;
+		}
+		break;
+	case OCPL: case OADD:
 		if (t != INT)
-			goto bad_complement;
+			goto bad_operand;
+		if (op == OADD)
+			break;
 	case ONEG:
 		if (!isarith(t))
-			goto bad_arithm;
+			goto bad_operand;
 		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");
+	return np;
+
+bad_operand:
+	error("bad operand in unary expression");
 }
 
 static Node *
--- a/lex.c
+++ b/lex.c
@@ -28,7 +28,6 @@
 	static char ch;
 
 	/* TODO: implement again */
-
 type:
 	switch (ch = toupper(getc(yyin))) {
 	case 'L':
--- a/main.c
+++ b/main.c
@@ -4,7 +4,8 @@
 
 #include "cc.h"
 
-extern void extdecl(void), init_keywords(void), open_file(const char *file);
+extern void extdecl(void), init_keywords(void),
+	open_file(const char *file),  init_expr(void);
 
 struct user_opt options;
 
@@ -12,6 +13,7 @@
 main(int argc, char *argv[])
 {
 	init_keywords();
+	init_expr();
 	open_file(NULL);
 	for (next(); yytoken != EOFTOK; extdecl());
 		/* nothing */;