allow boolean assign ops to be lvalues
Gurusamy Sarathy [Fri, 12 Feb 1999 12:40:17 +0000 (12:40 +0000)]
From: Stephen McCamant <smccam@uclink4.berkeley.edu>
Date: Mon, 11 Jan 1999 16:52:18 -0600 (CST)
Message-ID: <13978.32609.495338.544643@alias-2.pr.mcs.net>
--
From: Hugo van der Sanden <hv@crypt.compulink.co.uk>
Date: Mon, 18 Jan 1999 10:04:00 +0000
Message-Id: <199901181004.KAA17471@crypt.compulink.co.uk>
Subject: Re: [inconsistency 5.005_54] ||= not an lvalue

p4raw-id: //depot/perl@2901

MANIFEST
op.c
t/op/lop.t [new file with mode: 0755]

index b3ff728..2eea63b 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1159,6 +1159,7 @@ t/op/join.t               See if join works
 t/op/lex_assign.t      See if ops involving lexicals or pad temps work
 t/op/list.t            See if array lists work
 t/op/local.t           See if local works
+t/op/lop.t             See if logical operators work
 t/op/magic.t           See if magic variables work
 t/op/method.t          See if method calls work
 t/op/misc.t            See if miscellaneous bugs have been fixed
diff --git a/op.c b/op.c
index 412eb57..9e4f084 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1250,6 +1250,8 @@ mod(OP *o, I32 type)
     case OP_AV2ARYLEN:
        PL_hints |= HINT_BLOCK_SCOPE;
     case OP_SASSIGN:
+    case OP_ANDASSIGN:
+    case OP_ORASSIGN:
     case OP_AELEMFAST:
        PL_modcount++;
        break;
@@ -1380,8 +1382,8 @@ scalar_mod_type(OP *o, I32 type)
     case OP_READ:
     case OP_SYSREAD:
     case OP_RECV:
-    case OP_ANDASSIGN: /* may work later */
-    case OP_ORASSIGN:  /* may work later */
+    case OP_ANDASSIGN:
+    case OP_ORASSIGN:
        return TRUE;
     default:
        return FALSE;
diff --git a/t/op/lop.t b/t/op/lop.t
new file mode 100755 (executable)
index 0000000..f15201f
--- /dev/null
@@ -0,0 +1,44 @@
+#!./perl
+
+#
+# test the logical operators '&&', '||', '!', 'and', 'or', 'not'
+#
+
+BEGIN {
+    chdir 't' if -d 't';
+    unshift @INC, '../lib';
+}
+
+print "1..7\n";
+
+my $test = 0;
+for my $i (undef, 0 .. 2, "", "0 but true") {
+    my $true = 1;
+    my $false = 0;
+    for my $j (undef, 0 .. 2, "", "0 but true") {
+       $true &&= !(
+           ((!$i || !$j) != !($i && $j))
+           or (!($i || $j) != (!$i && !$j))
+           or (!!($i || $j) != !(!$i && !$j))
+           or (!(!$i || !$j) != !!($i && $j))
+       );
+       $false ||= (
+           ((!$i || !$j) == !!($i && $j))
+           and (!!($i || $j) == (!$i && !$j))
+           and ((!$i || $j) == ($i && !$j))
+           and (($i || !$j) != (!$i && $j))
+       );
+    }
+    if (not $true) {
+       print "not ";
+    } elsif ($false) {
+       print "not ";
+    }
+    print "ok ", ++$test, "\n";
+}
+
+# $test == 6
+my $i = 0;
+(($i ||= 1) &&= 3) += 4;
+print "not " unless $i == 7;
+print "ok ", ++$test, "\n";