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