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