[PATCH] Implement logical XOR: ^^
[Thread Prev] | [Thread Next]
- Subject: [PATCH] Implement logical XOR: ^^
- From: "S. Gilles" <sgilles@xxxxxxxxxxxx>
- Reply-to: myrddin-dev@xxxxxxxxxxxxxx
- Date: Sat, 17 Mar 2018 04:26:40 -0400
- To: "myrddin-dev" <myrddin-dev@xxxxxxxxxxxxxx>
- Cc: "S. Gilles" <sgilles@xxxxxxxxxxxx>
---
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
| Re: [PATCH] Implement logical XOR: ^^ | Ori Bernstein <ori@xxxxxxxxxxxxxx> |
- Prev by Date: Re: [PATCH 1/1] Implement math.trunc and math.fast2sum
- Next by Date: Re: [PATCH] Implement logical XOR: ^^
- Previous by thread: Re: [PATCH 1/1] Implement math.trunc and math.fast2sum
- Next by thread: Re: [PATCH] Implement logical XOR: ^^
- Index(es):