Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Implement logical XOR: ^^


---

I wanted to xor two bools, and writing "a ? !b : b" feels a bit
wrong. I'm not sure if there are subtlties to flattencond() that
I've missed, but it seems to work.

---
 6/isel.c      |  2 +-
 6/simp.c      |  2 +-
 mi/flatten.c  | 13 +++++++++++--
 parse/gram.y  |  4 ++++
 parse/infer.c |  1 +
 parse/ops.def |  1 +
 parse/tok.c   |  2 ++
 7 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/6/isel.c b/6/isel.c
index bd122b71..03613548 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -940,7 +940,7 @@ selexpr(Isel *s, Node *n)
 		 * since they should have been replaced with more primitive
 		 * expressions by now */
 	case Obad: case Opreinc: case Opostinc: case Opredec: case Otern:
-	case Opostdec: case Olor: case Oland: case Oaddeq:
+	case Opostdec: case Olor: case Olxor: case Oland: case Oaddeq:
 	case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
 	case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
 	case Oslbase: case Osllen: case Ocast: case Outag: case Oudata:
diff --git a/6/simp.c b/6/simp.c
index d2a9d18f..a182fa6c 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -1253,7 +1253,7 @@ rval(Simp *s, Node *n, Node *dst)
 		t = rval(s, args[0], NULL);
 		r = tupget(s, t, i, dst);
 		break;
-	case Olor: case Oland:
+	case Olor: case Olxor: case Oland:
 	case Oaddeq: case Osubeq: case Omuleq: case Odiveq: case Omodeq:
 	case Oboreq: case Obandeq: case Obxoreq: case Obsleq: case Obsreq:
 	case Opreinc: case Opredec:
diff --git a/mi/flatten.c b/mi/flatten.c
index aba73cda..c4976720 100644
--- a/mi/flatten.c
+++ b/mi/flatten.c
@@ -251,7 +251,7 @@ static void
 flattencond(Flattenctx *s, Node *n, Node *ltrue, Node *lfalse)
 {
 	Node **args;
-	Node *v, *lnext;
+	Node *v, *lnext, *lalt;
 
 	args = n->expr.args;
 	switch (exprop(n)) {
@@ -261,6 +261,15 @@ flattencond(Flattenctx *s, Node *n, Node *ltrue, Node *lfalse)
 		append(s, lnext);
 		flattencond(s, args[1], ltrue, lfalse);
 		break;
+	case Olxor:
+		lnext = genlbl(n->loc);
+		lalt = genlbl(n->loc);
+		flattencond(s, args[0], lnext, lalt);
+		append(s, lnext);
+		flattencond(s, args[1], lfalse, ltrue);
+		append(s, lalt);
+		flattencond(s, args[1], ltrue, lfalse);
+		break;
 	case Olor:
 		lnext = genlbl(n->loc);
 		flattencond(s, args[0], ltrue, lnext);
@@ -506,7 +515,7 @@ rval(Flattenctx *s, Node *n)
 	case Osize:
 		r = n;	/* don't touch subexprs; they're a pseudo decl */
 		break;
-	case Olor: case Oland:
+	case Olor: case Olxor: case Oland:
 		r = flattenlazy(s, n);
 		break;
 	case Oidx:
diff --git a/parse/gram.y b/parse/gram.y
index 8fb448b9..01384218 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -72,6 +72,7 @@ static void setupinit(Node *n);
 %token<tok> Tne		/* != */
 
 %token<tok> Tlor	/* || */
+%token<tok> Tlxor	/* ^^ */
 %token<tok> Tland	/* && */
 %token<tok> Tlnot	/* ! */
 
@@ -718,6 +719,8 @@ ternexpr
 	;
 
 lorexpr : lorexpr Tlor landexpr
+	{$$ = mkexpr($1->loc, binop($2->type), $1, $3, NULL);}
+	| lorexpr Tlxor landexpr
 	{$$ = mkexpr($1->loc, binop($2->type), $1, $3, NULL);}
 	| landexpr
 	;
@@ -1274,6 +1277,7 @@ binop(int tt)
 	case Tle:	o = Ole;	break;
 	case Tne:	o = One;	break;
 	case Tlor:	o = Olor;	break;
+	case Tlxor:	o = Olxor;	break;
 	case Tland:	o = Oland;	break;
 	default:
 		die("Unimplemented binop\n");
diff --git a/parse/infer.c b/parse/infer.c
index 5424be99..88f5c7a7 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1699,6 +1699,7 @@ inferexpr(Node **np, Type *ret, int *sawret)
 
 		/* operands same type, returning bool */
 	case Olor:	/* @a || @b -> bool */
+	case Olxor:	/* @a ^^ @b -> bool */
 	case Oland:	/* @a && @b -> bool */
 	case Oeq:	/* @a == @a -> bool */
 	case One:	/* @a != @a -> bool */
diff --git a/parse/ops.def b/parse/ops.def
index c29ca1eb..73f6ea19 100644
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -20,6 +20,7 @@ O(Oaddr,	1,	OTpre,  "&")
 O(Oderef,	1,	OTpost, "#")
 O(Olor,	        1,	OTbin,  "||")
 O(Oland,	1,	OTbin,  "&&")
+O(Olxor,	1,	OTbin,  "^^")
 O(Olnot,	1,	OTpre,  "!")
 O(Oeq,	        1,	OTbin,  "==")
 O(One,	        1,	OTbin,  "!=")
diff --git a/parse/tok.c b/parse/tok.c
index 5c55cbcc..6eaa25fe 100644
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -609,6 +609,8 @@ oper(void)
 	case '^':
 		  if (match('='))
 			  tt = Tbxoreq;
+		  else if (match('^'))
+			  tt = Tlxor;
 		  else
 			  tt = Tbxor;
 		  break;
-- 
2.16.2


Follow-Ups:
Re: [PATCH] Implement logical XOR: ^^Ori Bernstein <ori@xxxxxxxxxxxxxx>