This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
FAQ sync
[perl5.git] / toke.c
diff --git a/toke.c b/toke.c
index 40b5465..46066d1 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1,7 +1,7 @@
 /*    toke.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #define PERL_IN_TOKE_C
 #include "perl.h"
 
-#define yychar (*PL_yycharp)
-#define yylval (*PL_yylvalp)
+#define yylval (PL_parser->yylval)
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#define YYINITDEPTH 200
+
+/* XXX temporary backwards compatibility */
+#define PL_lex_brackets                (PL_parser->lex_brackets)
+#define PL_lex_brackstack      (PL_parser->lex_brackstack)
+#define PL_lex_casemods                (PL_parser->lex_casemods)
+#define PL_lex_casestack        (PL_parser->lex_casestack)
+#define PL_lex_defer           (PL_parser->lex_defer)
+#define PL_lex_dojoin          (PL_parser->lex_dojoin)
+#define PL_lex_expect          (PL_parser->lex_expect)
+#define PL_lex_formbrack        (PL_parser->lex_formbrack)
+#define PL_lex_inpat           (PL_parser->lex_inpat)
+#define PL_lex_inwhat          (PL_parser->lex_inwhat)
+#define PL_lex_op              (PL_parser->lex_op)
+#define PL_lex_repl            (PL_parser->lex_repl)
+#define PL_lex_starts          (PL_parser->lex_starts)
+#define PL_lex_stuff           (PL_parser->lex_stuff)
+#define PL_multi_start         (PL_parser->multi_start)
+#define PL_multi_open          (PL_parser->multi_open)
+#define PL_multi_close         (PL_parser->multi_close)
+#define PL_pending_ident        (PL_parser->pending_ident)
+#define PL_preambled           (PL_parser->preambled)
+#define PL_sublex_info         (PL_parser->sublex_info)
+
+#ifdef PERL_MAD
+#  define PL_endwhite          (PL_parser->endwhite)
+#  define PL_faketokens                (PL_parser->faketokens)
+#  define PL_lasttoke          (PL_parser->lasttoke)
+#  define PL_nextwhite         (PL_parser->nextwhite)
+#  define PL_realtokenstart    (PL_parser->realtokenstart)
+#  define PL_skipwhite         (PL_parser->skipwhite)
+#  define PL_thisclose         (PL_parser->thisclose)
+#  define PL_thismad           (PL_parser->thismad)
+#  define PL_thisopen          (PL_parser->thisopen)
+#  define PL_thisstuff         (PL_parser->thisstuff)
+#  define PL_thistoken         (PL_parser->thistoken)
+#  define PL_thiswhite         (PL_parser->thiswhite)
+#endif
+
+static int
+S_pending_ident(pTHX);
 
 static const char ident_too_long[] = "Identifier too long";
 static const char commaless_variable_list[] = "comma-less variable list";
@@ -569,6 +611,8 @@ S_cr_textfilter(pTHX_ int idx, SV *sv, int maxlen)
 }
 #endif
 
+
+
 /*
  * Perl_lex_start
  * Initialize variables.  Uses the Perl save_stack to save its state (for
@@ -579,37 +623,36 @@ void
 Perl_lex_start(pTHX_ SV *line)
 {
     dVAR;
-    const char *s;
+    const char *s = NULL;
     STRLEN len;
+    yy_parser *parser;
+
+    /* create and initialise a parser */
+
+    Newxz(parser, 1, yy_parser);
+    parser->old_parser = PL_parser;
+    PL_parser = parser;
+
+    Newx(parser->stack, YYINITDEPTH, yy_stack_frame);
+    parser->ps = parser->stack;
+    parser->stack_size = YYINITDEPTH;
+
+    parser->stack->state = 0;
+    parser->yyerrstatus = 0;
+    parser->yychar = YYEMPTY;          /* Cause a token to be read.  */
+
+    /* initialise lexer state */
 
-    SAVEI32(PL_lex_dojoin);
-    SAVEI32(PL_lex_brackets);
-    SAVEI32(PL_lex_casemods);
-    SAVEI32(PL_lex_starts);
     SAVEI32(PL_lex_state);
-    SAVEVPTR(PL_lex_inpat);
-    SAVEI32(PL_lex_inwhat);
 #ifdef PERL_MAD
     if (PL_lex_state == LEX_KNOWNEXT) {
-       I32 toke = PL_lasttoke;
+       I32 toke = parser->old_parser->lasttoke;
        while (--toke >= 0) {
            SAVEI32(PL_nexttoke[toke].next_type);
            SAVEVPTR(PL_nexttoke[toke].next_val);
            if (PL_madskills)
                SAVEVPTR(PL_nexttoke[toke].next_mad);
        }
-       SAVEI32(PL_lasttoke);
-    }
-    if (PL_madskills) {
-       SAVESPTR(PL_thistoken);
-       SAVESPTR(PL_thiswhite);
-       SAVESPTR(PL_nextwhite);
-       SAVESPTR(PL_thisopen);
-       SAVESPTR(PL_thisclose);
-       SAVESPTR(PL_thisstuff);
-       SAVEVPTR(PL_thismad);
-       SAVEI32(PL_realtokenstart);
-       SAVEI32(PL_faketokens);
     }
     SAVEI32(PL_curforce);
 #else
@@ -631,46 +674,37 @@ Perl_lex_start(pTHX_ SV *line)
     SAVEPPTR(PL_last_uni);
     SAVEPPTR(PL_linestart);
     SAVESPTR(PL_linestr);
-    SAVEGENERICPV(PL_lex_brackstack);
-    SAVEGENERICPV(PL_lex_casestack);
     SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp);
-    SAVESPTR(PL_lex_stuff);
-    SAVEI32(PL_lex_defer);
-    SAVEI32(PL_sublex_info.sub_inwhat);
-    SAVESPTR(PL_lex_repl);
     SAVEINT(PL_expect);
-    SAVEINT(PL_lex_expect);
 
     PL_lex_state = LEX_NORMAL;
-    PL_lex_defer = 0;
     PL_expect = XSTATE;
-    PL_lex_brackets = 0;
-    Newx(PL_lex_brackstack, 120, char);
-    Newx(PL_lex_casestack, 12, char);
-    PL_lex_casemods = 0;
-    *PL_lex_casestack = '\0';
-    PL_lex_dojoin = 0;
-    PL_lex_starts = 0;
-    PL_lex_stuff = NULL;
-    PL_lex_repl = NULL;
-    PL_lex_inpat = 0;
-#ifdef PERL_MAD
-    PL_lasttoke = 0;
-#else
+    Newx(parser->lex_brackstack, 120, char);
+    Newx(parser->lex_casestack, 12, char);
+    *parser->lex_casestack = '\0';
+#ifndef PERL_MAD
     PL_nexttoke = 0;
 #endif
-    PL_lex_inwhat = 0;
-    PL_sublex_info.sub_inwhat = 0;
-    PL_linestr = line;
-    if (SvREADONLY(PL_linestr))
-       PL_linestr = sv_2mortal(newSVsv(PL_linestr));
-    s = SvPV_const(PL_linestr, len);
-    if (!len || s[len-1] != ';') {
-       if (!(SvFLAGS(PL_linestr) & SVs_TEMP))
-           PL_linestr = sv_2mortal(newSVsv(PL_linestr));
-       sv_catpvs(PL_linestr, "\n;");
-    }
-    SvTEMP_off(PL_linestr);
+
+    if (line) {
+       s = SvPV_const(line, len);
+    } else {
+       len = 0;
+    }
+    if (!len) {
+       PL_linestr = newSVpvs("\n;");
+    } else if (SvREADONLY(line) || s[len-1] != ';') {
+       PL_linestr = newSVsv(line);
+       if (s[len-1] != ';')
+           sv_catpvs(PL_linestr, "\n;");
+    } else {
+       SvTEMP_off(line);
+       SvREFCNT_inc_simple_void_NN(line);
+       PL_linestr = line;
+    }
+    /* PL_linestr needs to survive until end of scope, not just the next
+       FREETMPS. See changes 17505 and 17546 which fixed the symptoms only.  */
+    SAVEFREESV(PL_linestr);
     PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = PL_linestart = SvPVX(PL_linestr);
     PL_bufend = PL_bufptr + SvCUR(PL_linestr);
     PL_last_lop = PL_last_uni = NULL;
@@ -701,13 +735,12 @@ Perl_lex_end(pTHX)
  */
 
 STATIC void
-S_incline(pTHX_ char *s)
+S_incline(pTHX_ const char *s)
 {
     dVAR;
-    char *t;
-    char *n;
-    char *e;
-    char ch;
+    const char *t;
+    const char *n;
+    const char *e;
 
     CopLINE_inc(PL_curcop);
     if (*s++ != '#')
@@ -747,50 +780,65 @@ S_incline(pTHX_ char *s)
     if (*e != '\n' && *e != '\0')
        return;         /* false alarm */
 
-    ch = *t;
-    *t = '\0';
     if (t - s > 0) {
+       const STRLEN len = t - s;
 #ifndef USE_ITHREADS
        const char * const cf = CopFILE(PL_curcop);
        STRLEN tmplen = cf ? strlen(cf) : 0;
        if (tmplen > 7 && strnEQ(cf, "(eval ", 6)) {
            /* must copy *{"::_<(eval N)[oldfilename:L]"}
             * to *{"::_<newfilename"} */
-           char smallbuf[256], smallbuf2[256];
-           char *tmpbuf, *tmpbuf2;
-           GV **gvp, *gv2;
-           STRLEN tmplen2 = strlen(s);
-           if (tmplen + 3 < sizeof smallbuf)
+           /* However, the long form of evals is only turned on by the
+              debugger - usually they're "(eval %lu)" */
+           char smallbuf[128];
+           char *tmpbuf;
+           GV **gvp;
+           STRLEN tmplen2 = len;
+           if (tmplen + 2 <= sizeof smallbuf)
                tmpbuf = smallbuf;
            else
-               Newx(tmpbuf, tmplen + 3, char);
-           if (tmplen2 + 3 < sizeof smallbuf2)
-               tmpbuf2 = smallbuf2;
-           else
-               Newx(tmpbuf2, tmplen2 + 3, char);
-           tmpbuf[0] = tmpbuf2[0] = '_';
-           tmpbuf[1] = tmpbuf2[1] = '<';
-           memcpy(tmpbuf + 2, cf, ++tmplen);
-           memcpy(tmpbuf2 + 2, s, ++tmplen2);
-           ++tmplen; ++tmplen2;
+               Newx(tmpbuf, tmplen + 2, char);
+           tmpbuf[0] = '_';
+           tmpbuf[1] = '<';
+           memcpy(tmpbuf + 2, cf, tmplen);
+           tmplen += 2;
            gvp = (GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, FALSE);
            if (gvp) {
+               char *tmpbuf2;
+               GV *gv2;
+
+               if (tmplen2 + 2 <= sizeof smallbuf)
+                   tmpbuf2 = smallbuf;
+               else
+                   Newx(tmpbuf2, tmplen2 + 2, char);
+
+               if (tmpbuf2 != smallbuf || tmpbuf != smallbuf) {
+                   /* Either they malloc'd it, or we malloc'd it,
+                      so no prefix is present in ours.  */
+                   tmpbuf2[0] = '_';
+                   tmpbuf2[1] = '<';
+               }
+
+               memcpy(tmpbuf2 + 2, s, tmplen2);
+               tmplen2 += 2;
+
                gv2 = *(GV**)hv_fetch(PL_defstash, tmpbuf2, tmplen2, TRUE);
-               if (!isGV(gv2))
+               if (!isGV(gv2)) {
                    gv_init(gv2, PL_defstash, tmpbuf2, tmplen2, FALSE);
-               /* adjust ${"::_<newfilename"} to store the new file name */
-               GvSV(gv2) = newSVpvn(tmpbuf2 + 2, tmplen2 - 2);
-               GvHV(gv2) = (HV*)SvREFCNT_inc(GvHV(*gvp));
-               GvAV(gv2) = (AV*)SvREFCNT_inc(GvAV(*gvp));
+                   /* adjust ${"::_<newfilename"} to store the new file name */
+                   GvSV(gv2) = newSVpvn(tmpbuf2 + 2, tmplen2 - 2);
+                   GvHV(gv2) = (HV*)SvREFCNT_inc(GvHV(*gvp));
+                   GvAV(gv2) = (AV*)SvREFCNT_inc(GvAV(*gvp));
+               }
+
+               if (tmpbuf2 != smallbuf) Safefree(tmpbuf2);
            }
            if (tmpbuf != smallbuf) Safefree(tmpbuf);
-           if (tmpbuf2 != smallbuf2) Safefree(tmpbuf2);
        }
 #endif
        CopFILE_free(PL_curcop);
-       CopFILE_set(PL_curcop, s);
+       CopFILE_setn(PL_curcop, s, len);
     }
-    *t = ch;
     CopLINE_set(PL_curcop, atoi(n)-1);
 }
 
@@ -870,6 +918,23 @@ S_skipspace2(pTHX_ register char *s, SV **svp)
 }
 #endif
 
+STATIC void
+S_update_debugger_info(pTHX_ SV *orig_sv, const char *buf, STRLEN len)
+{
+    AV *av = CopFILEAVx(PL_curcop);
+    if (av) {
+       SV * const sv = newSV(0);
+       sv_upgrade(sv, SVt_PVMG);
+       if (orig_sv)
+           sv_setsv(sv, orig_sv);
+       else
+           sv_setpvn(sv, buf, len);
+       (void)SvIOK_on(sv);
+       SvIV_set(sv, 0);
+       av_store(av, (I32)CopLINE(PL_curcop), sv);
+    }
+}
+
 /*
  * S_skipspace
  * Called to gobble the appropriate amount and type of whitespace.
@@ -961,10 +1026,10 @@ S_skipspace(pTHX_ register char *s)
            /* XXX these shouldn't really be added here, can't set PL_faketokens */
            if (PL_minus_p) {
 #ifdef PERL_MAD
-               sv_catpv(PL_linestr,
+               sv_catpvs(PL_linestr,
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #else
-               sv_setpv(PL_linestr,
+               sv_setpvs(PL_linestr,
                         ";}continue{print or die qq(-p destination: $!\\n);}");
 #endif
                PL_minus_n = PL_minus_p = 0;
@@ -1033,15 +1098,8 @@ S_skipspace(pTHX_ register char *s)
        /* debugger active and we're not compiling the debugger code,
         * so store the line into the debugger's array of lines
         */
-       if (PERLDB_LINE && PL_curstash != PL_debstash) {
-           SV * const sv = newSV(0);
-
-           sv_upgrade(sv, SVt_PVMG);
-           sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr);
-            (void)SvIOK_on(sv);
-            SvIV_set(sv, 0);
-           av_store(CopFILEAVx(PL_curcop),(I32)CopLINE(PL_curcop),sv);
-       }
+       if (PERLDB_LINE && PL_curstash != PL_debstash)
+           update_debugger_info(NULL, PL_bufptr, PL_bufend - PL_bufptr);
     }
 
 #ifdef PERL_MAD
@@ -1249,11 +1307,12 @@ S_newSV_maybe_utf8(pTHX_ const char *start, STRLEN len)
  * S_force_word
  * When the lexer knows the next thing is a word (for instance, it has
  * just seen -> and it knows that the next char is a word char, then
- * it calls S_force_word to stick the next word into the PL_next lookahead.
+ * it calls S_force_word to stick the next word into the PL_nexttoke/val
+ * lookahead.
  *
  * Arguments:
  *   char *start : buffer position (must be within PL_linestr)
- *   int token   : PL_next will be this type of bare word (e.g., METHOD,WORD)
+ *   int token   : PL_next* will be this type of bare word (e.g., METHOD,WORD)
  *   int check_keyword : if true, Perl checks to make sure the word isn't
  *       a keyword (do this if the word is a label, e.g. goto FOO)
  *   int allow_pack : if true, : characters will also be allowed (require,
@@ -1545,7 +1604,7 @@ S_sublex_start(pTHX)
        /* readpipe() vas overriden */
        cSVOPx(cLISTOPx(cUNOPx(PL_lex_op)->op_first)->op_first->op_sibling)->op_sv = tokeq(PL_lex_stuff);
        yylval.opval = PL_lex_op;
-       PL_lex_op =
+       PL_lex_op = NULL;
        PL_lex_stuff = NULL;
        return THING;
     }
@@ -2613,7 +2672,7 @@ S_intuit_method(pTHX_ char *start, GV *gv, CV *cv)
        if (indirgv && GvCVu(indirgv))
            return 0;
        /* filehandle or package name makes it a method */
-       if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) {
+       if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, 0)) {
 #ifdef PERL_MAD
            soff = s - SvPVX(PL_linestr);
 #endif
@@ -2845,7 +2904,7 @@ S_find_in_my_stash(pTHX_ const char *pkgname, I32 len)
             pkgname = SvPV_nolen_const(sv);
     }
 
-    return gv_stashpv(pkgname, FALSE);
+    return gv_stashpv(pkgname, 0);
 }
 
 /*
@@ -2854,7 +2913,7 @@ S_find_in_my_stash(pTHX_ const char *pkgname, I32 len)
  * optree, provided sublex_start() is called afterwards.
  */
 STATIC void
-S_readpipe_override()
+S_readpipe_override(pTHX)
 {
     GV **gvp;
     GV *gv_readpipe = gv_fetchpvs("readpipe", GV_NOTQUAL, SVt_PVCV);
@@ -3546,15 +3605,8 @@ Perl_yylex(pTHX)
            PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = SvPVX(PL_linestr);
            PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
            PL_last_lop = PL_last_uni = NULL;
-           if (PERLDB_LINE && PL_curstash != PL_debstash) {
-               SV * const sv = newSV(0);
-
-               sv_upgrade(sv, SVt_PVMG);
-               sv_setsv(sv,PL_linestr);
-                (void)SvIOK_on(sv);
-                SvIV_set(sv, 0);
-               av_store(CopFILEAVx(PL_curcop),(I32)CopLINE(PL_curcop),sv);
-           }
+           if (PERLDB_LINE && PL_curstash != PL_debstash)
+               update_debugger_info(PL_linestr, NULL, 0);
            goto retry;
        }
        do {
@@ -3635,7 +3687,7 @@ Perl_yylex(pTHX)
                if (PL_madskills)
                    sv_catsv(PL_thiswhite, PL_linestr);
 #endif
-               if (*s == '=' && strnEQ(s, "=cut", 4)) {
+               if (*s == '=' && strnEQ(s, "=cut", 4) && !isALPHA(s[4])) {
                    sv_setpvn(PL_linestr, "", 0);
                    PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = SvPVX(PL_linestr);
                    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
@@ -3646,15 +3698,8 @@ Perl_yylex(pTHX)
            incline(s);
        } while (PL_doextract);
        PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = PL_linestart = s;
-       if (PERLDB_LINE && PL_curstash != PL_debstash) {
-           SV * const sv = newSV(0);
-
-           sv_upgrade(sv, SVt_PVMG);
-           sv_setsv(sv,PL_linestr);
-            (void)SvIOK_on(sv);
-            SvIV_set(sv, 0);
-           av_store(CopFILEAVx(PL_curcop),(I32)CopLINE(PL_curcop),sv);
-       }
+       if (PERLDB_LINE && PL_curstash != PL_debstash)
+           update_debugger_info(PL_linestr, NULL, 0);
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
        PL_last_lop = PL_last_uni = NULL;
        if (CopLINE(PL_curcop) == 1) {
@@ -4102,8 +4147,7 @@ Perl_yylex(pTHX)
        /* FALL THROUGH */
     case '~':
        if (s[1] == '~'
-       && (PL_expect == XOPERATOR || PL_expect == XTERMORDORDOR)
-       && FEATURE_IS_ENABLED("~~"))
+           && (PL_expect == XOPERATOR || PL_expect == XTERMORDORDOR))
        {
            s += 2;
            Eop(OP_SMARTMATCH);
@@ -4763,12 +4807,12 @@ Perl_yylex(pTHX)
                                t++;
                            } while (isSPACE(*t));
                            if (isIDFIRST_lazy_if(t,UTF)) {
-                               STRLEN dummylen;
+                               STRLEN len;
                                t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE,
-                                             &dummylen);
+                                             &len);
                                while (isSPACE(*t))
                                    t++;
-                               if (*t == ';' && get_cv(tmpbuf, FALSE))
+                               if (*t == ';' && get_cvn_flags(tmpbuf, len, 0))
                                    Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                                                "You need to quote \"%s\"",
                                                tmpbuf);
@@ -4987,7 +5031,7 @@ Perl_yylex(pTHX)
            no_op("Backticks",s);
        if (!s)
            missingterm(NULL);
-       S_readpipe_override();
+       readpipe_override();
        TERM(sublex_start());
 
     case '\\':
@@ -5088,7 +5132,7 @@ Perl_yylex(pTHX)
        if (!tmp && PL_expect == XSTATE
              && d < PL_bufend && *d == ':' && *(d + 1) != ':') {
            s = d + 1;
-           yylval.pval = savepv(PL_tokenbuf);
+           yylval.pval = CopLABEL_alloc(PL_tokenbuf);
            CLINE;
            TOKEN(LABEL);
        }
@@ -5489,7 +5533,7 @@ Perl_yylex(pTHX)
                        }
                    }
                    if (probable_sub) {
-                       gv = gv_fetchpv(PL_tokenbuf, TRUE, SVt_PVCV);
+                       gv = gv_fetchpv(PL_tokenbuf, GV_ADD, SVt_PVCV);
                        op_free(yylval.opval);
                        yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv));
                        yylval.opval->op_private |= OPpENTERSUB_NOPAREN;
@@ -5525,7 +5569,7 @@ Perl_yylex(pTHX)
                            d = PL_tokenbuf;
                            while (isLOWER(*d))
                                d++;
-                           if (!*d && !gv_stashpv(PL_tokenbuf,FALSE))
+                           if (!*d && !gv_stashpv(PL_tokenbuf, 0))
                                Perl_warner(aTHX_ packWARN(WARN_RESERVED), PL_warn_reserved,
                                       PL_tokenbuf);
                        }
@@ -5636,7 +5680,7 @@ Perl_yylex(pTHX)
                        PUTBACK;
                        PerlIO_apply_layers(aTHX_ PL_rsfp, NULL,
                                            Perl_form(aTHX_ ":encoding(%"SVf")",
-                                                     (void*)name));
+                                                     SVfARG(name)));
                        FREETMPS;
                        LEAVE;
                    }
@@ -6306,7 +6350,7 @@ Perl_yylex(pTHX)
            s = scan_str(s,!!PL_madskills,FALSE);
            if (!s)
                missingterm(NULL);
-           S_readpipe_override();
+           readpipe_override();
            TERM(sublex_start());
 
        case KEY_return:
@@ -6323,7 +6367,7 @@ Perl_yylex(pTHX)
                *PL_tokenbuf = '\0';
                s = force_word(s,WORD,TRUE,TRUE,FALSE);
                if (isIDFIRST_lazy_if(PL_tokenbuf,UTF))
-                   gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), TRUE);
+                   gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), GV_ADD);
                else if (*s == '<')
                    yyerror("<> should be quotes");
            }
@@ -6555,8 +6599,8 @@ Perl_yylex(pTHX)
                    if (PL_madskills)
                        nametoke = newSVpvn(s, d - s);
 #endif
-                   if (strchr(tmpbuf, ':'))
-                       sv_setpv(PL_subname, tmpbuf);
+                   if (memchr(tmpbuf, ':', len))
+                       sv_setpvn(PL_subname, tmpbuf, len);
                    else {
                        sv_setsv(PL_subname,PL_curstname);
                        sv_catpvs(PL_subname,"::");
@@ -6623,7 +6667,7 @@ Perl_yylex(pTHX)
                    if (bad_proto)
                        Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                                    "Illegal character in prototype for %"SVf" : %s",
-                                   (void*)PL_subname, d);
+                                   SVfARG(PL_subname), d);
                    SvCUR_set(PL_lex_stuff, tmp);
                    have_proto = TRUE;
 
@@ -6652,7 +6696,7 @@ Perl_yylex(pTHX)
                    if (!have_name)
                        Perl_croak(aTHX_ "Illegal declaration of anonymous subroutine");
                    else if (*s != ';')
-                       Perl_croak(aTHX_ "Illegal declaration of subroutine %"SVf, (void*)PL_subname);
+                       Perl_croak(aTHX_ "Illegal declaration of subroutine %"SVf, SVfARG(PL_subname));
                }
 
 #ifdef PERL_MAD
@@ -7393,7 +7437,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)
             case 'a':
               if (name[2] == 'y')
               {                                   /* say        */
-                return (all_keywords || FEATURE_IS_ENABLED("say") ? -KEY_say : 0);
+                return (all_keywords || FEATURE_IS_ENABLED("say") ? KEY_say : 0);
               }
 
               goto unknown;
@@ -10706,7 +10750,8 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL
            }
            if (PL_lex_state == LEX_NORMAL) {
                if (ckWARN(WARN_AMBIGUOUS) &&
-                   (keyword(dest, d - dest, 0) || get_cv(dest, FALSE)))
+                   (keyword(dest, d - dest, 0)
+                    || get_cvn_flags(dest, d - dest, 0)))
                {
                    if (funny == '#')
                        funny = '@';
@@ -10730,20 +10775,16 @@ void
 Perl_pmflag(pTHX_ U32* pmfl, int ch)
 {
     PERL_UNUSED_CONTEXT;
-    if (ch == 'i')
-       *pmfl |= PMf_FOLD;
-    else if (ch == 'g')
-       *pmfl |= PMf_GLOBAL;
-    else if (ch == 'c')
-       *pmfl |= PMf_CONTINUE;
-    else if (ch == 'o')
-       *pmfl |= PMf_KEEP;
-    else if (ch == 'm')
-       *pmfl |= PMf_MULTILINE;
-    else if (ch == 's')
-       *pmfl |= PMf_SINGLELINE;
-    else if (ch == 'x')
-       *pmfl |= PMf_EXTENDED;
+    if (ch<256) {
+        char c = (char)ch;
+        switch (c) {
+            CASE_STD_PMMOD_FLAGS_PARSE_SET(pmfl);
+            case GLOBAL_PAT_MOD:    *pmfl |= PMf_GLOBAL; break;
+            case CONTINUE_PAT_MOD:  *pmfl |= PMf_CONTINUE; break;
+            case ONCE_PAT_MOD:      *pmfl |= PMf_KEEP; break;
+            case KEEPCOPY_PAT_MOD:  *pmfl |= PMf_KEEPCOPY; break;
+        }
+    }
 }
 
 STATIC char *
@@ -10753,7 +10794,7 @@ S_scan_pat(pTHX_ char *start, I32 type)
     PMOP *pm;
     char *s = scan_str(start,!!PL_madskills,FALSE);
     const char * const valid_flags =
-       (const char *)((type == OP_QR) ? "iomsx" : "iogcmsx");
+       (const char *)((type == OP_QR) ? QR_PAT_MODS : M_PAT_MODS);
 #ifdef PERL_MAD
     char *modstart;
 #endif
@@ -10786,7 +10827,8 @@ S_scan_pat(pTHX_ char *start, I32 type)
     if ((pm->op_pmflags & PMf_CONTINUE) && !(pm->op_pmflags & PMf_GLOBAL)
            && ckWARN(WARN_REGEXP))
     {
-        Perl_warner(aTHX_ packWARN(WARN_REGEXP), "Use of /c modifier is meaningless without /g" );
+        Perl_warner(aTHX_ packWARN(WARN_REGEXP), 
+            "Use of /c modifier is meaningless without /g" );
     }
 
     pm->op_pmpermflags = pm->op_pmflags;
@@ -10850,11 +10892,11 @@ S_scan_subst(pTHX_ char *start)
 #endif
 
     while (*s) {
-       if (*s == 'e') {
+       if (*s == EXEC_PAT_MOD) {
            s++;
            es++;
        }
-       else if (strchr("iogcmsx", *s))
+       else if (strchr(S_PAT_MODS, *s))
            pmflag(&pm->op_pmflags,*s++);
        else
            break;
@@ -10965,7 +11007,7 @@ S_scan_trans(pTHX_ char *start)
     }
   no_more:
 
-    Newx(tbl, complement&&!del?258:256, short);
+    tbl = (short *)PerlMemShared_calloc(complement&&!del?258:256, sizeof(short));
     o = newPVOP(OP_TRANS, 0, (char*)tbl);
     o->op_private &= ~OPpTRANS_ALL;
     o->op_private |= del|squash|complement|
@@ -11216,15 +11258,8 @@ S_scan_heredoc(pTHX_ register char *s)
        else if (PL_bufend - PL_linestart == 1 && PL_bufend[-1] == '\r')
            PL_bufend[-1] = '\n';
 #endif
-       if (PERLDB_LINE && PL_curstash != PL_debstash) {
-           SV * const sv = newSV(0);
-
-           sv_upgrade(sv, SVt_PVMG);
-           sv_setsv(sv,PL_linestr);
-            (void)SvIOK_on(sv);
-            SvIV_set(sv, 0);
-           av_store(CopFILEAVx(PL_curcop), (I32)CopLINE(PL_curcop),sv);
-       }
+       if (PERLDB_LINE && PL_curstash != PL_debstash)
+           update_debugger_info(PL_linestr, NULL, 0);
        if (*s == term && memEQ(s,PL_tokenbuf,len)) {
            STRLEN off = PL_bufend - 1 - SvPVX_const(PL_linestr);
            *(SvPVX(PL_linestr) + off ) = ' ';
@@ -11473,7 +11508,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
     I32 termcode;                      /* terminating char. code */
     U8 termstr[UTF8_MAXBYTES];         /* terminating string */
     STRLEN termlen;                    /* length of terminating string */
-    char *last = NULL;                 /* last position for nesting bracket */
+    int last_off = 0;                  /* last position for nesting bracket */
 #ifdef PERL_MAD
     int stuffstart;
     char *tstart;
@@ -11574,9 +11609,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
                    else {
                        const char *t;
                        char *w;
-                       if (!last)
-                           last = SvPVX(sv);
-                       for (t = w = last; t < svlast; w++, t++) {
+                       for (t = w = SvPVX(sv)+last_off; t < svlast; w++, t++) {
                            /* At here, all closes are "was quoted" one,
                               so we don't check PL_multi_close. */
                            if (*t == '\\') {
@@ -11595,7 +11628,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
                            *w = '\0';
                            SvCUR_set(sv, w - SvPVX_const(sv));
                        }
-                       last = w;
+                       last_off = w - SvPVX(sv);
                        if (--brackets <= 0)
                            cont = FALSE;
                    }
@@ -11722,15 +11755,8 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
        CopLINE_inc(PL_curcop);
 
        /* update debugger info */
-       if (PERLDB_LINE && PL_curstash != PL_debstash) {
-           SV * const line_sv = newSV(0);
-
-           sv_upgrade(line_sv, SVt_PVMG);
-           sv_setsv(line_sv,PL_linestr);
-           (void)SvIOK_on(line_sv);
-           SvIV_set(line_sv, 0);
-           av_store(CopFILEAVx(PL_curcop), (I32)CopLINE(PL_curcop), line_sv);
-       }
+       if (PERLDB_LINE && PL_curstash != PL_debstash)
+           update_debugger_info(PL_linestr, NULL, 0);
 
        /* having changed the buffer, we must update PL_bufend */
        PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
@@ -11743,7 +11769,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
 #ifdef PERL_MAD
        if (PL_madskills) {
            char * const tstart = SvPVX(PL_linestr) + stuffstart;
-           const int len = s - start;
+           const int len = s - tstart;
            if (PL_thisstuff)
                sv_catpvn(PL_thisstuff, tstart, len);
            else
@@ -12391,6 +12417,7 @@ Perl_yyerror(pTHX_ const char *s)
     const char *context = NULL;
     int contlen = -1;
     SV *msg;
+    int yychar  = PL_parser->yychar;
 
     if (!yychar || (yychar == ';' && !PL_rsfp))
        where = "at EOF";
@@ -12462,13 +12489,13 @@ Perl_yyerror(pTHX_ const char *s)
         PL_multi_end = 0;
     }
     if (PL_in_eval & EVAL_WARNONLY && ckWARN_d(WARN_SYNTAX))
-       Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "%"SVf, (void*)msg);
+       Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "%"SVf, SVfARG(msg));
     else
        qerror(msg);
     if (PL_error_count >= 10) {
        if (PL_in_eval && SvCUR(ERRSV))
            Perl_croak(aTHX_ "%"SVf"%s has too many errors.\n",
-                      (void*)ERRSV, OutCopFILE(PL_curcop));
+                      SVfARG(ERRSV), OutCopFILE(PL_curcop));
        else
            Perl_croak(aTHX_ "%s has too many errors.\n",
             OutCopFILE(PL_curcop));