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