shithub: scc

Download patch

ref: e8eb00c8f615dd5820f1e0b4c4e88cdd53c48b68
parent: ad92212ec3827d9e105b874cdebf4ed3fc09709c
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Apr 15 07:45:29 EDT 2014

Add unary & (take address)

--- a/expr.c
+++ b/expr.c
@@ -394,7 +394,7 @@
 		next();
 		return incdec(unary(), op); /* TODO: unary or cast? */
 	case '!': op = OEXC; break;
-	/* TODO: case '&': */
+	case '&': op = OADDR; break;
 	/* TODO: case '*': */
 	case '+': op = OADD; break;
 	case '~': op = OCPL; break;
@@ -404,32 +404,39 @@
 
 	next();
 	np = cast();
-	t = BTYPE(np->type);
+	tp = UNQUAL(np->type);
+	t = tp->op;
 
 	switch (op) {
+	case OADDR:
+		if (!np->b.lvalue)
+			goto bad_operand;
+		/* TODO: check if variable is register */
+		tp = mktype(tp, PTR, NULL, 0);
+		break;
 	case OEXC:
 		switch (t) {
 		case FTN: case ARY:
 			np = addr2ptr(np);
 		case INT: case FLOAT: case PTR:
-			np = eval(np, 1);
+			return eval(np, 1);
 			break;
 		default:
 			goto bad_operand;
 		}
-		break;
-	case OCPL: case OADD:
+	case OADD:
 		if (t != INT)
 			goto bad_operand;
-		if (op == OADD)
-			break;
+		return np;
+	case OCPL:
+		if (t != INT)
+			goto bad_operand;
 	case ONEG:
 		if (!isarith(t))
 			goto bad_operand;
-		np = unarycode(op, np->type, np);
 	}
 
-	return np;
+	return unarycode(op, tp, np);
 
 bad_operand:
 	error("bad operand in unary expression");