perl 3.0 patch #13 (combined patch)
[p5sagit/p5-mst-13.2.git] / cons.c
diff --git a/cons.c b/cons.c
index 8e0c146..5515066 100644 (file)
--- a/cons.c
+++ b/cons.c
@@ -1,4 +1,4 @@
-/* $Header: cons.c,v 3.0 89/10/18 15:10:23 lwall Locked $
+/* $Header: cons.c,v 3.0.1.5 90/03/12 16:23:10 lwall Locked $
  *
  *    Copyright (c) 1989, Larry Wall
  *
@@ -6,6 +6,24 @@
  *    as specified in the README file that comes with the perl 3.0 kit.
  *
  * $Log:       cons.c,v $
+ * Revision 3.0.1.5  90/03/12  16:23:10  lwall
+ * patch13: perl -d coredumped on scripts with subs that did explicit return
+ * 
+ * Revision 3.0.1.4  90/02/28  16:44:00  lwall
+ * patch9: subs which return by both mechanisms can clobber local return data
+ * patch9: changed internal SUB label to _SUB_
+ * patch9: line numbers were bogus during certain portions of foreach evaluation
+ * 
+ * Revision 3.0.1.3  89/12/21  19:20:25  lwall
+ * patch7: made nested or recursive foreach work right
+ * 
+ * Revision 3.0.1.2  89/11/17  15:08:53  lwall
+ * patch5: nested foreach on same array didn't work
+ * 
+ * Revision 3.0.1.1  89/10/26  23:09:01  lwall
+ * patch1: numeric switch optimization was broken
+ * patch1: unless was broken when run under the debugger
+ * 
  * Revision 3.0  89/10/18  15:10:23  lwall
  * 3.0 baseline
  * 
@@ -57,8 +75,9 @@ CMD *cmd;
 
        mycompblock.comp_true = cmd;
        mycompblock.comp_alt = Nullcmd;
-       cmd = add_label(savestr("SUB"),make_ccmd(C_BLOCK,Nullarg,mycompblock));
+       cmd = add_label(savestr("_SUB_"),make_ccmd(C_BLOCK,Nullarg,mycompblock));
        saw_return = FALSE;
+       cmd->c_flags |= CF_TERM;
     }
     sub->cmd = cmd;
     stab_sub(stab) = sub;
@@ -285,11 +304,11 @@ int count;
 
     Newz(105,loc, max - min + 3, CMD*);
     loc++;
+    max -= min;
+    max++;
     while (count--) {
        i = (int)str_gnum(cur->c_short);
        i -= min;
-       max -= min;
-       max++;
        switch(cur->c_slen) {
        case O_LE:
            i++;
@@ -314,6 +333,7 @@ int count;
     }
     loc--;
     min--;
+    max++;
     for (i = 0; i <= max; i++)
        if (!loc[i])
            loc[i] = cur;
@@ -378,7 +398,7 @@ CMD *cur;
        stab2arg(A_WORD,DBstab),
        make_list(arg),
        Nullarg);
-    cmd->c_flags |= CF_COND;
+    cmd->c_flags |= CF_COND|CF_DBSUB;
     cmd->c_line = head->c_line;
     cmd->c_label = head->c_label;
     cmd->c_file = filename;
@@ -401,7 +421,9 @@ ARG *arg;
     cmd->c_expr = cond;
     if (cond)
        cmd->c_flags |= CF_COND;
-    if (cmdline != NOLINE) {
+    if (cmdline == NOLINE)
+       cmd->c_line = line;
+    else {
        cmd->c_line = cmdline;
        cmdline = NOLINE;
     }
@@ -426,7 +448,9 @@ struct compcmd cblock;
     cmd->ucmd.ccmd.cc_alt = cblock.comp_alt;
     if (arg)
        cmd->c_flags |= CF_COND;
-    if (cmdline != NOLINE) {
+    if (cmdline == NOLINE)
+       cmd->c_line = line;
+    else {
        cmd->c_line = cmdline;
        cmdline = NOLINE;
     }
@@ -455,7 +479,9 @@ struct compcmd cblock;
     cmd->ucmd.ccmd.cc_alt = cblock.comp_alt;
     if (arg)
        cmd->c_flags |= CF_COND;
-    if (cmdline != NOLINE) {
+    if (cmdline == NOLINE)
+       cmd->c_line = line;
+    else {
        cmd->c_line = cmdline;
        cmdline = NOLINE;
     }
@@ -797,12 +823,14 @@ register ARG *arg;
 
 CMD *
 invert(cmd)
-register CMD *cmd;
+CMD *cmd;
 {
-    if (cmd->c_head)
-       cmd->c_head->c_flags ^= CF_INVERT;
-    else
-       cmd->c_flags ^= CF_INVERT;
+    register CMD *targ = cmd;
+    if (targ->c_head)
+       targ = targ->c_head;
+    if (targ->c_flags & CF_DBSUB)
+       targ = targ->c_next;
+    targ->c_flags ^= CF_INVERT;
     return cmd;
 }
 
@@ -1022,6 +1050,8 @@ register CMD *cmd;
     cmd->c_flags &= ~CF_OPTIMIZE;      /* clear optimization type */
     cmd->c_flags |= CFT_ARRAY;         /* and set it to do the iteration */
     cmd->c_stab = eachstab;
+    cmd->c_short = str_new(0);         /* just to save a field in struct cmd */
+    cmd->c_short->str_u.str_useful = -1;
 
     return cmd;
 }
@@ -1182,20 +1212,26 @@ int willsave;                           /* willsave passes down the tree */
                /* Here we check to see if the temporary array generated for
                 * a foreach needs to be localized because of recursion.
                 */
-               if (tmpsave && (cmd->c_flags & CF_OPTIMIZE) == CFT_ARRAY &&
-                 lastcmd &&
-                 lastcmd->c_type == C_EXPR &&
-                 lastcmd->ucmd.acmd.ac_expr) {
-                   ARG *arg = lastcmd->ucmd.acmd.ac_expr;
-
-                   if (arg->arg_type == O_ASSIGN &&
-                       arg[1].arg_type == A_LEXPR &&
-                       arg[1].arg_ptr.arg_arg->arg_type == O_LARRAY &&
-                       strnEQ("_GEN_",
-                         stab_name(arg[1].arg_ptr.arg_arg[1].arg_ptr.arg_stab),
-                         5)) {         /* array generated for foreach */
-                       (void)localize(arg[1].arg_ptr.arg_arg);
+               if (tmpsave && (cmd->c_flags & CF_OPTIMIZE) == CFT_ARRAY) {
+                   if (lastcmd &&
+                     lastcmd->c_type == C_EXPR &&
+                     lastcmd->ucmd.acmd.ac_expr) {
+                       ARG *arg = lastcmd->ucmd.acmd.ac_expr;
+
+                       if (arg->arg_type == O_ASSIGN &&
+                           arg[1].arg_type == A_LEXPR &&
+                           arg[1].arg_ptr.arg_arg->arg_type == O_LARRAY &&
+                           strnEQ("_GEN_",
+                             stab_name(
+                               arg[1].arg_ptr.arg_arg[1].arg_ptr.arg_stab),
+                             5)) {     /* array generated for foreach */
+                           (void)localize(arg[1].arg_ptr.arg_arg);
+                       }
                    }
+
+                   /* in any event, save the iterator */
+
+                   (void)apush(tosave,cmd->c_short);
                }
                shouldsave |= tmpsave;
            }