perl 2.0 patch 1: removed redundant debugging code in regexp.c
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
1 /* $Header: walk.c,v 2.0 88/06/05 00:16:12 root Exp $
2  *
3  * $Log:        walk.c,v $
4  * Revision 2.0  88/06/05  00:16:12  root
5  * Baseline version 2.0.
6  * 
7  */
8
9 #include "handy.h"
10 #include "EXTERN.h"
11 #include "util.h"
12 #include "a2p.h"
13
14 bool exitval = FALSE;
15 bool realexit = FALSE;
16 bool saw_getline = FALSE;
17 int maxtmp = 0;
18 char *lparen;
19 char *rparen;
20
21 STR *
22 walk(useval,level,node,numericptr)
23 int useval;
24 int level;
25 register int node;
26 int *numericptr;
27 {
28     register int len;
29     register STR *str;
30     register int type;
31     register int i;
32     register STR *tmpstr;
33     STR *tmp2str;
34     char *t;
35     char *d, *s;
36     int numarg;
37     int numeric = FALSE;
38     STR *fstr;
39     char *index();
40
41     if (!node) {
42         *numericptr = 0;
43         return str_make("");
44     }
45     type = ops[node].ival;
46     len = type >> 8;
47     type &= 255;
48     switch (type) {
49     case OPROG:
50         str = walk(0,level,ops[node+1].ival,&numarg);
51         opens = str_new(0);
52         if (do_split && need_entire && !absmaxfld)
53             split_to_array = TRUE;
54         if (do_split && split_to_array)
55             set_array_base = TRUE;
56         if (set_array_base) {
57             str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
58         }
59         if (fswitch && !const_FS)
60             const_FS = fswitch;
61         if (saw_FS > 1 || saw_RS)
62             const_FS = 0;
63         if (saw_ORS && need_entire)
64             do_chop = TRUE;
65         if (fswitch) {
66             str_cat(str,"$FS = '");
67             if (index("*+?.[]()|^$\\",fswitch))
68                 str_cat(str,"\\");
69             sprintf(tokenbuf,"%c",fswitch);
70             str_cat(str,tokenbuf);
71             str_cat(str,"';\t\t# field separator from -F switch\n");
72         }
73         else if (saw_FS && !const_FS) {
74             str_cat(str,"$FS = ' ';\t\t# set field separator\n");
75         }
76         if (saw_OFS) {
77             str_cat(str,"$, = ' ';\t\t# set output field separator\n");
78         }
79         if (saw_ORS) {
80             str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
81         }
82         if (str->str_cur > 20)
83             str_cat(str,"\n");
84         if (ops[node+2].ival) {
85             str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
86             str_free(fstr);
87             str_cat(str,"\n\n");
88         }
89         if (saw_line_op)
90             str_cat(str,"line: ");
91         str_cat(str,"while (<>) {\n");
92         tab(str,++level);
93         if (saw_FS && !const_FS)
94             do_chop = TRUE;
95         if (do_chop) {
96             str_cat(str,"chop;\t# strip record separator\n");
97             tab(str,level);
98         }
99         arymax = 0;
100         if (namelist) {
101             while (isalpha(*namelist)) {
102                 for (d = tokenbuf,s=namelist;
103                   isalpha(*s) || isdigit(*s) || *s == '_';
104                   *d++ = *s++) ;
105                 *d = '\0';
106                 while (*s && !isalpha(*s)) s++;
107                 namelist = s;
108                 nameary[++arymax] = savestr(tokenbuf);
109             }
110         }
111         if (maxfld < arymax)
112             maxfld = arymax;
113         if (do_split)
114             emit_split(str,level);
115         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
116         str_free(fstr);
117         fixtab(str,--level);
118         str_cat(str,"}\n");
119         if (ops[node+4].ival) {
120             realexit = TRUE;
121             str_cat(str,"\n");
122             tab(str,level);
123             str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
124             str_free(fstr);
125             str_cat(str,"\n");
126         }
127         if (exitval)
128             str_cat(str,"exit ExitValue;\n");
129         if (saw_getline) {
130             str_cat(str,"\nsub Getline {\n    $_ = <>;\n");
131             tab(str,++level);
132             if (do_chop) {
133                 str_cat(str,"chop;\t# strip record separator\n");
134                 tab(str,level);
135             }
136             if (do_split)
137                 emit_split(str,level);
138             fixtab(str,--level);
139             str_cat(str,"}\n");
140         }
141         if (do_fancy_opens) {
142             str_cat(str,"\n\
143 sub Pick {\n\
144     ($name) = @_;\n\
145     $fh = $opened{$name};\n\
146     if (!$fh) {\n\
147         $nextfh == 0 && open(fh_0,$name);\n\
148         $nextfh == 1 && open(fh_1,$name);\n\
149         $nextfh == 2 && open(fh_2,$name);\n\
150         $nextfh == 3 && open(fh_3,$name);\n\
151         $nextfh == 4 && open(fh_4,$name);\n\
152         $nextfh == 5 && open(fh_5,$name);\n\
153         $nextfh == 6 && open(fh_6,$name);\n\
154         $nextfh == 7 && open(fh_7,$name);\n\
155         $nextfh == 8 && open(fh_8,$name);\n\
156         $nextfh == 9 && open(fh_9,$name);\n\
157         $fh = $opened{$name} = 'fh_' . $nextfh++;\n\
158     }\n\
159     select($fh);\n\
160 }\n\
161 ");
162         }
163         break;
164     case OHUNKS:
165         str = walk(0,level,ops[node+1].ival,&numarg);
166         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
167         str_free(fstr);
168         if (len == 3) {
169             str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
170             str_free(fstr);
171         }
172         else {
173         }
174         break;
175     case ORANGE:
176         str = walk(1,level,ops[node+1].ival,&numarg);
177         str_cat(str," .. ");
178         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
179         str_free(fstr);
180         break;
181     case OPAT:
182         goto def;
183     case OREGEX:
184         str = str_new(0);
185         str_set(str,"/");
186         tmpstr=walk(0,level,ops[node+1].ival,&numarg);
187         /* translate \nnn to [\nnn] */
188         for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
189             if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])) {
190                 *d++ = '[';
191                 *d++ = *s++;
192                 *d++ = *s++;
193                 *d++ = *s++;
194                 *d++ = *s;
195                 *d = ']';
196             }
197             else
198                 *d = *s;
199         }
200         *d = '\0';
201         for (d=tokenbuf; *d; d++)
202             *d += 128;
203         str_cat(str,tokenbuf);
204         str_free(tmpstr);
205         str_cat(str,"/");
206         break;
207     case OHUNK:
208         if (len == 1) {
209             str = str_new(0);
210             str = walk(0,level,oper1(OPRINT,0),&numarg);
211             str_cat(str," if ");
212             str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
213             str_free(fstr);
214             str_cat(str,";");
215         }
216         else {
217             tmpstr = walk(0,level,ops[node+1].ival,&numarg);
218             if (*tmpstr->str_ptr) {
219                 str = str_new(0);
220                 str_set(str,"if (");
221                 str_scat(str,tmpstr);
222                 str_cat(str,") {\n");
223                 tab(str,++level);
224                 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
225                 str_free(fstr);
226                 fixtab(str,--level);
227                 str_cat(str,"}\n");
228                 tab(str,level);
229             }
230             else {
231                 str = walk(0,level,ops[node+2].ival,&numarg);
232             }
233         }
234         break;
235     case OPPAREN:
236         str = str_new(0);
237         str_set(str,"(");
238         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
239         str_free(fstr);
240         str_cat(str,")");
241         break;
242     case OPANDAND:
243         str = walk(1,level,ops[node+1].ival,&numarg);
244         str_cat(str," && ");
245         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
246         str_free(fstr);
247         break;
248     case OPOROR:
249         str = walk(1,level,ops[node+1].ival,&numarg);
250         str_cat(str," || ");
251         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
252         str_free(fstr);
253         break;
254     case OPNOT:
255         str = str_new(0);
256         str_set(str,"!");
257         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
258         str_free(fstr);
259         break;
260     case OCPAREN:
261         str = str_new(0);
262         str_set(str,"(");
263         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
264         str_free(fstr);
265         numeric |= numarg;
266         str_cat(str,")");
267         break;
268     case OCANDAND:
269         str = walk(1,level,ops[node+1].ival,&numarg);
270         numeric = 1;
271         str_cat(str," && ");
272         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
273         str_free(fstr);
274         break;
275     case OCOROR:
276         str = walk(1,level,ops[node+1].ival,&numarg);
277         numeric = 1;
278         str_cat(str," || ");
279         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
280         str_free(fstr);
281         break;
282     case OCNOT:
283         str = str_new(0);
284         str_set(str,"!");
285         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
286         str_free(fstr);
287         numeric = 1;
288         break;
289     case ORELOP:
290         str = walk(1,level,ops[node+2].ival,&numarg);
291         numeric |= numarg;
292         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
293         tmp2str = walk(1,level,ops[node+3].ival,&numarg);
294         numeric |= numarg;
295         if (!numeric) {
296             t = tmpstr->str_ptr;
297             if (strEQ(t,"=="))
298                 str_set(tmpstr,"eq");
299             else if (strEQ(t,"!="))
300                 str_set(tmpstr,"ne");
301             else if (strEQ(t,"<"))
302                 str_set(tmpstr,"lt");
303             else if (strEQ(t,"<="))
304                 str_set(tmpstr,"le");
305             else if (strEQ(t,">"))
306                 str_set(tmpstr,"gt");
307             else if (strEQ(t,">="))
308                 str_set(tmpstr,"ge");
309             if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
310               !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
311                 numeric |= 2;
312         }
313         if (numeric & 2) {
314             if (numeric & 1)            /* numeric is very good guess */
315                 str_cat(str," ");
316             else
317                 str_cat(str,"\377");
318             numeric = 1;
319         }
320         else
321             str_cat(str," ");
322         str_scat(str,tmpstr);
323         str_free(tmpstr);
324         str_cat(str," ");
325         str_scat(str,tmp2str);
326         str_free(tmp2str);
327         numeric = 1;
328         break;
329     case ORPAREN:
330         str = str_new(0);
331         str_set(str,"(");
332         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
333         str_free(fstr);
334         numeric |= numarg;
335         str_cat(str,")");
336         break;
337     case OMATCHOP:
338         str = walk(1,level,ops[node+2].ival,&numarg);
339         str_cat(str," ");
340         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
341         if (strEQ(tmpstr->str_ptr,"~"))
342             str_cat(str,"=~");
343         else {
344             str_scat(str,tmpstr);
345             str_free(tmpstr);
346         }
347         str_cat(str," ");
348         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
349         str_free(fstr);
350         numeric = 1;
351         break;
352     case OMPAREN:
353         str = str_new(0);
354         str_set(str,"(");
355         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
356         str_free(fstr);
357         numeric |= numarg;
358         str_cat(str,")");
359         break;
360     case OCONCAT:
361         str = walk(1,level,ops[node+1].ival,&numarg);
362         str_cat(str," . ");
363         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
364         str_free(fstr);
365         break;
366     case OASSIGN:
367         str = walk(0,level,ops[node+2].ival,&numarg);
368         str_cat(str," ");
369         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
370         str_scat(str,tmpstr);
371         if (str_len(tmpstr) > 1)
372             numeric = 1;
373         str_free(tmpstr);
374         str_cat(str," ");
375         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
376         str_free(fstr);
377         numeric |= numarg;
378         break;
379     case OADD:
380         str = walk(1,level,ops[node+1].ival,&numarg);
381         str_cat(str," + ");
382         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
383         str_free(fstr);
384         numeric = 1;
385         break;
386     case OSUB:
387         str = walk(1,level,ops[node+1].ival,&numarg);
388         str_cat(str," - ");
389         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
390         str_free(fstr);
391         numeric = 1;
392         break;
393     case OMULT:
394         str = walk(1,level,ops[node+1].ival,&numarg);
395         str_cat(str," * ");
396         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
397         str_free(fstr);
398         numeric = 1;
399         break;
400     case ODIV:
401         str = walk(1,level,ops[node+1].ival,&numarg);
402         str_cat(str," / ");
403         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
404         str_free(fstr);
405         numeric = 1;
406         break;
407     case OMOD:
408         str = walk(1,level,ops[node+1].ival,&numarg);
409         str_cat(str," % ");
410         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
411         str_free(fstr);
412         numeric = 1;
413         break;
414     case OPOSTINCR:
415         str = walk(1,level,ops[node+1].ival,&numarg);
416         str_cat(str,"++");
417         numeric = 1;
418         break;
419     case OPOSTDECR:
420         str = walk(1,level,ops[node+1].ival,&numarg);
421         str_cat(str,"--");
422         numeric = 1;
423         break;
424     case OPREINCR:
425         str = str_new(0);
426         str_set(str,"++");
427         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
428         str_free(fstr);
429         numeric = 1;
430         break;
431     case OPREDECR:
432         str = str_new(0);
433         str_set(str,"--");
434         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
435         str_free(fstr);
436         numeric = 1;
437         break;
438     case OUMINUS:
439         str = str_new(0);
440         str_set(str,"-");
441         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
442         str_free(fstr);
443         numeric = 1;
444         break;
445     case OUPLUS:
446         numeric = 1;
447         goto def;
448     case OPAREN:
449         str = str_new(0);
450         str_set(str,"(");
451         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
452         str_free(fstr);
453         str_cat(str,")");
454         numeric |= numarg;
455         break;
456     case OGETLINE:
457         str = str_new(0);
458         str_set(str,"do Getline()");
459         saw_getline = TRUE;
460         break;
461     case OSPRINTF:
462         str = str_new(0);
463         str_set(str,"sprintf(");
464         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
465         str_free(fstr);
466         str_cat(str,")");
467         break;
468     case OSUBSTR:
469         str = str_new(0);
470         str_set(str,"substr(");
471         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
472         str_free(fstr);
473         str_cat(str,", ");
474         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
475         str_free(fstr);
476         str_cat(str,", ");
477         if (len == 3) {
478             str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
479             str_free(fstr);
480         }
481         else
482             str_cat(str,"999999");
483         str_cat(str,")");
484         break;
485     case OSTRING:
486         str = str_new(0);
487         str_set(str,ops[node+1].cval);
488         break;
489     case OSPLIT:
490         str = str_new(0);
491         numeric = 1;
492         tmpstr = walk(1,level,ops[node+2].ival,&numarg);
493         if (useval)
494             str_set(str,"(@");
495         else
496             str_set(str,"@");
497         str_scat(str,tmpstr);
498         str_cat(str," = split(");
499         if (len == 3) {
500             fstr = walk(1,level,ops[node+3].ival,&numarg);
501             if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
502                 i = fstr->str_ptr[1] & 127;
503                 if (index("*+?.[]()|^$\\",i))
504                     sprintf(tokenbuf,"/\\%c/",i);
505                 else
506                     sprintf(tokenbuf,"/%c/",i);
507                 str_cat(str,tokenbuf);
508             }
509             else
510                 str_scat(str,fstr);
511             str_free(fstr);
512         }
513         else if (const_FS) {
514             sprintf(tokenbuf,"/[%c\\n]/",const_FS);
515             str_cat(str,tokenbuf);
516         }
517         else if (saw_FS)
518             str_cat(str,"$FS");
519         else
520             str_cat(str,"' '");
521         str_cat(str,", ");
522         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
523         str_free(fstr);
524         str_cat(str,")");
525         if (useval) {
526             str_cat(str,")");
527         }
528         str_free(tmpstr);
529         break;
530     case OINDEX:
531         str = str_new(0);
532         str_set(str,"index(");
533         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
534         str_free(fstr);
535         str_cat(str,", ");
536         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
537         str_free(fstr);
538         str_cat(str,")");
539         numeric = 1;
540         break;
541     case ONUM:
542         str = walk(1,level,ops[node+1].ival,&numarg);
543         numeric = 1;
544         break;
545     case OSTR:
546         tmpstr = walk(1,level,ops[node+1].ival,&numarg);
547         s = "'";
548         for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
549             if (*t == '\'')
550                 s = "\"";
551             else if (*t == '\\') {
552                 s = "\"";
553                 *d++ = *t++ + 128;
554                 switch (*t) {
555                 case '\\': case '"': case 'n': case 't':
556                     break;
557                 default:        /* hide this from perl */
558                     *d++ = '\\' + 128;
559                 }
560             }
561             *d = *t + 128;
562         }
563         *d = '\0';
564         str = str_new(0);
565         str_set(str,s);
566         str_cat(str,tokenbuf);
567         str_free(tmpstr);
568         str_cat(str,s);
569         break;
570     case OVAR:
571         str = str_new(0);
572         str_set(str,"$");
573         str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
574         if (len == 1) {
575             tmp2str = hfetch(symtab,tmpstr->str_ptr);
576             if (tmp2str && atoi(tmp2str->str_ptr))
577                 numeric = 2;
578             if (strEQ(str->str_ptr,"$NR")) {
579                 numeric = 1;
580                 str_set(str,"$.");
581             }
582             else if (strEQ(str->str_ptr,"$NF")) {
583                 numeric = 1;
584                 str_set(str,"$#Fld");
585             }
586             else if (strEQ(str->str_ptr,"$0"))
587                 str_set(str,"$_");
588         }
589         else {
590             str_cat(tmpstr,"[]");
591             tmp2str = hfetch(symtab,tmpstr->str_ptr);
592             if (tmp2str && atoi(tmp2str->str_ptr))
593                 str_cat(str,"[");
594             else
595                 str_cat(str,"{");
596             str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
597             str_free(fstr);
598             if (tmp2str && atoi(tmp2str->str_ptr))
599                 strcpy(tokenbuf,"]");
600             else
601                 strcpy(tokenbuf,"}");
602             *tokenbuf += 128;
603             str_cat(str,tokenbuf);
604         }
605         str_free(tmpstr);
606         break;
607     case OFLD:
608         str = str_new(0);
609         if (split_to_array) {
610             str_set(str,"$Fld");
611             str_cat(str,"[");
612             str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
613             str_free(fstr);
614             str_cat(str,"]");
615         }
616         else {
617             i = atoi(walk(1,level,ops[node+1].ival,&numarg)->str_ptr);
618             if (i <= arymax)
619                 sprintf(tokenbuf,"$%s",nameary[i]);
620             else
621                 sprintf(tokenbuf,"$Fld%d",i);
622             str_set(str,tokenbuf);
623         }
624         break;
625     case OVFLD:
626         str = str_new(0);
627         str_set(str,"$Fld[");
628         i = ops[node+1].ival;
629         if ((ops[i].ival & 255) == OPAREN)
630             i = ops[i+1].ival;
631         tmpstr=walk(1,level,i,&numarg);
632         str_scat(str,tmpstr);
633         str_free(tmpstr);
634         str_cat(str,"]");
635         break;
636     case OJUNK:
637         goto def;
638     case OSNEWLINE:
639         str = str_new(2);
640         str_set(str,";\n");
641         tab(str,level);
642         break;
643     case ONEWLINE:
644         str = str_new(1);
645         str_set(str,"\n");
646         tab(str,level);
647         break;
648     case OSCOMMENT:
649         str = str_new(0);
650         str_set(str,";");
651         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
652         for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
653             *s += 128;
654         str_scat(str,tmpstr);
655         str_free(tmpstr);
656         tab(str,level);
657         break;
658     case OCOMMENT:
659         str = str_new(0);
660         tmpstr = walk(0,level,ops[node+1].ival,&numarg);
661         for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
662             *s += 128;
663         str_scat(str,tmpstr);
664         str_free(tmpstr);
665         tab(str,level);
666         break;
667     case OCOMMA:
668         str = walk(1,level,ops[node+1].ival,&numarg);
669         str_cat(str,", ");
670         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
671         str_free(fstr);
672         break;
673     case OSEMICOLON:
674         str = str_new(1);
675         str_set(str,"; ");
676         break;
677     case OSTATES:
678         str = walk(0,level,ops[node+1].ival,&numarg);
679         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
680         str_free(fstr);
681         break;
682     case OSTATE:
683         str = str_new(0);
684         if (len >= 1) {
685             str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
686             str_free(fstr);
687             if (len >= 2) {
688                 tmpstr = walk(0,level,ops[node+2].ival,&numarg);
689                 if (*tmpstr->str_ptr == ';') {
690                     addsemi(str);
691                     str_cat(str,tmpstr->str_ptr+1);
692                 }
693                 str_free(tmpstr);
694             }
695         }
696         break;
697     case OPRINTF:
698     case OPRINT:
699         lparen = "";    /* set to parens if necessary */
700         rparen = "";
701         str = str_new(0);
702         if (len == 3) {         /* output redirection */
703             tmpstr = walk(1,level,ops[node+3].ival,&numarg);
704             tmp2str = walk(1,level,ops[node+2].ival,&numarg);
705             if (!do_fancy_opens) {
706                 t = tmpstr->str_ptr;
707                 if (*t == '"' || *t == '\'')
708                     t = cpytill(tokenbuf,t+1,*t);
709                 else
710                     fatal("Internal error: OPRINT");
711                 d = savestr(t);
712                 s = savestr(tokenbuf);
713                 for (t = tokenbuf; *t; t++) {
714                     *t &= 127;
715                     if (!isalpha(*t) && !isdigit(*t))
716                         *t = '_';
717                 }
718                 if (!index(tokenbuf,'_'))
719                     strcpy(t,"_fh");
720                 str_cat(opens,"open(");
721                 str_cat(opens,tokenbuf);
722                 str_cat(opens,", ");
723                 d[1] = '\0';
724                 str_cat(opens,d);
725                 str_scat(opens,tmp2str);
726                 str_cat(opens,tmpstr->str_ptr+1);
727                 if (*tmp2str->str_ptr == '|')
728                     str_cat(opens,") || die 'Cannot pipe to \"");
729                 else
730                     str_cat(opens,") || die 'Cannot create file \"");
731                 if (*d == '"')
732                     str_cat(opens,"'.\"");
733                 str_cat(opens,s);
734                 if (*d == '"')
735                     str_cat(opens,"\".'");
736                 str_cat(opens,"\".';\n");
737                 str_free(tmpstr);
738                 str_free(tmp2str);
739                 safefree(s);
740                 safefree(d);
741             }
742             else {
743                 sprintf(tokenbuf,"do Pick('%s' . (%s)) &&\n",
744                    tmp2str->str_ptr, tmpstr->str_ptr);
745                 str_cat(str,tokenbuf);
746                 tab(str,level+1);
747                 *tokenbuf = '\0';
748                 str_free(tmpstr);
749                 str_free(tmp2str);
750                 lparen = "(";
751                 rparen = ")";
752             }
753         }
754         else
755             strcpy(tokenbuf,"stdout");
756         str_cat(str,lparen);    /* may be null */
757         if (type == OPRINTF)
758             str_cat(str,"printf");
759         else
760             str_cat(str,"print");
761         if (len == 3 || do_fancy_opens) {
762             if (*tokenbuf)
763                 str_cat(str," ");
764             str_cat(str,tokenbuf);
765         }
766         tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg);
767         if (!*tmpstr->str_ptr && lval_field) {
768             t = saw_OFS ? "$," : "' '";
769             if (split_to_array) {
770                 sprintf(tokenbuf,"join(%s,@Fld)",t);
771                 str_cat(tmpstr,tokenbuf);
772             }
773             else {
774                 for (i = 1; i < maxfld; i++) {
775                     if (i <= arymax)
776                         sprintf(tokenbuf,"$%s, ",nameary[i]);
777                     else
778                         sprintf(tokenbuf,"$Fld%d, ",i);
779                     str_cat(tmpstr,tokenbuf);
780                 }
781                 if (maxfld <= arymax)
782                     sprintf(tokenbuf,"$%s",nameary[maxfld]);
783                 else
784                     sprintf(tokenbuf,"$Fld%d",maxfld);
785                 str_cat(tmpstr,tokenbuf);
786             }
787         }
788         if (*tmpstr->str_ptr) {
789             str_cat(str," ");
790             str_scat(str,tmpstr);
791         }
792         else {
793             str_cat(str," $_");
794         }
795         str_cat(str,rparen);    /* may be null */
796         str_free(tmpstr);
797         break;
798     case OLENGTH:
799         str = str_make("length(");
800         goto maybe0;
801     case OLOG:
802         str = str_make("log(");
803         goto maybe0;
804     case OEXP:
805         str = str_make("exp(");
806         goto maybe0;
807     case OSQRT:
808         str = str_make("sqrt(");
809         goto maybe0;
810     case OINT:
811         str = str_make("int(");
812       maybe0:
813         numeric = 1;
814         if (len > 0)
815             tmpstr = walk(1,level,ops[node+1].ival,&numarg);
816         else
817             tmpstr = str_new(0);;
818         if (!*tmpstr->str_ptr) {
819             if (lval_field) {
820                 t = saw_OFS ? "$," : "' '";
821                 if (split_to_array) {
822                     sprintf(tokenbuf,"join(%s,@Fld)",t);
823                     str_cat(tmpstr,tokenbuf);
824                 }
825                 else {
826                     sprintf(tokenbuf,"join(%s, ",t);
827                     str_cat(tmpstr,tokenbuf);
828                     for (i = 1; i < maxfld; i++) {
829                         if (i <= arymax)
830                             sprintf(tokenbuf,"$%s,",nameary[i]);
831                         else
832                             sprintf(tokenbuf,"$Fld%d,",i);
833                         str_cat(tmpstr,tokenbuf);
834                     }
835                     if (maxfld <= arymax)
836                         sprintf(tokenbuf,"$%s)",nameary[maxfld]);
837                     else
838                         sprintf(tokenbuf,"$Fld%d)",maxfld);
839                     str_cat(tmpstr,tokenbuf);
840                 }
841             }
842             else
843                 str_cat(tmpstr,"$_");
844         }
845         if (strEQ(tmpstr->str_ptr,"$_")) {
846             if (type == OLENGTH && !do_chop) {
847                 str = str_make("(length(");
848                 str_cat(tmpstr,") - 1");
849             }
850         }
851         str_scat(str,tmpstr);
852         str_free(tmpstr);
853         str_cat(str,")");
854         break;
855     case OBREAK:
856         str = str_new(0);
857         str_set(str,"last");
858         break;
859     case ONEXT:
860         str = str_new(0);
861         str_set(str,"next line");
862         break;
863     case OEXIT:
864         str = str_new(0);
865         if (realexit) {
866             str_set(str,"exit");
867             if (len == 1) {
868                 str_cat(str," ");
869                 exitval = TRUE;
870                 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
871                 str_free(fstr);
872             }
873         }
874         else {
875             if (len == 1) {
876                 str_set(str,"ExitValue = ");
877                 exitval = TRUE;
878                 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
879                 str_free(fstr);
880                 str_cat(str,"; ");
881             }
882             str_cat(str,"last line");
883         }
884         break;
885     case OCONTINUE:
886         str = str_new(0);
887         str_set(str,"next");
888         break;
889     case OREDIR:
890         goto def;
891     case OIF:
892         str = str_new(0);
893         str_set(str,"if (");
894         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
895         str_free(fstr);
896         str_cat(str,") ");
897         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
898         str_free(fstr);
899         if (len == 3) {
900             i = ops[node+3].ival;
901             if (i) {
902                 if ((ops[i].ival & 255) == OBLOCK) {
903                     i = ops[i+1].ival;
904                     if (i) {
905                         if ((ops[i].ival & 255) != OIF)
906                             i = 0;
907                     }
908                 }
909                 else
910                     i = 0;
911             }
912             if (i) {
913                 str_cat(str,"els");
914                 str_scat(str,fstr=walk(0,level,i,&numarg));
915                 str_free(fstr);
916             }
917             else {
918                 str_cat(str,"else ");
919                 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
920                 str_free(fstr);
921             }
922         }
923         break;
924     case OWHILE:
925         str = str_new(0);
926         str_set(str,"while (");
927         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
928         str_free(fstr);
929         str_cat(str,") ");
930         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
931         str_free(fstr);
932         break;
933     case OFOR:
934         str = str_new(0);
935         str_set(str,"for (");
936         str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
937         i = numarg;
938         if (i) {
939             t = s = tmpstr->str_ptr;
940             while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
941                 t++;
942             i = t - s;
943             if (i < 2)
944                 i = 0;
945         }
946         str_cat(str,"; ");
947         fstr=walk(1,level,ops[node+2].ival,&numarg);
948         if (i && (t = index(fstr->str_ptr,0377))) {
949             if (strnEQ(fstr->str_ptr,s,i))
950                 *t = ' ';
951         }
952         str_scat(str,fstr);
953         str_free(fstr);
954         str_free(tmpstr);
955         str_cat(str,"; ");
956         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
957         str_free(fstr);
958         str_cat(str,") ");
959         str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
960         str_free(fstr);
961         break;
962     case OFORIN:
963         tmpstr=walk(0,level,ops[node+2].ival,&numarg);
964         str = str_new(0);
965         str_sset(str,tmpstr);
966         str_cat(str,"[]");
967         tmp2str = hfetch(symtab,str->str_ptr);
968         if (tmp2str && atoi(tmp2str->str_ptr)) {
969             fstr=walk(1,level,ops[node+1].ival,&numarg);
970             sprintf(tokenbuf,
971               "foreach $%s (@%s) ",
972               fstr->str_ptr,
973               tmpstr->str_ptr);
974             str_set(str,tokenbuf);
975             str_free(fstr);
976             str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
977             str_free(fstr);
978         }
979         else {
980             str_set(str,"while (($");
981             str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
982             str_free(fstr);
983             str_cat(str,",$junkval) = each(");
984             str_scat(str,tmpstr);
985             str_cat(str,")) ");
986             str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
987             str_free(fstr);
988         }
989         str_free(tmpstr);
990         break;
991     case OBLOCK:
992         str = str_new(0);
993         str_set(str,"{");
994         if (len >= 2 && ops[node+2].ival) {
995             str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
996             str_free(fstr);
997         }
998         fixtab(str,++level);
999         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
1000         str_free(fstr);
1001         addsemi(str);
1002         fixtab(str,--level);
1003         str_cat(str,"}\n");
1004         tab(str,level);
1005         if (len >= 3) {
1006             str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
1007             str_free(fstr);
1008         }
1009         break;
1010     default:
1011       def:
1012         if (len) {
1013             if (len > 5)
1014                 fatal("Garbage length in walk");
1015             str = walk(0,level,ops[node+1].ival,&numarg);
1016             for (i = 2; i<= len; i++) {
1017                 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg));
1018                 str_free(fstr);
1019             }
1020         }
1021         else {
1022             str = Nullstr;
1023         }
1024         break;
1025     }
1026     if (!str)
1027         str = str_new(0);
1028     *numericptr = numeric;
1029 #ifdef DEBUGGING
1030     if (debug & 4) {
1031         printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1032         for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1033             if (*t == '\n')
1034                 printf("\\n");
1035             else if (*t == '\t')
1036                 printf("\\t");
1037             else
1038                 putchar(*t);
1039         putchar('\n');
1040     }
1041 #endif
1042     return str;
1043 }
1044
1045 tab(str,lvl)
1046 register STR *str;
1047 register int lvl;
1048 {
1049     while (lvl > 1) {
1050         str_cat(str,"\t");
1051         lvl -= 2;
1052     }
1053     if (lvl)
1054         str_cat(str,"    ");
1055 }
1056
1057 fixtab(str,lvl)
1058 register STR *str;
1059 register int lvl;
1060 {
1061     register char *s;
1062
1063     /* strip trailing white space */
1064
1065     s = str->str_ptr+str->str_cur - 1;
1066     while (s >= str->str_ptr && (*s == ' ' || *s == '\t'))
1067         s--;
1068     s[1] = '\0';
1069     str->str_cur = s + 1 - str->str_ptr;
1070     if (s >= str->str_ptr && *s != '\n')
1071         str_cat(str,"\n");
1072
1073     tab(str,lvl);
1074 }
1075
1076 addsemi(str)
1077 register STR *str;
1078 {
1079     register char *s;
1080
1081     s = str->str_ptr+str->str_cur - 1;
1082     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1083         s--;
1084     if (s >= str->str_ptr && *s != ';' && *s != '}')
1085         str_cat(str,";");
1086 }
1087
1088 emit_split(str,level)
1089 register STR *str;
1090 int level;
1091 {
1092     register int i;
1093
1094     if (split_to_array)
1095         str_cat(str,"@Fld");
1096     else {
1097         str_cat(str,"(");
1098         for (i = 1; i < maxfld; i++) {
1099             if (i <= arymax)
1100                 sprintf(tokenbuf,"$%s,",nameary[i]);
1101             else
1102                 sprintf(tokenbuf,"$Fld%d,",i);
1103             str_cat(str,tokenbuf);
1104         }
1105         if (maxfld <= arymax)
1106             sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1107         else
1108             sprintf(tokenbuf,"$Fld%d)",maxfld);
1109         str_cat(str,tokenbuf);
1110     }
1111     if (const_FS) {
1112         sprintf(tokenbuf," = split(/[%c\\n]/);\n",const_FS);
1113         str_cat(str,tokenbuf);
1114     }
1115     else if (saw_FS)
1116         str_cat(str," = split($FS);\n");
1117     else
1118         str_cat(str," = split(' ');\n");
1119     tab(str,level);
1120 }
1121
1122 prewalk(numit,level,node,numericptr)
1123 int numit;
1124 int level;
1125 register int node;
1126 int *numericptr;
1127 {
1128     register int len;
1129     register int type;
1130     register int i;
1131     char *t;
1132     char *d, *s;
1133     int numarg;
1134     int numeric = FALSE;
1135
1136     if (!node) {
1137         *numericptr = 0;
1138         return 0;
1139     }
1140     type = ops[node].ival;
1141     len = type >> 8;
1142     type &= 255;
1143     switch (type) {
1144     case OPROG:
1145         prewalk(0,level,ops[node+1].ival,&numarg);
1146         if (ops[node+2].ival) {
1147             prewalk(0,level,ops[node+2].ival,&numarg);
1148         }
1149         ++level;
1150         prewalk(0,level,ops[node+3].ival,&numarg);
1151         --level;
1152         if (ops[node+3].ival) {
1153             prewalk(0,level,ops[node+4].ival,&numarg);
1154         }
1155         break;
1156     case OHUNKS:
1157         prewalk(0,level,ops[node+1].ival,&numarg);
1158         prewalk(0,level,ops[node+2].ival,&numarg);
1159         if (len == 3) {
1160             prewalk(0,level,ops[node+3].ival,&numarg);
1161         }
1162         break;
1163     case ORANGE:
1164         prewalk(1,level,ops[node+1].ival,&numarg);
1165         prewalk(1,level,ops[node+2].ival,&numarg);
1166         break;
1167     case OPAT:
1168         goto def;
1169     case OREGEX:
1170         prewalk(0,level,ops[node+1].ival,&numarg);
1171         break;
1172     case OHUNK:
1173         if (len == 1) {
1174             prewalk(0,level,ops[node+1].ival,&numarg);
1175         }
1176         else {
1177             i = prewalk(0,level,ops[node+1].ival,&numarg);
1178             if (i) {
1179                 ++level;
1180                 prewalk(0,level,ops[node+2].ival,&numarg);
1181                 --level;
1182             }
1183             else {
1184                 prewalk(0,level,ops[node+2].ival,&numarg);
1185             }
1186         }
1187         break;
1188     case OPPAREN:
1189         prewalk(0,level,ops[node+1].ival,&numarg);
1190         break;
1191     case OPANDAND:
1192         prewalk(0,level,ops[node+1].ival,&numarg);
1193         prewalk(0,level,ops[node+2].ival,&numarg);
1194         break;
1195     case OPOROR:
1196         prewalk(0,level,ops[node+1].ival,&numarg);
1197         prewalk(0,level,ops[node+2].ival,&numarg);
1198         break;
1199     case OPNOT:
1200         prewalk(0,level,ops[node+1].ival,&numarg);
1201         break;
1202     case OCPAREN:
1203         prewalk(0,level,ops[node+1].ival,&numarg);
1204         numeric |= numarg;
1205         break;
1206     case OCANDAND:
1207         prewalk(0,level,ops[node+1].ival,&numarg);
1208         numeric = 1;
1209         prewalk(0,level,ops[node+2].ival,&numarg);
1210         break;
1211     case OCOROR:
1212         prewalk(0,level,ops[node+1].ival,&numarg);
1213         numeric = 1;
1214         prewalk(0,level,ops[node+2].ival,&numarg);
1215         break;
1216     case OCNOT:
1217         prewalk(0,level,ops[node+1].ival,&numarg);
1218         numeric = 1;
1219         break;
1220     case ORELOP:
1221         prewalk(0,level,ops[node+2].ival,&numarg);
1222         numeric |= numarg;
1223         prewalk(0,level,ops[node+1].ival,&numarg);
1224         prewalk(0,level,ops[node+3].ival,&numarg);
1225         numeric |= numarg;
1226         numeric = 1;
1227         break;
1228     case ORPAREN:
1229         prewalk(0,level,ops[node+1].ival,&numarg);
1230         numeric |= numarg;
1231         break;
1232     case OMATCHOP:
1233         prewalk(0,level,ops[node+2].ival,&numarg);
1234         prewalk(0,level,ops[node+1].ival,&numarg);
1235         prewalk(0,level,ops[node+3].ival,&numarg);
1236         numeric = 1;
1237         break;
1238     case OMPAREN:
1239         prewalk(0,level,ops[node+1].ival,&numarg);
1240         numeric |= numarg;
1241         break;
1242     case OCONCAT:
1243         prewalk(0,level,ops[node+1].ival,&numarg);
1244         prewalk(0,level,ops[node+2].ival,&numarg);
1245         break;
1246     case OASSIGN:
1247         prewalk(0,level,ops[node+2].ival,&numarg);
1248         prewalk(0,level,ops[node+1].ival,&numarg);
1249         prewalk(0,level,ops[node+3].ival,&numarg);
1250         if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1251             numericize(ops[node+2].ival);
1252             if (!numarg)
1253                 numericize(ops[node+3].ival);
1254         }
1255         numeric |= numarg;
1256         break;
1257     case OADD:
1258         prewalk(1,level,ops[node+1].ival,&numarg);
1259         prewalk(1,level,ops[node+2].ival,&numarg);
1260         numeric = 1;
1261         break;
1262     case OSUB:
1263         prewalk(1,level,ops[node+1].ival,&numarg);
1264         prewalk(1,level,ops[node+2].ival,&numarg);
1265         numeric = 1;
1266         break;
1267     case OMULT:
1268         prewalk(1,level,ops[node+1].ival,&numarg);
1269         prewalk(1,level,ops[node+2].ival,&numarg);
1270         numeric = 1;
1271         break;
1272     case ODIV:
1273         prewalk(1,level,ops[node+1].ival,&numarg);
1274         prewalk(1,level,ops[node+2].ival,&numarg);
1275         numeric = 1;
1276         break;
1277     case OMOD:
1278         prewalk(1,level,ops[node+1].ival,&numarg);
1279         prewalk(1,level,ops[node+2].ival,&numarg);
1280         numeric = 1;
1281         break;
1282     case OPOSTINCR:
1283         prewalk(1,level,ops[node+1].ival,&numarg);
1284         numeric = 1;
1285         break;
1286     case OPOSTDECR:
1287         prewalk(1,level,ops[node+1].ival,&numarg);
1288         numeric = 1;
1289         break;
1290     case OPREINCR:
1291         prewalk(1,level,ops[node+1].ival,&numarg);
1292         numeric = 1;
1293         break;
1294     case OPREDECR:
1295         prewalk(1,level,ops[node+1].ival,&numarg);
1296         numeric = 1;
1297         break;
1298     case OUMINUS:
1299         prewalk(1,level,ops[node+1].ival,&numarg);
1300         numeric = 1;
1301         break;
1302     case OUPLUS:
1303         prewalk(1,level,ops[node+1].ival,&numarg);
1304         numeric = 1;
1305         break;
1306     case OPAREN:
1307         prewalk(0,level,ops[node+1].ival,&numarg);
1308         numeric |= numarg;
1309         break;
1310     case OGETLINE:
1311         break;
1312     case OSPRINTF:
1313         prewalk(0,level,ops[node+1].ival,&numarg);
1314         break;
1315     case OSUBSTR:
1316         prewalk(0,level,ops[node+1].ival,&numarg);
1317         prewalk(1,level,ops[node+2].ival,&numarg);
1318         if (len == 3) {
1319             prewalk(1,level,ops[node+3].ival,&numarg);
1320         }
1321         break;
1322     case OSTRING:
1323         break;
1324     case OSPLIT:
1325         numeric = 1;
1326         prewalk(0,level,ops[node+2].ival,&numarg);
1327         if (len == 3)
1328             prewalk(0,level,ops[node+3].ival,&numarg);
1329         prewalk(0,level,ops[node+1].ival,&numarg);
1330         break;
1331     case OINDEX:
1332         prewalk(0,level,ops[node+1].ival,&numarg);
1333         prewalk(0,level,ops[node+2].ival,&numarg);
1334         numeric = 1;
1335         break;
1336     case ONUM:
1337         prewalk(0,level,ops[node+1].ival,&numarg);
1338         numeric = 1;
1339         break;
1340     case OSTR:
1341         prewalk(0,level,ops[node+1].ival,&numarg);
1342         break;
1343     case OVAR:
1344         prewalk(0,level,ops[node+1].ival,&numarg);
1345         if (len == 1) {
1346             if (numit)
1347                 numericize(node);
1348         }
1349         else {
1350             prewalk(0,level,ops[node+2].ival,&numarg);
1351         }
1352         break;
1353     case OFLD:
1354         prewalk(0,level,ops[node+1].ival,&numarg);
1355         break;
1356     case OVFLD:
1357         i = ops[node+1].ival;
1358         prewalk(0,level,i,&numarg);
1359         break;
1360     case OJUNK:
1361         goto def;
1362     case OSNEWLINE:
1363         break;
1364     case ONEWLINE:
1365         break;
1366     case OSCOMMENT:
1367         break;
1368     case OCOMMENT:
1369         break;
1370     case OCOMMA:
1371         prewalk(0,level,ops[node+1].ival,&numarg);
1372         prewalk(0,level,ops[node+2].ival,&numarg);
1373         break;
1374     case OSEMICOLON:
1375         break;
1376     case OSTATES:
1377         prewalk(0,level,ops[node+1].ival,&numarg);
1378         prewalk(0,level,ops[node+2].ival,&numarg);
1379         break;
1380     case OSTATE:
1381         if (len >= 1) {
1382             prewalk(0,level,ops[node+1].ival,&numarg);
1383             if (len >= 2) {
1384                 prewalk(0,level,ops[node+2].ival,&numarg);
1385             }
1386         }
1387         break;
1388     case OPRINTF:
1389     case OPRINT:
1390         if (len == 3) {         /* output redirection */
1391             prewalk(0,level,ops[node+3].ival,&numarg);
1392             prewalk(0,level,ops[node+2].ival,&numarg);
1393         }
1394         prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1395         break;
1396     case OLENGTH:
1397         goto maybe0;
1398     case OLOG:
1399         goto maybe0;
1400     case OEXP:
1401         goto maybe0;
1402     case OSQRT:
1403         goto maybe0;
1404     case OINT:
1405       maybe0:
1406         numeric = 1;
1407         if (len > 0)
1408             prewalk(type != OLENGTH,level,ops[node+1].ival,&numarg);
1409         break;
1410     case OBREAK:
1411         break;
1412     case ONEXT:
1413         break;
1414     case OEXIT:
1415         if (len == 1) {
1416             prewalk(1,level,ops[node+1].ival,&numarg);
1417         }
1418         break;
1419     case OCONTINUE:
1420         break;
1421     case OREDIR:
1422         goto def;
1423     case OIF:
1424         prewalk(0,level,ops[node+1].ival,&numarg);
1425         prewalk(0,level,ops[node+2].ival,&numarg);
1426         if (len == 3) {
1427             prewalk(0,level,ops[node+3].ival,&numarg);
1428         }
1429         break;
1430     case OWHILE:
1431         prewalk(0,level,ops[node+1].ival,&numarg);
1432         prewalk(0,level,ops[node+2].ival,&numarg);
1433         break;
1434     case OFOR:
1435         prewalk(0,level,ops[node+1].ival,&numarg);
1436         prewalk(0,level,ops[node+2].ival,&numarg);
1437         prewalk(0,level,ops[node+3].ival,&numarg);
1438         prewalk(0,level,ops[node+4].ival,&numarg);
1439         break;
1440     case OFORIN:
1441         prewalk(0,level,ops[node+2].ival,&numarg);
1442         prewalk(0,level,ops[node+1].ival,&numarg);
1443         prewalk(0,level,ops[node+3].ival,&numarg);
1444         break;
1445     case OBLOCK:
1446         if (len == 2) {
1447             prewalk(0,level,ops[node+2].ival,&numarg);
1448         }
1449         ++level;
1450         prewalk(0,level,ops[node+1].ival,&numarg);
1451         --level;
1452         break;
1453     default:
1454       def:
1455         if (len) {
1456             if (len > 5)
1457                 fatal("Garbage length in prewalk");
1458             prewalk(0,level,ops[node+1].ival,&numarg);
1459             for (i = 2; i<= len; i++) {
1460                 prewalk(0,level,ops[node+i].ival,&numarg);
1461             }
1462         }
1463         break;
1464     }
1465     *numericptr = numeric;
1466     return 1;
1467 }
1468
1469 numericize(node)
1470 register int node;
1471 {
1472     register int len;
1473     register int type;
1474     register int i;
1475     STR *tmpstr;
1476     STR *tmp2str;
1477     int numarg;
1478
1479     type = ops[node].ival;
1480     len = type >> 8;
1481     type &= 255;
1482     if (type == OVAR && len == 1) {
1483         tmpstr=walk(0,0,ops[node+1].ival,&numarg);
1484         tmp2str = str_make("1");
1485         hstore(symtab,tmpstr->str_ptr,tmp2str);
1486     }
1487 }