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