This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
toke.c: Recognize "0odddd" octal literals.
authorTAKAI Kousuke <62541129+t-a-k@users.noreply.github.com>
Thu, 22 Oct 2020 14:23:57 +0000 (23:23 +0900)
committerKarl Williamson <khw@cpan.org>
Tue, 8 Dec 2020 04:52:14 +0000 (21:52 -0700)
t/base/num.t: Add some test for "0odddd" octals.

t/base/num.t
toke.c

index 6ccc0cf..2e66bc9 100644 (file)
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..53\n";
+print "1..56\n";
 
 # First test whether the number stringification works okay.
 # (Testing with == would exercise the IV/NV part, not the PV.)
@@ -211,3 +211,14 @@ print $a eq "16702650"     ? "ok 52\n" : "not ok 52 # $a\n";
 
 $a = 0B1101; "$a";
 print $a eq "13"           ? "ok 53\n" : "not ok 53 # $a\n";
+
+# 0odddd octal constants
+
+$a = 0o100; "$a";
+print $a eq "64"       ? "ok 54\n" : "not ok 54 # $a\n";
+
+$a = 0o100; "$a";
+print $a + 1 == 0o101  ? "ok 55\n" : "not ok 55 #" . $a + 1 . "\n";
+
+$a = 0O1703; "$a";
+print $a eq "963"      ? "ok 56\n" : "not ok 56 # $a\n";
diff --git a/toke.c b/toke.c
index 9dcc7c3..fd6e9a6 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -11366,7 +11366,7 @@ Perl_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int
   \d(_?\d)*(\.(\d(_?\d)*)?)?[Ee][\+\-]?(\d(_?\d)*)     12 12.34 12.
   \.\d(_?\d)*[Ee][\+\-]?(\d(_?\d)*)                    .34
   0b[01](_?[01])*                                       binary integers
-  0[0-7](_?[0-7])*                                      octal integers
+  0o?[0-7](_?[0-7])*                                    octal integers
   0x[0-9A-Fa-f](_?[0-9A-Fa-f])*                         hexadecimal integers
   0x[0-9A-Fa-f](_?[0-9A-Fa-f])*(?:\.\d*)?p[+-]?[0-9]+   hexadecimal floats
 
@@ -11478,6 +11478,10 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
            else {
                shift = 3;
                s++;
+                if (isALPHA_FOLD_EQ(*s, 'o')) {
+                    s++;
+                    just_zero = FALSE;
+                }
            }
 
            if (*s == '_') {
@@ -11755,8 +11759,8 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                 }
             }
 
-            if (shift != 3 && !has_digs) {
-                /* 0x or 0b with no digits, treat it as an error.
+            if (!just_zero && !has_digs) {
+                /* 0x, 0o or 0b with no digits, treat it as an error.
                    Originally this backed up the parse before the b or
                    x, but that has the potential for silent changes in
                    behaviour, like for: "0x.3" and "0x+$foo".
@@ -11766,7 +11770,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                 if (*d) ++d; /* so the user sees the bad non-digit */
                 PL_bufptr = (char *)d; /* so yyerror reports the context */
                 yyerror(Perl_form(aTHX_ "No digits found for %s literal",
-                                  shift == 4 ? "hexadecimal" : "binary"));
+                                  base));
                 PL_bufptr = oldbp;
             }