home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl560.zip / x2p / walk.c < prev   
C/C++ Source or Header  |  1999-10-26  |  49KB  |  2,067 lines

  1. /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
  2.  *
  3.  *    Copyright (c) 1991-1997, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    walk.c,v $
  9.  */
  10.  
  11. #include "EXTERN.h"
  12. #include "a2p.h"
  13. #include "util.h"
  14.  
  15. bool exitval = FALSE;
  16. bool realexit = FALSE;
  17. bool saw_getline = FALSE;
  18. bool subretnum = FALSE;
  19. bool saw_FNR = FALSE;
  20. bool saw_argv0 = FALSE;
  21. bool saw_fh = FALSE;
  22. int maxtmp = 0;
  23. char *lparen;
  24. char *rparen;
  25. char *limit;
  26. STR *subs;
  27. STR *curargs = Nullstr;
  28.  
  29. static void addsemi ( STR *str );
  30. static void emit_split ( STR *str, int level );
  31. static void fixtab ( STR *str, int lvl );
  32. static void numericize ( int node );
  33. static void tab ( STR *str, int lvl );
  34.  
  35. int prewalk ( int numit, int level, int node, int *numericptr );
  36. STR * walk ( int useval, int level, int node, int *numericptr, int minprec );
  37.  
  38.  
  39. STR *
  40. walk(int useval, int level, register int node, int *numericptr, int minprec)
  41.            
  42.           
  43.                   
  44.                 
  45.                         /* minimum precedence without parens */
  46. {
  47.     register int len;
  48.     register STR *str;
  49.     register int type;
  50.     register int i;
  51.     register STR *tmpstr;
  52.     STR *tmp2str;
  53.     STR *tmp3str;
  54.     char *t;
  55.     char *d, *s;
  56.     int numarg;
  57.     int numeric = FALSE;
  58.     STR *fstr;
  59.     int prec = P_MAX;        /* assume no parens needed */
  60.  
  61.     if (!node) {
  62.     *numericptr = 0;
  63.     return str_make("");
  64.     }
  65.     type = ops[node].ival;
  66.     len = type >> 8;
  67.     type &= 255;
  68.     switch (type) {
  69.     case OPROG:
  70.     arymax = 0;
  71.     if (namelist) {
  72.         while (isalpha(*namelist)) {
  73.         for (d = tokenbuf,s=namelist;
  74.           isalpha(*s) || isdigit(*s) || *s == '_';
  75.           *d++ = *s++) ;
  76.         *d = '\0';
  77.         while (*s && !isalpha(*s)) s++;
  78.         namelist = s;
  79.         nameary[++arymax] = savestr(tokenbuf);
  80.         }
  81.     }
  82.     if (maxfld < arymax)
  83.         maxfld = arymax;
  84.     opens = str_new(0);
  85.     subs = str_new(0);
  86.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  87.     if (do_split && need_entire && !absmaxfld)
  88.         split_to_array = TRUE;
  89.     if (do_split && split_to_array)
  90.         set_array_base = TRUE;
  91.     if (set_array_base) {
  92.         str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
  93.     }
  94.     if (fswitch && !const_FS)
  95.         const_FS = fswitch;
  96.     if (saw_FS > 1 || saw_RS)
  97.         const_FS = 0;
  98.     if (saw_ORS && need_entire)
  99.         do_chop = TRUE;
  100.     if (fswitch) {
  101.         str_cat(str,"$FS = '");
  102.         if (strchr("*+?.[]()|^$\\",fswitch))
  103.         str_cat(str,"\\");
  104.         sprintf(tokenbuf,"%c",fswitch);
  105.         str_cat(str,tokenbuf);
  106.         str_cat(str,"';\t\t# field separator from -F switch\n");
  107.     }
  108.     else if (saw_FS && !const_FS) {
  109.         str_cat(str,"$FS = ' ';\t\t# set field separator\n");
  110.     }
  111.     if (saw_OFS) {
  112.         str_cat(str,"$, = ' ';\t\t# set output field separator\n");
  113.     }
  114.     if (saw_ORS) {
  115.         str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
  116.     }
  117.     if (saw_argv0) {
  118.         str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
  119.     }
  120.     if (str->str_cur > 20)
  121.         str_cat(str,"\n");
  122.     if (ops[node+2].ival) {
  123.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  124.         str_free(fstr);
  125.         str_cat(str,"\n\n");
  126.     }
  127.     fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
  128.     if (*fstr->str_ptr) {
  129.         if (saw_line_op)
  130.         str_cat(str,"line: ");
  131.         str_cat(str,"while (<>) {\n");
  132.         tab(str,++level);
  133.         if (saw_FS && !const_FS)
  134.         do_chop = TRUE;
  135.         if (do_chop) {
  136.         str_cat(str,"chomp;\t# strip record separator\n");
  137.         tab(str,level);
  138.         }
  139.         if (do_split)
  140.         emit_split(str,level);
  141.         str_scat(str,fstr);
  142.         str_free(fstr);
  143.         fixtab(str,--level);
  144.         str_cat(str,"}\n");
  145.         if (saw_FNR)
  146.         str_cat(str,"continue {\n    $FNRbase = $. if eof;\n}\n");
  147.     }
  148.     else if (old_awk)
  149.         str_cat(str,"while (<>) { }        # (no line actions)\n");
  150.     if (ops[node+4].ival) {
  151.         realexit = TRUE;
  152.         str_cat(str,"\n");
  153.         tab(str,level);
  154.         str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
  155.         str_free(fstr);
  156.         str_cat(str,"\n");
  157.     }
  158.     if (exitval)
  159.         str_cat(str,"exit $ExitValue;\n");
  160.     if (subs->str_ptr) {
  161.         str_cat(str,"\n");
  162.         str_scat(str,subs);
  163.     }
  164.     if (saw_getline) {
  165.         for (len = 0; len < 4; len++) {
  166.         if (saw_getline & (1 << len)) {
  167.             sprintf(tokenbuf,"\nsub Getline%d {\n",len);
  168.             str_cat(str, tokenbuf);
  169.             if (len & 2) {
  170.             if (do_fancy_opens)
  171.                 str_cat(str,"    &Pick('',@_);\n");
  172.             else
  173.                 str_cat(str,"    ($fh) = @_;\n");
  174.             }
  175.             else {
  176.             if (saw_FNR)
  177.                 str_cat(str,"    $FNRbase = $. if eof;\n");
  178.             }
  179.             if (len & 1)
  180.             str_cat(str,"    local($_);\n");
  181.             if (len & 2)
  182.             str_cat(str,
  183.               "    if ($getline_ok = (($_ = <$fh>) ne ''))");
  184.             else
  185.             str_cat(str,
  186.               "    if ($getline_ok = (($_ = <>) ne ''))");
  187.             str_cat(str, " {\n");
  188.             level += 2;
  189.             tab(str,level);
  190.             i = 0;
  191.             if (do_chop) {
  192.             i++;
  193.             str_cat(str,"chomp;\t# strip record separator\n");
  194.             tab(str,level);
  195.             }
  196.             if (do_split && !(len & 1)) {
  197.             i++;
  198.             emit_split(str,level);
  199.             }
  200.             if (!i)
  201.             str_cat(str,";\n");
  202.             fixtab(str,--level);
  203.             str_cat(str,"}\n    $_;\n}\n");
  204.             --level;
  205.         }
  206.         }
  207.     }
  208.     if (do_fancy_opens) {
  209.         str_cat(str,"\n\
  210. sub Pick {\n\
  211.     local($mode,$name,$pipe) = @_;\n\
  212.     $fh = $name;\n\
  213.     open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
  214. }\n\
  215. ");
  216.     }
  217.     break;
  218.     case OHUNKS:
  219.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  220.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  221.     str_free(fstr);
  222.     if (len == 3) {
  223.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  224.         str_free(fstr);
  225.     }
  226.     else {
  227.     }
  228.     break;
  229.     case ORANGE:
  230.     prec = P_DOTDOT;
  231.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  232.     str_cat(str," .. ");
  233.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  234.     str_free(fstr);
  235.     break;
  236.     case OPAT:
  237.     goto def;
  238.     case OREGEX:
  239.     str = str_new(0);
  240.     str_set(str,"/");
  241.     tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  242.     /* translate \nnn to [\nnn] */
  243.     for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
  244.         if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
  245.         *d++ = '[';
  246.         *d++ = *s++;
  247.         *d++ = *s++;
  248.         *d++ = *s++;
  249.         *d++ = *s;
  250.         *d = ']';
  251.         }
  252.         else
  253.         *d = *s;
  254.     }
  255.     *d = '\0';
  256.     for (d=tokenbuf; *d; d++)
  257.         *d += 128;
  258.     str_cat(str,tokenbuf);
  259.     str_free(tmpstr);
  260.     str_cat(str,"/");
  261.     break;
  262.     case OHUNK:
  263.     if (len == 1) {
  264.         str = str_new(0);
  265.         str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
  266.         str_cat(str," if ");
  267.         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  268.         str_free(fstr);
  269.         str_cat(str,";");
  270.     }
  271.     else {
  272.         tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  273.         if (*tmpstr->str_ptr) {
  274.         str = str_new(0);
  275.         str_set(str,"if (");
  276.         str_scat(str,tmpstr);
  277.         str_cat(str,") {\n");
  278.         tab(str,++level);
  279.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  280.         str_free(fstr);
  281.         fixtab(str,--level);
  282.         str_cat(str,"}\n");
  283.         tab(str,level);
  284.         }
  285.         else {
  286.         str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
  287.         }
  288.     }
  289.     break;
  290.     case OPPAREN:
  291.     str = str_new(0);
  292.     str_set(str,"(");
  293.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  294.     str_free(fstr);
  295.     str_cat(str,")");
  296.     break;
  297.     case OPANDAND:
  298.     prec = P_ANDAND;
  299.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  300.     str_cat(str," && ");
  301.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  302.     str_free(fstr);
  303.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  304.     str_free(fstr);
  305.     break;
  306.     case OPOROR:
  307.     prec = P_OROR;
  308.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  309.     str_cat(str," || ");
  310.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  311.     str_free(fstr);
  312.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  313.     str_free(fstr);
  314.     break;
  315.     case OPNOT:
  316.     prec = P_UNARY;
  317.     str = str_new(0);
  318.     str_set(str,"!");
  319.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  320.     str_free(fstr);
  321.     break;
  322.     case OCOND:
  323.     prec = P_COND;
  324.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  325.     str_cat(str," ? ");
  326.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  327.     str_free(fstr);
  328.     str_cat(str," : ");
  329.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  330.     str_free(fstr);
  331.     break;
  332.     case OCPAREN:
  333.     str = str_new(0);
  334.     str_set(str,"(");
  335.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  336.     str_free(fstr);
  337.     numeric |= numarg;
  338.     str_cat(str,")");
  339.     break;
  340.     case OCANDAND:
  341.     prec = P_ANDAND;
  342.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  343.     numeric = 1;
  344.     str_cat(str," && ");
  345.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  346.     str_free(fstr);
  347.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  348.     str_free(fstr);
  349.     break;
  350.     case OCOROR:
  351.     prec = P_OROR;
  352.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  353.     numeric = 1;
  354.     str_cat(str," || ");
  355.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  356.     str_free(fstr);
  357.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  358.     str_free(fstr);
  359.     break;
  360.     case OCNOT:
  361.     prec = P_UNARY;
  362.     str = str_new(0);
  363.     str_set(str,"!");
  364.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  365.     str_free(fstr);
  366.     numeric = 1;
  367.     break;
  368.     case ORELOP:
  369.     prec = P_REL;
  370.     str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
  371.     numeric |= numarg;
  372.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  373.     tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
  374.     numeric |= numarg;
  375.     if (!numeric ||
  376.      (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
  377.         t = tmpstr->str_ptr;
  378.         if (strEQ(t,"=="))
  379.         str_set(tmpstr,"eq");
  380.         else if (strEQ(t,"!="))
  381.         str_set(tmpstr,"ne");
  382.         else if (strEQ(t,"<"))
  383.         str_set(tmpstr,"lt");
  384.         else if (strEQ(t,"<="))
  385.         str_set(tmpstr,"le");
  386.         else if (strEQ(t,">"))
  387.         str_set(tmpstr,"gt");
  388.         else if (strEQ(t,">="))
  389.         str_set(tmpstr,"ge");
  390.         if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
  391.           !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
  392.         numeric |= 2;
  393.     }
  394.     if (numeric & 2) {
  395.         if (numeric & 1)        /* numeric is very good guess */
  396.         str_cat(str," ");
  397.         else
  398.         str_cat(str,"\377");
  399.         numeric = 1;
  400.     }
  401.     else
  402.         str_cat(str," ");
  403.     str_scat(str,tmpstr);
  404.     str_free(tmpstr);
  405.     str_cat(str," ");
  406.     str_scat(str,tmp2str);
  407.     str_free(tmp2str);
  408.     numeric = 1;
  409.     break;
  410.     case ORPAREN:
  411.     str = str_new(0);
  412.     str_set(str,"(");
  413.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  414.     str_free(fstr);
  415.     numeric |= numarg;
  416.     str_cat(str,")");
  417.     break;
  418.     case OMATCHOP:
  419.     prec = P_MATCH;
  420.     str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
  421.     str_cat(str," ");
  422.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  423.     if (strEQ(tmpstr->str_ptr,"~"))
  424.         str_cat(str,"=~");
  425.     else {
  426.         str_scat(str,tmpstr);
  427.         str_free(tmpstr);
  428.     }
  429.     str_cat(str," ");
  430.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  431.     str_free(fstr);
  432.     numeric = 1;
  433.     break;
  434.     case OMPAREN:
  435.     str = str_new(0);
  436.     str_set(str,"(");
  437.     str_scat(str,
  438.       fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  439.     str_free(fstr);
  440.     numeric |= numarg;
  441.     str_cat(str,")");
  442.     break;
  443.     case OCONCAT:
  444.     prec = P_ADD;
  445.     type = ops[ops[node+1].ival].ival & 255;
  446.     str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
  447.     str_cat(str," . ");
  448.     type = ops[ops[node+2].ival].ival & 255;
  449.     str_scat(str,
  450.       fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
  451.     str_free(fstr);
  452.     break;
  453.     case OASSIGN:
  454.     prec = P_ASSIGN;
  455.     str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
  456.     str_cat(str," ");
  457.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  458.     str_scat(str,tmpstr);
  459.     if (str_len(tmpstr) > 1)
  460.         numeric = 1;
  461.     str_free(tmpstr);
  462.     str_cat(str," ");
  463.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
  464.     str_free(fstr);
  465.     numeric |= numarg;
  466.     if (strEQ(str->str_ptr,"$/ = ''"))
  467.         str_set(str, "$/ = \"\\n\\n\"");
  468.     break;
  469.     case OADD:
  470.     prec = P_ADD;
  471.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  472.     str_cat(str," + ");
  473.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  474.     str_free(fstr);
  475.     numeric = 1;
  476.     break;
  477.     case OSUBTRACT:
  478.     prec = P_ADD;
  479.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  480.     str_cat(str," - ");
  481.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  482.     str_free(fstr);
  483.     numeric = 1;
  484.     break;
  485.     case OMULT:
  486.     prec = P_MUL;
  487.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  488.     str_cat(str," * ");
  489.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  490.     str_free(fstr);
  491.     numeric = 1;
  492.     break;
  493.     case ODIV:
  494.     prec = P_MUL;
  495.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  496.     str_cat(str," / ");
  497.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  498.     str_free(fstr);
  499.     numeric = 1;
  500.     break;
  501.     case OPOW:
  502.     prec = P_POW;
  503.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  504.     str_cat(str," ** ");
  505.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
  506.     str_free(fstr);
  507.     numeric = 1;
  508.     break;
  509.     case OMOD:
  510.     prec = P_MUL;
  511.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  512.     str_cat(str," % ");
  513.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  514.     str_free(fstr);
  515.     numeric = 1;
  516.     break;
  517.     case OPOSTINCR:
  518.     prec = P_AUTO;
  519.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  520.     str_cat(str,"++");
  521.     numeric = 1;
  522.     break;
  523.     case OPOSTDECR:
  524.     prec = P_AUTO;
  525.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  526.     str_cat(str,"--");
  527.     numeric = 1;
  528.     break;
  529.     case OPREINCR:
  530.     prec = P_AUTO;
  531.     str = str_new(0);
  532.     str_set(str,"++");
  533.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  534.     str_free(fstr);
  535.     numeric = 1;
  536.     break;
  537.     case OPREDECR:
  538.     prec = P_AUTO;
  539.     str = str_new(0);
  540.     str_set(str,"--");
  541.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  542.     str_free(fstr);
  543.     numeric = 1;
  544.     break;
  545.     case OUMINUS:
  546.     prec = P_UNARY;
  547.     str = str_new(0);
  548.     str_set(str,"-");
  549.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  550.     str_free(fstr);
  551.     numeric = 1;
  552.     break;
  553.     case OUPLUS:
  554.     numeric = 1;
  555.     goto def;
  556.     case OPAREN:
  557.     str = str_new(0);
  558.     str_set(str,"(");
  559.     str_scat(str,
  560.       fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  561.     str_free(fstr);
  562.     str_cat(str,")");
  563.     numeric |= numarg;
  564.     break;
  565.     case OGETLINE:
  566.     str = str_new(0);
  567.     if (useval)
  568.         str_cat(str,"(");
  569.     if (len > 0) {
  570.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  571.         if (!*fstr->str_ptr) {
  572.         str_cat(str,"$_");
  573.         len = 2;        /* a legal fiction */
  574.         }
  575.         str_free(fstr);
  576.     }
  577.     else
  578.         str_cat(str,"$_");
  579.     if (len > 1) {
  580.         tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
  581.         fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  582.         if (!do_fancy_opens) {
  583.         t = tmpstr->str_ptr;
  584.         if (*t == '"' || *t == '\'')
  585.             t = cpytill(tokenbuf,t+1,*t);
  586.         else
  587.             fatal("Internal error: OGETLINE %s", t);
  588.         d = savestr(t);
  589.         s = savestr(tokenbuf);
  590.         for (t = tokenbuf; *t; t++) {
  591.             *t &= 127;
  592.             if (islower(*t))
  593.             *t = toupper(*t);
  594.             if (!isalpha(*t) && !isdigit(*t))
  595.             *t = '_';
  596.         }
  597.         if (!strchr(tokenbuf,'_'))
  598.             strcpy(t,"_FH");
  599.         tmp3str = hfetch(symtab,tokenbuf);
  600.         if (!tmp3str) {
  601.             do_opens = TRUE;
  602.             str_cat(opens,"open(");
  603.             str_cat(opens,tokenbuf);
  604.             str_cat(opens,", ");
  605.             d[1] = '\0';
  606.             str_cat(opens,d);
  607.             str_cat(opens,tmpstr->str_ptr+1);
  608.             opens->str_cur--;
  609.             if (*fstr->str_ptr == '|')
  610.             str_cat(opens,"|");
  611.             str_cat(opens,d);
  612.             if (*fstr->str_ptr == '|')
  613.             str_cat(opens,") || die 'Cannot pipe from \"");
  614.             else
  615.             str_cat(opens,") || die 'Cannot open file \"");
  616.             if (*d == '"')
  617.             str_cat(opens,"'.\"");
  618.             str_cat(opens,s);
  619.             if (*d == '"')
  620.             str_cat(opens,"\".'");
  621.             str_cat(opens,"\".';\n");
  622.             hstore(symtab,tokenbuf,str_make("x"));
  623.         }
  624.         safefree(s);
  625.         safefree(d);
  626.         str_set(tmpstr,"'");
  627.         str_cat(tmpstr,tokenbuf);
  628.         str_cat(tmpstr,"'");
  629.         }
  630.         if (*fstr->str_ptr == '|')
  631.         str_cat(tmpstr,", '|'");
  632.         str_free(fstr);
  633.     }
  634.     else
  635.         tmpstr = str_make("");
  636.     sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
  637.     str_cat(str,tokenbuf); 
  638.     str_free(tmpstr);
  639.     if (useval)
  640.         str_cat(str,",$getline_ok)");
  641.     saw_getline |= 1 << len;
  642.     break;
  643.     case OSPRINTF:
  644.     str = str_new(0);
  645.     str_set(str,"sprintf(");
  646.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  647.     str_free(fstr);
  648.     str_cat(str,")");
  649.     break;
  650.     case OSUBSTR:
  651.     str = str_new(0);
  652.     str_set(str,"substr(");
  653.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  654.     str_free(fstr);
  655.     str_cat(str,", ");
  656.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
  657.     str_free(fstr);
  658.     str_cat(str,", ");
  659.     if (len == 3) {
  660.         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
  661.         str_free(fstr);
  662.     }
  663.     else
  664.         str_cat(str,"999999");
  665.     str_cat(str,")");
  666.     break;
  667.     case OSTRING:
  668.     str = str_new(0);
  669.     str_set(str,ops[node+1].cval);
  670.     break;
  671.     case OSPLIT:
  672.     str = str_new(0);
  673.     limit = ", 9999)";
  674.     numeric = 1;
  675.     tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  676.     if (useval)
  677.         str_set(str,"(@");
  678.     else
  679.         str_set(str,"@");
  680.     str_scat(str,tmpstr);
  681.     str_cat(str," = split(");
  682.     if (len == 3) {
  683.         fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
  684.         if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
  685.         i = fstr->str_ptr[1] & 127;
  686.         if (strchr("*+?.[]()|^$\\",i))
  687.             sprintf(tokenbuf,"/\\%c/",i);
  688.         else if (i == ' ')
  689.             sprintf(tokenbuf,"' '");
  690.         else
  691.             sprintf(tokenbuf,"/%c/",i);
  692.         str_cat(str,tokenbuf);
  693.         }
  694.         else
  695.         str_scat(str,fstr);
  696.         str_free(fstr);
  697.     }
  698.     else if (const_FS) {
  699.         sprintf(tokenbuf,"/[%c\\n]/",const_FS);
  700.         str_cat(str,tokenbuf);
  701.     }
  702.     else if (saw_FS)
  703.         str_cat(str,"$FS");
  704.     else {
  705.         str_cat(str,"' '");
  706.         limit = ")";
  707.     }
  708.     str_cat(str,", ");
  709.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  710.     str_free(fstr);
  711.     str_cat(str,limit);
  712.     if (useval) {
  713.         str_cat(str,")");
  714.     }
  715.     str_free(tmpstr);
  716.     break;
  717.     case OINDEX:
  718.     str = str_new(0);
  719.     str_set(str,"index(");
  720.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  721.     str_free(fstr);
  722.     str_cat(str,", ");
  723.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
  724.     str_free(fstr);
  725.     str_cat(str,")");
  726.     numeric = 1;
  727.     break;
  728.     case OMATCH:
  729.     str = str_new(0);
  730.     prec = P_ANDAND;
  731.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
  732.     str_free(fstr);
  733.     str_cat(str," =~ ");
  734.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
  735.     str_free(fstr);
  736.     str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
  737.     numeric = 1;
  738.     break;
  739.     case OUSERDEF:
  740.     str = str_new(0);
  741.     subretnum = FALSE;
  742.     fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
  743.     curargs = str_new(0);
  744.     str_sset(curargs,fstr);
  745.     str_cat(curargs,",");
  746.     tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
  747.     str_free(curargs);
  748.     curargs = Nullstr;
  749.     level--;
  750.     subretnum |= numarg;
  751.     s = Nullch;
  752.     t = tmp2str->str_ptr;
  753.     while (t = instr(t,"return "))
  754.         s = t++;
  755.     if (s) {
  756.         i = 0;
  757.         for (t = s+7; *t; t++) {
  758.         if (*t == ';' || *t == '}')
  759.             i++;
  760.         }
  761.         if (i == 1) {
  762.         strcpy(s,s+7);
  763.         tmp2str->str_cur -= 7;
  764.         }
  765.     }
  766.     str_set(str,"\n");
  767.     tab(str,level);
  768.     str_cat(str,"sub ");
  769.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  770.     str_cat(str," {\n");
  771.     tab(str,++level);
  772.     if (fstr->str_cur) {
  773.         str_cat(str,"local(");
  774.         str_scat(str,fstr);
  775.         str_cat(str,") = @_;");
  776.     }
  777.     str_free(fstr);
  778.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
  779.     str_free(fstr);
  780.     fixtab(str,level);
  781.     str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
  782.     str_free(fstr);
  783.     fixtab(str,level);
  784.     str_scat(str,tmp2str);
  785.     str_free(tmp2str);
  786.     fixtab(str,--level);
  787.     str_cat(str,"}\n");
  788.     tab(str,level);
  789.     str_scat(subs,str);
  790.     str_set(str,"");
  791.     str_cat(tmpstr,"(");
  792.     tmp2str = str_new(0);
  793.     if (subretnum)
  794.         str_set(tmp2str,"1");
  795.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  796.     str_free(tmpstr);
  797.     level++;
  798.     break;
  799.     case ORETURN:
  800.     str = str_new(0);
  801.     if (len > 0) {
  802.         str_cat(str,"return ");
  803.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
  804.         str_free(fstr);
  805.         if (numarg)
  806.         subretnum = TRUE;
  807.     }
  808.     else
  809.         str_cat(str,"return");
  810.     break;
  811.     case OUSERFUN:
  812.     str = str_new(0);
  813.     str_set(str,"&");
  814.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  815.     str_free(fstr);
  816.     str_cat(str,"(");
  817.     tmpstr = hfetch(symtab,str->str_ptr+3);
  818.     if (tmpstr && tmpstr->str_ptr)
  819.         numeric |= atoi(tmpstr->str_ptr);
  820.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  821.     str_free(fstr);
  822.     str_cat(str,")");
  823.     break;
  824.     case OGSUB:
  825.     case OSUB:
  826.     if (type == OGSUB)
  827.         s = "g";
  828.     else
  829.         s = "";
  830.     str = str_new(0);
  831.     tmpstr = str_new(0);
  832.     i = 0;
  833.     if (len == 3) {
  834.         tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
  835.         if (strNE(tmpstr->str_ptr,"$_")) {
  836.         str_cat(tmpstr, " =~ s");
  837.         i++;
  838.         }
  839.         else
  840.         str_set(tmpstr, "s");
  841.     }
  842.     else
  843.         str_set(tmpstr, "s");
  844.     type = ops[ops[node+2].ival].ival;
  845.     len = type >> 8;
  846.     type &= 255;
  847.     tmp3str = str_new(0);
  848.     if (type == OSTR) {
  849.         tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
  850.         for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
  851.         if (*t == '&')
  852.             *d++ = '$' + 128;
  853.         else if (*t == '$')
  854.             *d++ = '\\' + 128;
  855.         *d = *t + 128;
  856.         }
  857.         *d = '\0';
  858.         str_set(tmp2str,tokenbuf);
  859.     }
  860.     else {
  861.         tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  862.         str_set(tmp3str,"($s_ = '\"'.(");
  863.         str_scat(tmp3str,tmp2str);
  864.         str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
  865.         str_set(tmp2str,"eval $s_");
  866.         s = (char*)(*s == 'g' ? "ge" : "e");
  867.         i++;
  868.     }
  869.     type = ops[ops[node+1].ival].ival;
  870.     len = type >> 8;
  871.     type &= 255;
  872.     fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  873.     if (type == OREGEX) {
  874.         if (useval && i)
  875.         str_cat(str,"(");
  876.         str_scat(str,tmp3str);
  877.         str_scat(str,tmpstr);
  878.         str_scat(str,fstr);
  879.         str_scat(str,tmp2str);
  880.         str_cat(str,"/");
  881.         str_cat(str,s);
  882.     }
  883.     else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
  884.         if (useval && i)
  885.         str_cat(str,"(");
  886.         str_scat(str,tmp3str);
  887.         str_scat(str,tmpstr);
  888.         str_cat(str,"/");
  889.         str_scat(str,fstr);
  890.         str_cat(str,"/");
  891.         str_scat(str,tmp2str);
  892.         str_cat(str,"/");
  893.         str_cat(str,s);
  894.     }
  895.     else {
  896.         i++;
  897.         if (useval)
  898.         str_cat(str,"(");
  899.         str_cat(str,"$s = ");
  900.         str_scat(str,fstr);
  901.         str_cat(str,", ");
  902.         str_scat(str,tmp3str);
  903.         str_scat(str,tmpstr);
  904.         str_cat(str,"/$s/");
  905.         str_scat(str,tmp2str);
  906.         str_cat(str,"/");
  907.         str_cat(str,s);
  908.     }
  909.     if (useval && i)
  910.         str_cat(str,")");
  911.     str_free(fstr);
  912.     str_free(tmpstr);
  913.     str_free(tmp2str);
  914.     str_free(tmp3str);
  915.     numeric = 1;
  916.     break;
  917.     case ONUM:
  918.     str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  919.     numeric = 1;
  920.     break;
  921.     case OSTR:
  922.     tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  923.     s = "'";
  924.     for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
  925.         if (*t == '\'')
  926.         s = "\"";
  927.         else if (*t == '\\') {
  928.         s = "\"";
  929.         *d++ = *t++ + 128;
  930.         switch (*t) {
  931.         case '\\': case '"': case 'n': case 't': case '$':
  932.             break;
  933.         default:    /* hide this from perl */
  934.             *d++ = '\\' + 128;
  935.         }
  936.         }
  937.         *d = *t + 128;
  938.     }
  939.     *d = '\0';
  940.     str = str_new(0);
  941.     str_set(str,s);
  942.     str_cat(str,tokenbuf);
  943.     str_free(tmpstr);
  944.     str_cat(str,s);
  945.     break;
  946.     case ODEFINED:
  947.     prec = P_UNI;
  948.     str = str_new(0);
  949.     str_set(str,"defined $");
  950.     goto addvar;
  951.     case ODELETE:
  952.     str = str_new(0);
  953.     str_set(str,"delete $");
  954.     goto addvar;
  955.     case OSTAR:
  956.     str = str_new(0);
  957.     str_set(str,"*");
  958.     goto addvar;
  959.     case OVAR:
  960.     str = str_new(0);
  961.     str_set(str,"$");
  962.       addvar:
  963.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  964.     if (len == 1) {
  965.         tmp2str = hfetch(symtab,tmpstr->str_ptr);
  966.         if (tmp2str && atoi(tmp2str->str_ptr))
  967.         numeric = 2;
  968.         if (strEQ(str->str_ptr,"$FNR")) {
  969.         numeric = 1;
  970.         saw_FNR++;
  971.         str_set(str,"($.-$FNRbase)");
  972.         }
  973.         else if (strEQ(str->str_ptr,"$NR")) {
  974.         numeric = 1;
  975.         str_set(str,"$.");
  976.         }
  977.         else if (strEQ(str->str_ptr,"$NF")) {
  978.         numeric = 1;
  979.         str_set(str,"$#Fld");
  980.         }
  981.         else if (strEQ(str->str_ptr,"$0"))
  982.         str_set(str,"$_");
  983.         else if (strEQ(str->str_ptr,"$ARGC"))
  984.         str_set(str,"($#ARGV+1)");
  985.     }
  986.     else {
  987. #ifdef NOTDEF
  988.         if (curargs) {
  989.         sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
  990.     ???    if (instr(curargs->str_ptr,tokenbuf))
  991.             str_cat(str,"\377");    /* can't translate yet */
  992.         }
  993. #endif
  994.         str_cat(tmpstr,"[]");
  995.         tmp2str = hfetch(symtab,tmpstr->str_ptr);
  996.         if (tmp2str && atoi(tmp2str->str_ptr))
  997.         str_cat(str,"[");
  998.         else
  999.         str_cat(str,"{");
  1000.         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  1001.         str_free(fstr);
  1002.         if (strEQ(str->str_ptr,"$ARGV[0")) {
  1003.         str_set(str,"$ARGV0");
  1004.         saw_argv0++;
  1005.         }
  1006.         else {
  1007.         if (tmp2str && atoi(tmp2str->str_ptr))
  1008.             strcpy(tokenbuf,"]");
  1009.         else
  1010.             strcpy(tokenbuf,"}");
  1011.         *tokenbuf += 128;
  1012.         str_cat(str,tokenbuf);
  1013.         }
  1014.     }
  1015.     str_free(tmpstr);
  1016.     break;
  1017.     case OFLD:
  1018.     str = str_new(0);
  1019.     if (split_to_array) {
  1020.         str_set(str,"$Fld");
  1021.         str_cat(str,"[");
  1022.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1023.         str_free(fstr);
  1024.         str_cat(str,"]");
  1025.     }
  1026.     else {
  1027.         i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
  1028.         if (i <= arymax)
  1029.         sprintf(tokenbuf,"$%s",nameary[i]);
  1030.         else
  1031.         sprintf(tokenbuf,"$Fld%d",i);
  1032.         str_set(str,tokenbuf);
  1033.     }
  1034.     break;
  1035.     case OVFLD:
  1036.     str = str_new(0);
  1037.     str_set(str,"$Fld[");
  1038.     i = ops[node+1].ival;
  1039.     if ((ops[i].ival & 255) == OPAREN)
  1040.         i = ops[i+1].ival;
  1041.     tmpstr=walk(1,level,i,&numarg,P_MIN);
  1042.     str_scat(str,tmpstr);
  1043.     str_free(tmpstr);
  1044.     str_cat(str,"]");
  1045.     break;
  1046.     case OJUNK:
  1047.     goto def;
  1048.     case OSNEWLINE:
  1049.     str = str_new(2);
  1050.     str_set(str,";\n");
  1051.     tab(str,level);
  1052.     break;
  1053.     case ONEWLINE:
  1054.     str = str_new(1);
  1055.     str_set(str,"\n");
  1056.     tab(str,level);
  1057.     break;
  1058.     case OSCOMMENT:
  1059.     str = str_new(0);
  1060.     str_set(str,";");
  1061.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1062.     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
  1063.         *s += 128;
  1064.     str_scat(str,tmpstr);
  1065.     str_free(tmpstr);
  1066.     tab(str,level);
  1067.     break;
  1068.     case OCOMMENT:
  1069.     str = str_new(0);
  1070.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1071.     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
  1072.         *s += 128;
  1073.     str_scat(str,tmpstr);
  1074.     str_free(tmpstr);
  1075.     tab(str,level);
  1076.     break;
  1077.     case OCOMMA:
  1078.     prec = P_COMMA;
  1079.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  1080.     str_cat(str,", ");
  1081.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  1082.     str_free(fstr);
  1083.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  1084.     str_free(fstr);
  1085.     break;
  1086.     case OSEMICOLON:
  1087.     str = str_new(1);
  1088.     str_set(str,";\n");
  1089.     tab(str,level);
  1090.     break;
  1091.     case OSTATES:
  1092.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1093.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1094.     str_free(fstr);
  1095.     break;
  1096.     case OSTATE:
  1097.     str = str_new(0);
  1098.     if (len >= 1) {
  1099.         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  1100.         str_free(fstr);
  1101.         if (len >= 2) {
  1102.         tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
  1103.         if (*tmpstr->str_ptr == ';') {
  1104.             addsemi(str);
  1105.             str_cat(str,tmpstr->str_ptr+1);
  1106.         }
  1107.         str_free(tmpstr);
  1108.         }
  1109.     }
  1110.     break;
  1111.     case OCLOSE:
  1112.     str = str_make("close(");
  1113.     tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  1114.     if (!do_fancy_opens) {
  1115.         t = tmpstr->str_ptr;
  1116.         if (*t == '"' || *t == '\'')
  1117.         t = cpytill(tokenbuf,t+1,*t);
  1118.         else
  1119.         fatal("Internal error: OCLOSE %s",t);
  1120.         s = savestr(tokenbuf);
  1121.         for (t = tokenbuf; *t; t++) {
  1122.         *t &= 127;
  1123.         if (islower(*t))
  1124.             *t = toupper(*t);
  1125.         if (!isalpha(*t) && !isdigit(*t))
  1126.             *t = '_';
  1127.         }
  1128.         if (!strchr(tokenbuf,'_'))
  1129.         strcpy(t,"_FH");
  1130.         str_free(tmpstr);
  1131.         safefree(s);
  1132.         str_set(str,"close ");
  1133.         str_cat(str,tokenbuf);
  1134.     }
  1135.     else {
  1136.         sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
  1137.            tmpstr->str_ptr, tmpstr->str_ptr);
  1138.         str_free(tmpstr);
  1139.         str_set(str,tokenbuf);
  1140.     }
  1141.     break;
  1142.     case OPRINTF:
  1143.     case OPRINT:
  1144.     lparen = "";    /* set to parens if necessary */
  1145.     rparen = "";
  1146.     str = str_new(0);
  1147.     if (len == 3) {        /* output redirection */
  1148.         tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
  1149.         tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  1150.         if (!do_fancy_opens) {
  1151.         t = tmpstr->str_ptr;
  1152.         if (*t == '"' || *t == '\'')
  1153.             t = cpytill(tokenbuf,t+1,*t);
  1154.         else
  1155.             fatal("Internal error: OPRINT");
  1156.         d = savestr(t);
  1157.         s = savestr(tokenbuf);
  1158.         for (t = tokenbuf; *t; t++) {
  1159.             *t &= 127;
  1160.             if (islower(*t))
  1161.             *t = toupper(*t);
  1162.             if (!isalpha(*t) && !isdigit(*t))
  1163.             *t = '_';
  1164.         }
  1165.         if (!strchr(tokenbuf,'_'))
  1166.             strcpy(t,"_FH");
  1167.         tmp3str = hfetch(symtab,tokenbuf);
  1168.         if (!tmp3str) {
  1169.             str_cat(opens,"open(");
  1170.             str_cat(opens,tokenbuf);
  1171.             str_cat(opens,", ");
  1172.             d[1] = '\0';
  1173.             str_cat(opens,d);
  1174.             str_scat(opens,tmp2str);
  1175.             str_cat(opens,tmpstr->str_ptr+1);
  1176.             if (*tmp2str->str_ptr == '|')
  1177.             str_cat(opens,") || die 'Cannot pipe to \"");
  1178.             else
  1179.             str_cat(opens,") || die 'Cannot create file \"");
  1180.             if (*d == '"')
  1181.             str_cat(opens,"'.\"");
  1182.             str_cat(opens,s);
  1183.             if (*d == '"')
  1184.             str_cat(opens,"\".'");
  1185.             str_cat(opens,"\".';\n");
  1186.             hstore(symtab,tokenbuf,str_make("x"));
  1187.         }
  1188.         str_free(tmpstr);
  1189.         str_free(tmp2str);
  1190.         safefree(s);
  1191.         safefree(d);
  1192.         }
  1193.         else {
  1194.         sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
  1195.            tmp2str->str_ptr, tmpstr->str_ptr);
  1196.         str_cat(str,tokenbuf);
  1197.         tab(str,level+1);
  1198.         strcpy(tokenbuf,"$fh");
  1199.         str_free(tmpstr);
  1200.         str_free(tmp2str);
  1201.         lparen = "(";
  1202.         rparen = ")";
  1203.         }
  1204.     }
  1205.     else
  1206.         strcpy(tokenbuf,"");
  1207.     str_cat(str,lparen);    /* may be null */
  1208.     if (type == OPRINTF)
  1209.         str_cat(str,"printf");
  1210.     else
  1211.         str_cat(str,"print");
  1212.     saw_fh = 0;
  1213.     if (len == 3 || do_fancy_opens) {
  1214.         if (*tokenbuf) {
  1215.         str_cat(str," ");
  1216.         saw_fh = 1;
  1217.         }
  1218.         str_cat(str,tokenbuf);
  1219.     }
  1220.     tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
  1221.     if (!*tmpstr->str_ptr && lval_field) {
  1222.         t = (char*)(saw_OFS ? "$," : "' '");
  1223.         if (split_to_array) {
  1224.         sprintf(tokenbuf,"join(%s,@Fld)",t);
  1225.         str_cat(tmpstr,tokenbuf);
  1226.         }
  1227.         else {
  1228.         for (i = 1; i < maxfld; i++) {
  1229.             if (i <= arymax)
  1230.             sprintf(tokenbuf,"$%s, ",nameary[i]);
  1231.             else
  1232.             sprintf(tokenbuf,"$Fld%d, ",i);
  1233.             str_cat(tmpstr,tokenbuf);
  1234.         }
  1235.         if (maxfld <= arymax)
  1236.             sprintf(tokenbuf,"$%s",nameary[maxfld]);
  1237.         else
  1238.             sprintf(tokenbuf,"$Fld%d",maxfld);
  1239.         str_cat(tmpstr,tokenbuf);
  1240.         }
  1241.     }
  1242.     if (*tmpstr->str_ptr) {
  1243.         str_cat(str," ");
  1244.         if (!saw_fh && *tmpstr->str_ptr == '(') {
  1245.         str_cat(str,"(");
  1246.         str_scat(str,tmpstr);
  1247.         str_cat(str,")");
  1248.         }
  1249.         else
  1250.         str_scat(str,tmpstr);
  1251.     }
  1252.     else {
  1253.         str_cat(str," $_");
  1254.     }
  1255.     str_cat(str,rparen);    /* may be null */
  1256.     str_free(tmpstr);
  1257.     break;
  1258.     case ORAND:
  1259.     str = str_make("rand(1)");
  1260.     break;
  1261.     case OSRAND:
  1262.     str = str_make("srand(");
  1263.     goto maybe0;
  1264.     case OATAN2:
  1265.     str = str_make("atan2(");
  1266.     goto maybe0;
  1267.     case OSIN:
  1268.     str = str_make("sin(");
  1269.     goto maybe0;
  1270.     case OCOS:
  1271.     str = str_make("cos(");
  1272.     goto maybe0;
  1273.     case OSYSTEM:
  1274.     str = str_make("system(");
  1275.     goto maybe0;
  1276.     case OLENGTH:
  1277.     str = str_make("length(");
  1278.     goto maybe0;
  1279.     case OLOG:
  1280.     str = str_make("log(");
  1281.     goto maybe0;
  1282.     case OEXP:
  1283.     str = str_make("exp(");
  1284.     goto maybe0;
  1285.     case OSQRT:
  1286.     str = str_make("sqrt(");
  1287.     goto maybe0;
  1288.     case OINT:
  1289.     str = str_make("int(");
  1290.       maybe0:
  1291.     numeric = 1;
  1292.     if (len > 0)
  1293.         tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  1294.     else
  1295.         tmpstr = str_new(0);
  1296.     if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
  1297.         if (lval_field) {
  1298.         t = (char*)(saw_OFS ? "$," : "' '");
  1299.         if (split_to_array) {
  1300.             sprintf(tokenbuf,"join(%s,@Fld)",t);
  1301.             str_cat(tmpstr,tokenbuf);
  1302.         }
  1303.         else {
  1304.             sprintf(tokenbuf,"join(%s, ",t);
  1305.             str_cat(tmpstr,tokenbuf);
  1306.             for (i = 1; i < maxfld; i++) {
  1307.             if (i <= arymax)
  1308.                 sprintf(tokenbuf,"$%s,",nameary[i]);
  1309.             else
  1310.                 sprintf(tokenbuf,"$Fld%d,",i);
  1311.             str_cat(tmpstr,tokenbuf);
  1312.             }
  1313.             if (maxfld <= arymax)
  1314.             sprintf(tokenbuf,"$%s)",nameary[maxfld]);
  1315.             else
  1316.             sprintf(tokenbuf,"$Fld%d)",maxfld);
  1317.             str_cat(tmpstr,tokenbuf);
  1318.         }
  1319.         }
  1320.         else
  1321.         str_cat(tmpstr,"$_");
  1322.     }
  1323.     if (strEQ(tmpstr->str_ptr,"$_")) {
  1324.         if (type == OLENGTH && !do_chop) {
  1325.         str = str_make("(length(");
  1326.         str_cat(tmpstr,") - 1");
  1327.         }
  1328.     }
  1329.     str_scat(str,tmpstr);
  1330.     str_free(tmpstr);
  1331.     str_cat(str,")");
  1332.     break;
  1333.     case OBREAK:
  1334.     str = str_new(0);
  1335.     str_set(str,"last");
  1336.     break;
  1337.     case ONEXT:
  1338.     str = str_new(0);
  1339.     str_set(str,"next line");
  1340.     break;
  1341.     case OEXIT:
  1342.     str = str_new(0);
  1343.     if (realexit) {
  1344.         prec = P_UNI;
  1345.         str_set(str,"exit");
  1346.         if (len == 1) {
  1347.         str_cat(str," ");
  1348.         exitval = TRUE;
  1349.         str_scat(str,
  1350.           fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  1351.         str_free(fstr);
  1352.         }
  1353.     }
  1354.     else {
  1355.         if (len == 1) {
  1356.         str_set(str,"$ExitValue = ");
  1357.         exitval = TRUE;
  1358.         str_scat(str,
  1359.           fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
  1360.         str_free(fstr);
  1361.         str_cat(str,"; ");
  1362.         }
  1363.         str_cat(str,"last line");
  1364.     }
  1365.     break;
  1366.     case OCONTINUE:
  1367.     str = str_new(0);
  1368.     str_set(str,"next");
  1369.     break;
  1370.     case OREDIR:
  1371.     goto def;
  1372.     case OIF:
  1373.     str = str_new(0);
  1374.     str_set(str,"if (");
  1375.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1376.     str_free(fstr);
  1377.     str_cat(str,") ");
  1378.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1379.     str_free(fstr);
  1380.     if (len == 3) {
  1381.         i = ops[node+3].ival;
  1382.         if (i) {
  1383.         if ((ops[i].ival & 255) == OBLOCK) {
  1384.             i = ops[i+1].ival;
  1385.             if (i) {
  1386.             if ((ops[i].ival & 255) != OIF)
  1387.                 i = 0;
  1388.             }
  1389.         }
  1390.         else
  1391.             i = 0;
  1392.         }
  1393.         if (i) {
  1394.         str_cat(str,"els");
  1395.         str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
  1396.         str_free(fstr);
  1397.         }
  1398.         else {
  1399.         str_cat(str,"else ");
  1400.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  1401.         str_free(fstr);
  1402.         }
  1403.     }
  1404.     break;
  1405.     case OWHILE:
  1406.     str = str_new(0);
  1407.     str_set(str,"while (");
  1408.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1409.     str_free(fstr);
  1410.     str_cat(str,") ");
  1411.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1412.     str_free(fstr);
  1413.     break;
  1414.     case ODO:
  1415.     str = str_new(0);
  1416.     str_set(str,"do ");
  1417.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1418.     str_free(fstr);
  1419.     if (str->str_ptr[str->str_cur - 1] == '\n')
  1420.         --str->str_cur;
  1421.     str_cat(str," while (");
  1422.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1423.     str_free(fstr);
  1424.     str_cat(str,");");
  1425.     break;
  1426.     case OFOR:
  1427.     str = str_new(0);
  1428.     str_set(str,"for (");
  1429.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1430.     i = numarg;
  1431.     if (i) {
  1432.         t = s = tmpstr->str_ptr;
  1433.         while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
  1434.         t++;
  1435.         i = t - s;
  1436.         if (i < 2)
  1437.         i = 0;
  1438.     }
  1439.     str_cat(str,"; ");
  1440.     fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  1441.     if (i && (t = strchr(fstr->str_ptr,0377))) {
  1442.         if (strnEQ(fstr->str_ptr,s,i))
  1443.         *t = ' ';
  1444.     }
  1445.     str_scat(str,fstr);
  1446.     str_free(fstr);
  1447.     str_free(tmpstr);
  1448.     str_cat(str,"; ");
  1449.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
  1450.     str_free(fstr);
  1451.     str_cat(str,") ");
  1452.     str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
  1453.     str_free(fstr);
  1454.     break;
  1455.     case OFORIN:
  1456.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1457.     d = strchr(tmpstr->str_ptr,'$');
  1458.     if (!d)
  1459.         fatal("Illegal for loop: %s",tmpstr->str_ptr);
  1460.     s = strchr(d,'{');
  1461.     if (!s)
  1462.         s = strchr(d,'[');
  1463.     if (!s)
  1464.         fatal("Illegal for loop: %s",d);
  1465.     *s++ = '\0';
  1466.     for (t = s; i = *t; t++) {
  1467.         i &= 127;
  1468.         if (i == '}' || i == ']')
  1469.         break;
  1470.     }
  1471.     if (*t)
  1472.         *t = '\0';
  1473.     str = str_new(0);
  1474.     str_set(str,d+1);
  1475.     str_cat(str,"[]");
  1476.     tmp2str = hfetch(symtab,str->str_ptr);
  1477.     if (tmp2str && atoi(tmp2str->str_ptr)) {
  1478.         sprintf(tokenbuf,
  1479.           "foreach %s ($[ .. $#%s) ",
  1480.           s,
  1481.           d+1);
  1482.     }
  1483.     else {
  1484.         sprintf(tokenbuf,
  1485.           "foreach %s (keys %%%s) ",
  1486.           s,
  1487.           d+1);
  1488.     }
  1489.     str_set(str,tokenbuf);
  1490.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1491.     str_free(fstr);
  1492.     str_free(tmpstr);
  1493.     break;
  1494.     case OBLOCK:
  1495.     str = str_new(0);
  1496.     str_set(str,"{");
  1497.     if (len >= 2 && ops[node+2].ival) {
  1498.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1499.         str_free(fstr);
  1500.     }
  1501.     fixtab(str,++level);
  1502.     str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  1503.     str_free(fstr);
  1504.     addsemi(str);
  1505.     fixtab(str,--level);
  1506.     str_cat(str,"}\n");
  1507.     tab(str,level);
  1508.     if (len >= 3) {
  1509.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  1510.         str_free(fstr);
  1511.     }
  1512.     break;
  1513.     default:
  1514.       def:
  1515.     if (len) {
  1516.         if (len > 5)
  1517.         fatal("Garbage length in walk");
  1518.         str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1519.         for (i = 2; i<= len; i++) {
  1520.         str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
  1521.         str_free(fstr);
  1522.         }
  1523.     }
  1524.     else {
  1525.         str = Nullstr;
  1526.     }
  1527.     break;
  1528.     }
  1529.     if (!str)
  1530.     str = str_new(0);
  1531.  
  1532.     if (useval && prec < minprec) {        /* need parens? */
  1533.     fstr = str_new(str->str_cur+2);
  1534.     str_nset(fstr,"(",1);
  1535.     str_scat(fstr,str);
  1536.     str_ncat(fstr,")",1);
  1537.     str_free(str);
  1538.     str = fstr;
  1539.     }
  1540.  
  1541.     *numericptr = numeric;
  1542. #ifdef DEBUGGING
  1543.     if (debug & 4) {
  1544.     printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
  1545.     for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
  1546.         if (*t == '\n')
  1547.         printf("\\n");
  1548.         else if (*t == '\t')
  1549.         printf("\\t");
  1550.         else
  1551.         putchar(*t);
  1552.     putchar('\n');
  1553.     }
  1554. #endif
  1555.     return str;
  1556. }
  1557.  
  1558. static void
  1559. tab(register STR *str, register int lvl)
  1560. {
  1561.     while (lvl > 1) {
  1562.     str_cat(str,"\t");
  1563.     lvl -= 2;
  1564.     }
  1565.     if (lvl)
  1566.     str_cat(str,"    ");
  1567. }
  1568.  
  1569. static void
  1570. fixtab(register STR *str, register int lvl)
  1571. {
  1572.     register char *s;
  1573.  
  1574.     /* strip trailing white space */
  1575.  
  1576.     s = str->str_ptr+str->str_cur - 1;
  1577.     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
  1578.     s--;
  1579.     s[1] = '\0';
  1580.     str->str_cur = s + 1 - str->str_ptr;
  1581.     if (s >= str->str_ptr && *s != '\n')
  1582.     str_cat(str,"\n");
  1583.  
  1584.     tab(str,lvl);
  1585. }
  1586.  
  1587. static void
  1588. addsemi(register STR *str)
  1589. {
  1590.     register char *s;
  1591.  
  1592.     s = str->str_ptr+str->str_cur - 1;
  1593.     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
  1594.     s--;
  1595.     if (s >= str->str_ptr && *s != ';' && *s != '}')
  1596.     str_cat(str,";");
  1597. }
  1598.  
  1599. static void
  1600. emit_split(register STR *str, int level)
  1601. {
  1602.     register int i;
  1603.  
  1604.     if (split_to_array)
  1605.     str_cat(str,"@Fld");
  1606.     else {
  1607.     str_cat(str,"(");
  1608.     for (i = 1; i < maxfld; i++) {
  1609.         if (i <= arymax)
  1610.         sprintf(tokenbuf,"$%s,",nameary[i]);
  1611.         else
  1612.         sprintf(tokenbuf,"$Fld%d,",i);
  1613.         str_cat(str,tokenbuf);
  1614.     }
  1615.     if (maxfld <= arymax)
  1616.         sprintf(tokenbuf,"$%s)",nameary[maxfld]);
  1617.     else
  1618.         sprintf(tokenbuf,"$Fld%d)",maxfld);
  1619.     str_cat(str,tokenbuf);
  1620.     }
  1621.     if (const_FS) {
  1622.     sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
  1623.     str_cat(str,tokenbuf);
  1624.     }
  1625.     else if (saw_FS)
  1626.     str_cat(str," = split($FS, $_, 9999);\n");
  1627.     else
  1628.     str_cat(str," = split(' ', $_, 9999);\n");
  1629.     tab(str,level);
  1630. }
  1631.  
  1632. int
  1633. prewalk(int numit, int level, register int node, int *numericptr)
  1634. {
  1635.     register int len;
  1636.     register int type;
  1637.     register int i;
  1638.     int numarg;
  1639.     int numeric = FALSE;
  1640.     STR *tmpstr;
  1641.     STR *tmp2str;
  1642.  
  1643.     if (!node) {
  1644.     *numericptr = 0;
  1645.     return 0;
  1646.     }
  1647.     type = ops[node].ival;
  1648.     len = type >> 8;
  1649.     type &= 255;
  1650.     switch (type) {
  1651.     case OPROG:
  1652.     prewalk(0,level,ops[node+1].ival,&numarg);
  1653.     if (ops[node+2].ival) {
  1654.         prewalk(0,level,ops[node+2].ival,&numarg);
  1655.     }
  1656.     ++level;
  1657.     prewalk(0,level,ops[node+3].ival,&numarg);
  1658.     --level;
  1659.     if (ops[node+3].ival) {
  1660.         prewalk(0,level,ops[node+4].ival,&numarg);
  1661.     }
  1662.     break;
  1663.     case OHUNKS:
  1664.     prewalk(0,level,ops[node+1].ival,&numarg);
  1665.     prewalk(0,level,ops[node+2].ival,&numarg);
  1666.     if (len == 3) {
  1667.         prewalk(0,level,ops[node+3].ival,&numarg);
  1668.     }
  1669.     break;
  1670.     case ORANGE:
  1671.     prewalk(1,level,ops[node+1].ival,&numarg);
  1672.     prewalk(1,level,ops[node+2].ival,&numarg);
  1673.     break;
  1674.     case OPAT:
  1675.     goto def;
  1676.     case OREGEX:
  1677.     prewalk(0,level,ops[node+1].ival,&numarg);
  1678.     break;
  1679.     case OHUNK:
  1680.     if (len == 1) {
  1681.         prewalk(0,level,ops[node+1].ival,&numarg);
  1682.     }
  1683.     else {
  1684.         i = prewalk(0,level,ops[node+1].ival,&numarg);
  1685.         if (i) {
  1686.         ++level;
  1687.         prewalk(0,level,ops[node+2].ival,&numarg);
  1688.         --level;
  1689.         }
  1690.         else {
  1691.         prewalk(0,level,ops[node+2].ival,&numarg);
  1692.         }
  1693.     }
  1694.     break;
  1695.     case OPPAREN:
  1696.     prewalk(0,level,ops[node+1].ival,&numarg);
  1697.     break;
  1698.     case OPANDAND:
  1699.     prewalk(0,level,ops[node+1].ival,&numarg);
  1700.     prewalk(0,level,ops[node+2].ival,&numarg);
  1701.     break;
  1702.     case OPOROR:
  1703.     prewalk(0,level,ops[node+1].ival,&numarg);
  1704.     prewalk(0,level,ops[node+2].ival,&numarg);
  1705.     break;
  1706.     case OPNOT:
  1707.     prewalk(0,level,ops[node+1].ival,&numarg);
  1708.     break;
  1709.     case OCPAREN:
  1710.     prewalk(0,level,ops[node+1].ival,&numarg);
  1711.     numeric |= numarg;
  1712.     break;
  1713.     case OCANDAND:
  1714.     prewalk(0,level,ops[node+1].ival,&numarg);
  1715.     numeric = 1;
  1716.     prewalk(0,level,ops[node+2].ival,&numarg);
  1717.     break;
  1718.     case OCOROR:
  1719.     prewalk(0,level,ops[node+1].ival,&numarg);
  1720.     numeric = 1;
  1721.     prewalk(0,level,ops[node+2].ival,&numarg);
  1722.     break;
  1723.     case OCNOT:
  1724.     prewalk(0,level,ops[node+1].ival,&numarg);
  1725.     numeric = 1;
  1726.     break;
  1727.     case ORELOP:
  1728.     prewalk(0,level,ops[node+2].ival,&numarg);
  1729.     numeric |= numarg;
  1730.     prewalk(0,level,ops[node+1].ival,&numarg);
  1731.     prewalk(0,level,ops[node+3].ival,&numarg);
  1732.     numeric |= numarg;
  1733.     numeric = 1;
  1734.     break;
  1735.     case ORPAREN:
  1736.     prewalk(0,level,ops[node+1].ival,&numarg);
  1737.     numeric |= numarg;
  1738.     break;
  1739.     case OMATCHOP:
  1740.     prewalk(0,level,ops[node+2].ival,&numarg);
  1741.     prewalk(0,level,ops[node+1].ival,&numarg);
  1742.     prewalk(0,level,ops[node+3].ival,&numarg);
  1743.     numeric = 1;
  1744.     break;
  1745.     case OMPAREN:
  1746.     prewalk(0,level,ops[node+1].ival,&numarg);
  1747.     numeric |= numarg;
  1748.     break;
  1749.     case OCONCAT:
  1750.     prewalk(0,level,ops[node+1].ival,&numarg);
  1751.     prewalk(0,level,ops[node+2].ival,&numarg);
  1752.     break;
  1753.     case OASSIGN:
  1754.     prewalk(0,level,ops[node+2].ival,&numarg);
  1755.     prewalk(0,level,ops[node+1].ival,&numarg);
  1756.     prewalk(0,level,ops[node+3].ival,&numarg);
  1757.     if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
  1758.         numericize(ops[node+2].ival);
  1759.         if (!numarg)
  1760.         numericize(ops[node+3].ival);
  1761.     }
  1762.     numeric |= numarg;
  1763.     break;
  1764.     case OADD:
  1765.     prewalk(1,level,ops[node+1].ival,&numarg);
  1766.     prewalk(1,level,ops[node+2].ival,&numarg);
  1767.     numeric = 1;
  1768.     break;
  1769.     case OSUBTRACT:
  1770.     prewalk(1,level,ops[node+1].ival,&numarg);
  1771.     prewalk(1,level,ops[node+2].ival,&numarg);
  1772.     numeric = 1;
  1773.     break;
  1774.     case OMULT:
  1775.     prewalk(1,level,ops[node+1].ival,&numarg);
  1776.     prewalk(1,level,ops[node+2].ival,&numarg);
  1777.     numeric = 1;
  1778.     break;
  1779.     case ODIV:
  1780.     prewalk(1,level,ops[node+1].ival,&numarg);
  1781.     prewalk(1,level,ops[node+2].ival,&numarg);
  1782.     numeric = 1;
  1783.     break;
  1784.     case OPOW:
  1785.     prewalk(1,level,ops[node+1].ival,&numarg);
  1786.     prewalk(1,level,ops[node+2].ival,&numarg);
  1787.     numeric = 1;
  1788.     break;
  1789.     case OMOD:
  1790.     prewalk(1,level,ops[node+1].ival,&numarg);
  1791.     prewalk(1,level,ops[node+2].ival,&numarg);
  1792.     numeric = 1;
  1793.     break;
  1794.     case OPOSTINCR:
  1795.     prewalk(1,level,ops[node+1].ival,&numarg);
  1796.     numeric = 1;
  1797.     break;
  1798.     case OPOSTDECR:
  1799.     prewalk(1,level,ops[node+1].ival,&numarg);
  1800.     numeric = 1;
  1801.     break;
  1802.     case OPREINCR:
  1803.     prewalk(1,level,ops[node+1].ival,&numarg);
  1804.     numeric = 1;
  1805.     break;
  1806.     case OPREDECR:
  1807.     prewalk(1,level,ops[node+1].ival,&numarg);
  1808.     numeric = 1;
  1809.     break;
  1810.     case OUMINUS:
  1811.     prewalk(1,level,ops[node+1].ival,&numarg);
  1812.     numeric = 1;
  1813.     break;
  1814.     case OUPLUS:
  1815.     prewalk(1,level,ops[node+1].ival,&numarg);
  1816.     numeric = 1;
  1817.     break;
  1818.     case OPAREN:
  1819.     prewalk(0,level,ops[node+1].ival,&numarg);
  1820.     numeric |= numarg;
  1821.     break;
  1822.     case OGETLINE:
  1823.     break;
  1824.     case OSPRINTF:
  1825.     prewalk(0,level,ops[node+1].ival,&numarg);
  1826.     break;
  1827.     case OSUBSTR:
  1828.     prewalk(0,level,ops[node+1].ival,&numarg);
  1829.     prewalk(1,level,ops[node+2].ival,&numarg);
  1830.     if (len == 3) {
  1831.         prewalk(1,level,ops[node+3].ival,&numarg);
  1832.     }
  1833.     break;
  1834.     case OSTRING:
  1835.     break;
  1836.     case OSPLIT:
  1837.     numeric = 1;
  1838.     prewalk(0,level,ops[node+2].ival,&numarg);
  1839.     if (len == 3)
  1840.         prewalk(0,level,ops[node+3].ival,&numarg);
  1841.     prewalk(0,level,ops[node+1].ival,&numarg);
  1842.     break;
  1843.     case OINDEX:
  1844.     prewalk(0,level,ops[node+1].ival,&numarg);
  1845.     prewalk(0,level,ops[node+2].ival,&numarg);
  1846.     numeric = 1;
  1847.     break;
  1848.     case OMATCH:
  1849.     prewalk(0,level,ops[node+1].ival,&numarg);
  1850.     prewalk(0,level,ops[node+2].ival,&numarg);
  1851.     numeric = 1;
  1852.     break;
  1853.     case OUSERDEF:
  1854.     subretnum = FALSE;
  1855.     --level;
  1856.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1857.     ++level;
  1858.     prewalk(0,level,ops[node+2].ival,&numarg);
  1859.     prewalk(0,level,ops[node+4].ival,&numarg);
  1860.     prewalk(0,level,ops[node+5].ival,&numarg);
  1861.     --level;
  1862.     str_cat(tmpstr,"(");
  1863.     tmp2str = str_new(0);
  1864.     if (subretnum || numarg)
  1865.         str_set(tmp2str,"1");
  1866.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  1867.     str_free(tmpstr);
  1868.     level++;
  1869.     break;
  1870.     case ORETURN:
  1871.     if (len > 0) {
  1872.         prewalk(0,level,ops[node+1].ival,&numarg);
  1873.         if (numarg)
  1874.         subretnum = TRUE;
  1875.     }
  1876.     break;
  1877.     case OUSERFUN:
  1878.     tmp2str = str_new(0);
  1879.     str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1880.     fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
  1881.     str_free(tmpstr);
  1882.     str_cat(tmp2str,"(");
  1883.     tmpstr = hfetch(symtab,tmp2str->str_ptr);
  1884.     if (tmpstr && tmpstr->str_ptr)
  1885.         numeric |= atoi(tmpstr->str_ptr);
  1886.     prewalk(0,level,ops[node+2].ival,&numarg);
  1887.     str_free(tmp2str);
  1888.     break;
  1889.     case OGSUB:
  1890.     case OSUB:
  1891.     if (len >= 3)
  1892.         prewalk(0,level,ops[node+3].ival,&numarg);
  1893.     prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
  1894.     prewalk(0,level,ops[node+1].ival,&numarg);
  1895.     numeric = 1;
  1896.     break;
  1897.     case ONUM:
  1898.     prewalk(0,level,ops[node+1].ival,&numarg);
  1899.     numeric = 1;
  1900.     break;
  1901.     case OSTR:
  1902.     prewalk(0,level,ops[node+1].ival,&numarg);
  1903.     break;
  1904.     case ODEFINED:
  1905.     case ODELETE:
  1906.     case OSTAR:
  1907.     case OVAR:
  1908.     prewalk(0,level,ops[node+1].ival,&numarg);
  1909.     if (len == 1) {
  1910.         if (numit)
  1911.         numericize(node);
  1912.     }
  1913.     else {
  1914.         prewalk(0,level,ops[node+2].ival,&numarg);
  1915.     }
  1916.     break;
  1917.     case OFLD:
  1918.     prewalk(0,level,ops[node+1].ival,&numarg);
  1919.     break;
  1920.     case OVFLD:
  1921.     i = ops[node+1].ival;
  1922.     prewalk(0,level,i,&numarg);
  1923.     break;
  1924.     case OJUNK:
  1925.     goto def;
  1926.     case OSNEWLINE:
  1927.     break;
  1928.     case ONEWLINE:
  1929.     break;
  1930.     case OSCOMMENT:
  1931.     break;
  1932.     case OCOMMENT:
  1933.     break;
  1934.     case OCOMMA:
  1935.     prewalk(0,level,ops[node+1].ival,&numarg);
  1936.     prewalk(0,level,ops[node+2].ival,&numarg);
  1937.     prewalk(0,level,ops[node+3].ival,&numarg);
  1938.     break;
  1939.     case OSEMICOLON:
  1940.     break;
  1941.     case OSTATES:
  1942.     prewalk(0,level,ops[node+1].ival,&numarg);
  1943.     prewalk(0,level,ops[node+2].ival,&numarg);
  1944.     break;
  1945.     case OSTATE:
  1946.     if (len >= 1) {
  1947.         prewalk(0,level,ops[node+1].ival,&numarg);
  1948.         if (len >= 2) {
  1949.         prewalk(0,level,ops[node+2].ival,&numarg);
  1950.         }
  1951.     }
  1952.     break;
  1953.     case OCLOSE:
  1954.     prewalk(0,level,ops[node+1].ival,&numarg);
  1955.     break;
  1956.     case OPRINTF:
  1957.     case OPRINT:
  1958.     if (len == 3) {        /* output redirection */
  1959.         prewalk(0,level,ops[node+3].ival,&numarg);
  1960.         prewalk(0,level,ops[node+2].ival,&numarg);
  1961.     }
  1962.     prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
  1963.     break;
  1964.     case ORAND:
  1965.     break;
  1966.     case OSRAND:
  1967.     goto maybe0;
  1968.     case OATAN2:
  1969.     goto maybe0;
  1970.     case OSIN:
  1971.     goto maybe0;
  1972.     case OCOS:
  1973.     goto maybe0;
  1974.     case OSYSTEM:
  1975.     goto maybe0;
  1976.     case OLENGTH:
  1977.     goto maybe0;
  1978.     case OLOG:
  1979.     goto maybe0;
  1980.     case OEXP:
  1981.     goto maybe0;
  1982.     case OSQRT:
  1983.     goto maybe0;
  1984.     case OINT:
  1985.       maybe0:
  1986.     numeric = 1;
  1987.     if (len > 0)
  1988.         prewalk(type != OLENGTH && type != OSYSTEM,
  1989.           level,ops[node+1].ival,&numarg);
  1990.     break;
  1991.     case OBREAK:
  1992.     break;
  1993.     case ONEXT:
  1994.     break;
  1995.     case OEXIT:
  1996.     if (len == 1) {
  1997.         prewalk(1,level,ops[node+1].ival,&numarg);
  1998.     }
  1999.     break;
  2000.     case OCONTINUE:
  2001.     break;
  2002.     case OREDIR:
  2003.     goto def;
  2004.     case OIF:
  2005.     prewalk(0,level,ops[node+1].ival,&numarg);
  2006.     prewalk(0,level,ops[node+2].ival,&numarg);
  2007.     if (len == 3) {
  2008.         prewalk(0,level,ops[node+3].ival,&numarg);
  2009.     }
  2010.     break;
  2011.     case OWHILE:
  2012.     prewalk(0,level,ops[node+1].ival,&numarg);
  2013.     prewalk(0,level,ops[node+2].ival,&numarg);
  2014.     break;
  2015.     case OFOR:
  2016.     prewalk(0,level,ops[node+1].ival,&numarg);
  2017.     prewalk(0,level,ops[node+2].ival,&numarg);
  2018.     prewalk(0,level,ops[node+3].ival,&numarg);
  2019.     prewalk(0,level,ops[node+4].ival,&numarg);
  2020.     break;
  2021.     case OFORIN:
  2022.     prewalk(0,level,ops[node+2].ival,&numarg);
  2023.     prewalk(0,level,ops[node+1].ival,&numarg);
  2024.     break;
  2025.     case OBLOCK:
  2026.     if (len == 2) {
  2027.         prewalk(0,level,ops[node+2].ival,&numarg);
  2028.     }
  2029.     ++level;
  2030.     prewalk(0,level,ops[node+1].ival,&numarg);
  2031.     --level;
  2032.     break;
  2033.     default:
  2034.       def:
  2035.     if (len) {
  2036.         if (len > 5)
  2037.         fatal("Garbage length in prewalk");
  2038.         prewalk(0,level,ops[node+1].ival,&numarg);
  2039.         for (i = 2; i<= len; i++) {
  2040.         prewalk(0,level,ops[node+i].ival,&numarg);
  2041.         }
  2042.     }
  2043.     break;
  2044.     }
  2045.     *numericptr = numeric;
  2046.     return 1;
  2047. }
  2048.  
  2049. static void
  2050. numericize(register int node)
  2051. {
  2052.     register int len;
  2053.     register int type;
  2054.     STR *tmpstr;
  2055.     STR *tmp2str;
  2056.     int numarg;
  2057.  
  2058.     type = ops[node].ival;
  2059.     len = type >> 8;
  2060.     type &= 255;
  2061.     if (type == OVAR && len == 1) {
  2062.     tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
  2063.     tmp2str = str_make("1");
  2064.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  2065.     }
  2066. }
  2067.