Change 17777 by rgs@rgs-home on 2002/08/25 18:42:46

        Fix parsing problems with the // operator.
        Make // able to follow various unary operators used without
        arguments or parens (shift, pop, getc, pos, readline,
        readlink, undef, umask, and the filetest operators), as
        well as the <FH> operator.

Affected files ...

.... //depot/perl/perl.h#470 edit
.... //depot/perl/t/op/dor.t#2 edit
.... //depot/perl/toke.c#441 edit

Differences ...

==== //depot/perl/perl.h#470 (text) ====
Index: perl/perl.h
--- perl/perl.h#469~17742~      Tue Aug 20 07:51:16 2002
+++ perl/perl.h Sun Aug 25 11:42:46 2002
@@ -3178,7 +3178,8 @@
     XBLOCK,
     XATTRBLOCK,
     XATTRTERM,
-    XTERMBLOCK
+    XTERMBLOCK,
+    XTERMORDORDOR /* evil hack */
 } expectation;
 
 enum {         /* pass one of these to get_vtbl */

==== //depot/perl/t/op/dor.t#2 (text) ====
Index: perl/t/op/dor.t
--- perl/t/op/dor.t#1~17682~    Mon Aug  5 08:04:54 2002
+++ perl/t/op/dor.t     Sun Aug 25 11:42:46 2002
@@ -10,7 +10,7 @@
 package main;
 require './test.pl';
 
-plan( tests => 9 );
+plan( tests => 25 );
 
 my($x);
 
@@ -42,3 +42,20 @@
 $x = '';
 $x //= 0;
 is($x, '',             '       //=: left-hand operand defined but empty');
+
+@ARGV = (undef, 0, 3);
+is(shift       // 7, 7,        'shift // ... works');
+is(shift()     // 7, 0,        'shift() // ... works');
+is(shift @ARGV // 7, 3,        'shift @array // ... works');
+
+@ARGV = (3, 0, undef);
+is(pop         // 7, 7,        'pop // ... works');
+is(pop()       // 7, 0,        'pop() // ... works');
+is(pop @ARGV   // 7, 3,        'pop @array // ... works');
+
+# Test that various syntaxes are allowed
+
+for (qw(getc pos readline readlink undef umask <> <FOO> <$foo> -f)) {
+    eval "sub { $_ // 0 }";
+    is($@, '', "$_ // ... compiles");
+}

==== //depot/perl/toke.c#441 (text) ====
Index: perl/toke.c
--- perl/toke.c#440~17746~      Tue Aug 20 09:48:05 2002
+++ perl/toke.c Sun Aug 25 11:42:46 2002
@@ -149,7 +149,7 @@
 #define PREREF(retval) return (REPORT2("preref",retval) PL_expect = XREF,PL_bufptr = 
s,(int)retval)
 #define TERM(retval) return (CLINE, REPORT2("term",retval) PL_expect = XOPERATOR, 
PL_bufptr = s,(int)retval)
 #define LOOPX(f) return(yylval.ival=f, REPORT("loopx",f) PL_expect = XTERM,PL_bufptr 
= s,(int)LOOPEX)
-#define FTST(f) return(yylval.ival=f, REPORT("ftst",f) PL_expect = XTERM,PL_bufptr = 
s,(int)UNIOP)
+#define FTST(f) return(yylval.ival=f, REPORT("ftst",f) PL_expect = 
+XTERMORDORDOR,PL_bufptr = s,(int)UNIOP)
 #define FUN0(f) return(yylval.ival = f, REPORT("fun0",f) PL_expect = 
XOPERATOR,PL_bufptr = s,(int)FUNC0)
 #define FUN1(f) return(yylval.ival = f, REPORT("fun1",f) PL_expect = 
XOPERATOR,PL_bufptr = s,(int)FUNC1)
 #define BOop(f) return ao((yylval.ival=f, REPORT("bitorop",f) PL_expect = 
XTERM,PL_bufptr = s,(int)BITOROP))
@@ -164,14 +164,18 @@
 
 /* This bit of chicanery makes a unary function followed by
  * a parenthesis into a function with one argument, highest precedence.
+ * The UNIDOR macro is for unary functions that can be followed by the //
+ * operator (such as C<shift // 0>).
  */
-#define UNI(f) return(yylval.ival = f, \
+#define UNI2(f,x) return(yylval.ival = f, \
        REPORT("uni",f) \
-       PL_expect = XTERM, \
+       PL_expect = x, \
        PL_bufptr = s, \
        PL_last_uni = PL_oldbufptr, \
        PL_last_lop_op = f, \
        (*s == '(' || (s = skipspace(s), *s == '(') ? (int)FUNC1 : (int)UNIOP) )
+#define UNI(f)    UNI2(f,XTERM)
+#define UNIDOR(f) UNI2(f,XTERMORDORDOR)
 
 #define UNIBRACK(f) return(yylval.ival = f, \
         REPORT("uni",f) \
@@ -997,6 +1001,9 @@
        }
        yylval.opval = (OP*)newSVOP(op_type, 0, sv);
        PL_lex_stuff = Nullsv;
+       /* Allow <FH> // "foo" */
+       if (op_type == OP_READLINE)
+           PL_expect = XTERMORDORDOR;
        return THING;
     }
 
@@ -3597,6 +3604,10 @@
        TERM('@');
 
      case '/':                 /* may be division, defined-or, or pattern */
+       if (PL_expect == XTERMORDORDOR && s[1] == '/') {
+           s += 2;
+           AOPERATOR(DORDOR);
+       }
      case '?':                 /* may either be conditional or pattern */
         if(PL_expect == XOPERATOR) {
             tmp = *s++;
@@ -3745,7 +3756,9 @@
                TERM(THING);
            }
            /* avoid v123abc() or $h{v1}, allow C<print v10;> */
-           else if (!isALPHA(*start) && (PL_expect == XTERM || PL_expect == XREF || 
PL_expect == XSTATE)) {
+           else if (!isALPHA(*start) && (PL_expect == XTERM
+                       || PL_expect == XREF || PL_expect == XSTATE
+                       || PL_expect == XTERMORDORDOR)) {
                char c = *start;
                GV *gv;
                *start = '\0';
@@ -4427,7 +4440,7 @@
            UNI(OP_GMTIME);
 
        case KEY_getc:
-           UNI(OP_GETC);
+           UNIDOR(OP_GETC);
 
        case KEY_getppid:
            FUN0(OP_GETPPID);
@@ -4677,10 +4690,10 @@
            LOP(OP_PUSH,XTERM);
 
        case KEY_pop:
-           UNI(OP_POP);
+           UNIDOR(OP_POP);
 
        case KEY_pos:
-           UNI(OP_POS);
+           UNIDOR(OP_POS);
        
        case KEY_pack:
            LOP(OP_PACK,XTERM);
@@ -4820,7 +4833,7 @@
 
        case KEY_readline:
            set_csh();
-           UNI(OP_READLINE);
+           UNIDOR(OP_READLINE);
 
        case KEY_readpipe:
            set_csh();
@@ -4836,7 +4849,7 @@
            LOP(OP_REVERSE,XTERM);
 
        case KEY_readlink:
-           UNI(OP_READLINK);
+           UNIDOR(OP_READLINK);
 
        case KEY_ref:
            UNI(OP_REF);
@@ -4903,7 +4916,7 @@
            LOP(OP_SSOCKOPT,XTERM);
 
        case KEY_shift:
-           UNI(OP_SHIFT);
+           UNIDOR(OP_SHIFT);
 
        case KEY_shmctl:
            LOP(OP_SHMCTL,XTERM);
@@ -5133,7 +5146,7 @@
            LOP(OP_UNLINK,XTERM);
 
        case KEY_undef:
-           UNI(OP_UNDEF);
+           UNIDOR(OP_UNDEF);
 
        case KEY_unpack:
            LOP(OP_UNPACK,XTERM);
@@ -5142,7 +5155,7 @@
            LOP(OP_UTIME,XTERM);
 
        case KEY_umask:
-           UNI(OP_UMASK);
+           UNIDOR(OP_UMASK);
 
        case KEY_unshift:
            LOP(OP_UNSHIFT,XTERM);
End of Patch.

Reply via email to