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