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