shithub: scc

Download patch

ref: 8a651eca19fb38f1585c51dcc5d7f8307ad80ffd
parent: 0a7dad2565a39f1d4d57cc0406fe236709d6b847
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Jan 25 09:51:19 EST 2018

[as] Create unary() function

This unary function implements unary + and -.

--- a/as/as.h
+++ b/as/as.h
@@ -56,6 +56,7 @@
 	NUMBER,
 	REG,
 	STRING,
+	MINUS,
 	SHL,
 	SHR,
 	GE,
--- a/as/expr.c
+++ b/as/expr.c
@@ -143,13 +143,32 @@
 }
 
 static Node *
-unary(int op, Node *np)
+unaryop(int op, Node *np)
 {
-	if (op !=  '!')
+	TUINT val;
+
+	if (np->addr != ANUMBER)
+		error("invalid argument for unary operator");
+	if (np->op != NUMBER) {
+		np = node(op, np, NULL);
+		np->addr = ANUMBER;
+		return np;
+	}
+
+	val = np->sym->value;
+	switch (op) {
+	case '!':
+		val = !val;
+	case '+':
+		break;
+	case '-':
+		val = -val;
+		break;
+	default:
 		abort();
-	if (np->op != NUMBER)
-		return node(op, np, NULL);
-	np->sym->value = ~np->sym->value;
+	}
+	np->sym->value = val;
+
 	return np;
 }
 
@@ -359,7 +378,7 @@
 /* grammar functions                                                     */
 /*************************************************************************/
 
-static Node *or(void);
+static Node *expr(void);
 
 static Node *
 primary(void)
@@ -384,12 +403,12 @@
 		next();
 		break;
 	case '(':
-		np = or();
+		np = expr();
 		expect(')');
 		break;
 	case '[':
 		next();
-		np = or();
+		np = expr();
 		expect(']');
 		np = content(np);
 		break;
@@ -401,12 +420,29 @@
 }
 
 static Node *
+unary(void)
+{
+	int op, tok;
+	Node *np;
+
+	switch (tok = yytoken) {
+	case '!':
+	case '-':
+	case '+':
+		next();
+		return unaryop(tok, primary());
+	default:
+		return primary();
+	}
+}
+
+static Node *
 mul(void)
 {
 	int op;
 	Node *np;
 
-	np = primary();
+	np = unary();
 	for (;;) {
 		switch (op = yytoken) {
 		case '*':
@@ -467,30 +503,19 @@
 }
 
 static Node *
-not(void)
-{
-	Node *np;
-
-	np = relational();
-	while (accept('!'))
-		np = unary('!', relational());
-	return np;
-}
-
-static Node *
 and(void)
 {
 	int op;
 	Node *np;
 
-	np = not();
+	np = relational();
 	while (accept('&'))
-		np = binary('&', np, not());
+		np = binary('&', np, relational());
 	return np;
 }
 
 static Node *
-or(void)
+expr(void)
 {
 	int op;
 	Node *np;
@@ -529,7 +554,7 @@
 		textp++;
 	default:
 		next();
-		np = or();
+		np = expr();
 		if (imm)
 			np->addr = AIMM;
 		if (yytoken != ',' && yytoken != EOS)