perl 4.0.00: (no release announcement available)
[p5sagit/p5-mst-13.2.git] / x2p / walk.c
1 /* $Header: walk.c,v 4.0 91/03/20 01:58:36 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 4.0  91/03/20  01:58:36  lwall
10  * 4.0 baseline.
11  * 
12  */
13
14 #include "handy.h"
15 #include "EXTERN.h"
16 #include "util.h"
17 #include "a2p.h"
18
19 bool exitval = FALSE;
20 bool realexit = FALSE;
21 bool saw_getline = FALSE;
22 bool subretnum = FALSE;
23 bool saw_FNR = FALSE;
24 bool saw_argv0 = FALSE;
25 int maxtmp = 0;
26 char *lparen;
27 char *rparen;
28 STR *subs;
29 STR *curargs = Nullstr;
30
31 STR *
32 walk(useval,level,node,numericptr,minprec)
33 int useval;
34 int level;
35 register int node;
36 int *numericptr;
37 int minprec;                    /* minimum precedence without parens */
38 {
39     register int len;
40     register STR *str;
41     register int type;
42     register int i;
43     register STR *tmpstr;
44     STR *tmp2str;
45     STR *tmp3str;
46     char *t;
47     char *d, *s;
48     int numarg;
49     int numeric = FALSE;
50     STR *fstr;
51     int prec = P_MAX;           /* assume no parens needed */
52     char *index();
53
54     if (!node) {
55         *numericptr = 0;
56         return str_make("");
57     }
58     type = ops[node].ival;
59     len = type >> 8;
60     type &= 255;
61     switch (type) {
62     case OPROG:
63         opens = str_new(0);
64         subs = str_new(0);
65         str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
66         if (do_split && need_entire && !absmaxfld)
67             split_to_array = TRUE;
68         if (do_split && split_to_array)
69             set_array_base = TRUE;
70         if (set_array_base) {
71             str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
72         }
73         if (fswitch && !const_FS)
74             const_FS = fswitch;
75         if (saw_FS > 1 || saw_RS)
76             const_FS = 0;
77         if (saw_ORS && need_entire)
78             do_chop = TRUE;
79         if (fswitch) {
80             str_cat(str,"$FS = '");
81             if (index("*+?.[]()|^$\\",fswitch))
82                 str_cat(str,"\\");
83             sprintf(tokenbuf,"%c",fswitch);
84             str_cat(str,tokenbuf);
85             str_cat(str,"';\t\t# field separator from -F switch\n");
86         }
87         else if (saw_FS && !const_FS) {
88             str_cat(str,"$FS = ' ';\t\t# set field separator\n");
89         }
90         if (saw_OFS) {
91             str_cat(str,"$, = ' ';\t\t# set output field separator\n");
92         }
93         if (saw_ORS) {
94             str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
95         }
96         if (saw_argv0) {
97             str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
98         }
99         if (str->str_cur > 20)
100             str_cat(str,"\n");
101         if (ops[node+2].ival) {
102             str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
103             str_free(fstr);
104             str_cat(str,"\n\n");
105         }
106         fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
107         if (*fstr->str_ptr) {
108             if (saw_line_op)
109                 str_cat(str,"line: ");
110             str_cat(str,"while (<>) {\n");
111             tab(str,++level);
112             if (saw_FS && !const_FS)
113                 do_chop = TRUE;
114             if (do_chop) {
115                 str_cat(str,"chop;\t# strip record separator\n");
116                 tab(str,level);
117             }
118             arymax = 0;
119             if (namelist) {
120                 while (isalpha(*namelist)) {
121                     for (d = tokenbuf,s=namelist;
122                       isalpha(*s) || isdigit(*s) || *s == '_';
123                       *d++ = *s++) ;
124                     *d = '\0';
125                     while (*s && !isalpha(*s)) s++;
126                     namelist = s;
127                     nameary[++arymax] = savestr(tokenbuf);
128                 }
129             }
130             if (maxfld < arymax)
131                 maxfld = arymax;
132             if (do_split)
133                 emit_split(str,level);
134             str_scat(str,fstr);
135             str_free(fstr);
136             fixtab(str,--level);
137             str_cat(str,"}\n");
138             if (saw_FNR)
139                 str_cat(str,"continue {\n    $FNRbase = $. if eof;\n}\n");
140         }
141         else
142             str_cat(str,"while (<>) { }         # (no line actions)\n");
143         if (ops[node+4].ival) {
144             realexit = TRUE;
145             str_cat(str,"\n");
146             tab(str,level);
147             str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
148             str_free(fstr);
149             str_cat(str,"\n");
150         }
151         if (exitval)
152             str_cat(str,"exit $ExitValue;\n");
153         if (subs->str_ptr) {
154             str_cat(str,"\n");
155             str_scat(str,subs);
156         }
157         if (saw_getline) {
158             for (len = 0; len < 4; len++) {
159                 if (saw_getline & (1 << len)) {
160                     sprintf(tokenbuf,"\nsub Getline%d {\n",len);
161                     str_cat(str, tokenbuf);
162                     if (len & 2) {
163                         if (do_fancy_opens)
164                             str_cat(str,"    &Pick('',@_);\n");
165                         else
166                             str_cat(str,"    ($fh) = @_;\n");
167                     }
168                     else {
169                         if (saw_FNR)
170                             str_cat(str,"    $FNRbase = $. if eof;\n");
171                     }
172                     if (len & 1)
173                         str_cat(str,"    local($_);\n");
174                     if (len & 2)
175                         str_cat(str,
176                           "    if ($getline_ok = (($_ = <$fh>) ne ''))");
177                     else
178                         str_cat(str,
179                           "    if ($getline_ok = (($_ = <>) ne ''))");
180                     str_cat(str, " {\n");
181                     level += 2;
182                     tab(str,level);
183                     i = 0;
184                     if (do_chop) {
185                         i++;
186                         str_cat(str,"chop;\t# strip record separator\n");
187                         tab(str,level);
188                     }
189                     if (do_split && !(len & 1)) {
190                         i++;
191                         emit_split(str,level);
192                     }
193                     if (!i)
194                         str_cat(str,";\n");
195                     fixtab(str,--level);
196                     str_cat(str,"}\n    $_;\n}\n");
197                     --level;
198                 }
199             }
200         }
201         if (do_fancy_opens) {
202             str_cat(str,"\n\
203 sub Pick {\n\
204     local($mode,$name,$pipe) = @_;\n\
205     $fh = $opened{$name};\n\
206     if (!$fh) {\n\
207         $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
208         open($fh,$mode.$name.$pipe);\n\
209     }\n\
210 }\n\
211 ");
212         }
213         break;
214     case OHUNKS:
215         str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
216         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
217         str_free(fstr);
218         if (len == 3) {
219             str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
220             str_free(fstr);
221         }
222         else {
223         }
224         break;
225     case ORANGE:
226         prec = P_DOTDOT;
227         str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
228         str_cat(str," .. ");
229         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
230         str_free(fstr);
231         break;
232     case OPAT:
233         goto def;
234     case OREGEX:
235         str = str_new(0);
236         str_set(str,"/");
237         tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
238         /* translate \nnn to [\nnn] */
239         for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
240             if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
241                 *d++ = '[';
242                 *d++ = *s++;
243                 *d++ = *s++;
244                 *d++ = *s++;
245                 *d++ = *s;
246                 *d = ']';
247             }
248             else
249                 *d = *s;
250         }
251         *d = '\0';
252         for (d=tokenbuf; *d; d++)
253             *d += 128;
254         str_cat(str,tokenbuf);
255         str_free(tmpstr);
256         str_cat(str,"/");
257         break;
258     case OHUNK:
259         if (len == 1) {
260             str = str_new(0);
261             str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
262             str_cat(str," if ");
263             str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
264             str_free(fstr);
265             str_cat(str,";");
266         }
267         else {
268             tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
269             if (*tmpstr->str_ptr) {
270                 str = str_new(0);
271                 str_set(str,"if (");
272                 str_scat(str,tmpstr);
273                 str_cat(str,") {\n");
274                 tab(str,++level);
275                 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
276                 str_free(fstr);
277                 fixtab(str,--level);
278                 str_cat(str,"}\n");
279                 tab(str,level);
280             }
281             else {
282                 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
283             }
284         }
285         break;
286     case OPPAREN:
287         str = str_new(0);
288         str_set(str,"(");
289         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
290         str_free(fstr);
291         str_cat(str,")");
292         break;
293     case OPANDAND:
294         prec = P_ANDAND;
295         str = walk(1,level,ops[node+1].ival,&numarg,prec);
296         str_cat(str," && ");
297         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
298         str_free(fstr);
299         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
300         str_free(fstr);
301         break;
302     case OPOROR:
303         prec = P_OROR;
304         str = walk(1,level,ops[node+1].ival,&numarg,prec);
305         str_cat(str," || ");
306         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
307         str_free(fstr);
308         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
309         str_free(fstr);
310         break;
311     case OPNOT:
312         prec = P_UNARY;
313         str = str_new(0);
314         str_set(str,"!");
315         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
316         str_free(fstr);
317         break;
318     case OCOND:
319         prec = P_COND;
320         str = walk(1,level,ops[node+1].ival,&numarg,prec);
321         str_cat(str," ? ");
322         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
323         str_free(fstr);
324         str_cat(str," : ");
325         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
326         str_free(fstr);
327         break;
328     case OCPAREN:
329         str = str_new(0);
330         str_set(str,"(");
331         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
332         str_free(fstr);
333         numeric |= numarg;
334         str_cat(str,")");
335         break;
336     case OCANDAND:
337         prec = P_ANDAND;
338         str = walk(1,level,ops[node+1].ival,&numarg,prec);
339         numeric = 1;
340         str_cat(str," && ");
341         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
342         str_free(fstr);
343         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
344         str_free(fstr);
345         break;
346     case OCOROR:
347         prec = P_OROR;
348         str = walk(1,level,ops[node+1].ival,&numarg,prec);
349         numeric = 1;
350         str_cat(str," || ");
351         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
352         str_free(fstr);
353         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
354         str_free(fstr);
355         break;
356     case OCNOT:
357         prec = P_UNARY;
358         str = str_new(0);
359         str_set(str,"!");
360         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
361         str_free(fstr);
362         numeric = 1;
363         break;
364     case ORELOP:
365         prec = P_REL;
366         str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
367         numeric |= numarg;
368         tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
369         tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
370         numeric |= numarg;
371         if (!numeric ||
372          (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
373             t = tmpstr->str_ptr;
374             if (strEQ(t,"=="))
375                 str_set(tmpstr,"eq");
376             else if (strEQ(t,"!="))
377                 str_set(tmpstr,"ne");
378             else if (strEQ(t,"<"))
379                 str_set(tmpstr,"lt");
380             else if (strEQ(t,"<="))
381                 str_set(tmpstr,"le");
382             else if (strEQ(t,">"))
383                 str_set(tmpstr,"gt");
384             else if (strEQ(t,">="))
385                 str_set(tmpstr,"ge");
386             if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
387               !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
388                 numeric |= 2;
389         }
390         if (numeric & 2) {
391             if (numeric & 1)            /* numeric is very good guess */
392                 str_cat(str," ");
393             else
394                 str_cat(str,"\377");
395             numeric = 1;
396         }
397         else
398             str_cat(str," ");
399         str_scat(str,tmpstr);
400         str_free(tmpstr);
401         str_cat(str," ");
402         str_scat(str,tmp2str);
403         str_free(tmp2str);
404         numeric = 1;
405         break;
406     case ORPAREN:
407         str = str_new(0);
408         str_set(str,"(");
409         str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
410         str_free(fstr);
411         numeric |= numarg;
412         str_cat(str,")");
413         break;
414     case OMATCHOP:
415         prec = P_MATCH;
416         str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
417         str_cat(str," ");
418         tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
419         if (strEQ(tmpstr->str_ptr,"~"))
420             str_cat(str,"=~");
421         else {
422             str_scat(str,tmpstr);
423             str_free(tmpstr);
424         }
425         str_cat(str," ");
426         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
427         str_free(fstr);
428         numeric = 1;
429         break;
430     case OMPAREN:
431         str = str_new(0);
432         str_set(str,"(");
433         str_scat(str,
434           fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
435         str_free(fstr);
436         numeric |= numarg;
437         str_cat(str,")");
438         break;
439     case OCONCAT:
440         prec = P_ADD;
441         type = ops[ops[node+1].ival].ival & 255;
442         str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
443         str_cat(str," . ");
444         type = ops[ops[node+2].ival].ival & 255;
445         str_scat(str,
446           fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
447         str_free(fstr);
448         break;
449     case OASSIGN:
450         prec = P_ASSIGN;
451         str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
452         str_cat(str," ");
453         tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
454         str_scat(str,tmpstr);
455         if (str_len(tmpstr) > 1)
456             numeric = 1;
457         str_free(tmpstr);
458         str_cat(str," ");
459         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
460         str_free(fstr);
461         numeric |= numarg;
462         break;
463     case OADD:
464         prec = P_ADD;
465         str = walk(1,level,ops[node+1].ival,&numarg,prec);
466         str_cat(str," + ");
467         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
468         str_free(fstr);
469         numeric = 1;
470         break;
471     case OSUBTRACT:
472         prec = P_ADD;
473         str = walk(1,level,ops[node+1].ival,&numarg,prec);
474         str_cat(str," - ");
475         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
476         str_free(fstr);
477         numeric = 1;
478         break;
479     case OMULT:
480         prec = P_MUL;
481         str = walk(1,level,ops[node+1].ival,&numarg,prec);
482         str_cat(str," * ");
483         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
484         str_free(fstr);
485         numeric = 1;
486         break;
487     case ODIV:
488         prec = P_MUL;
489         str = walk(1,level,ops[node+1].ival,&numarg,prec);
490         str_cat(str," / ");
491         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
492         str_free(fstr);
493         numeric = 1;
494         break;
495     case OPOW:
496         prec = P_POW;
497         str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
498         str_cat(str," ** ");
499         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
500         str_free(fstr);
501         numeric = 1;
502         break;
503     case OMOD:
504         prec = P_MUL;
505         str = walk(1,level,ops[node+1].ival,&numarg,prec);
506         str_cat(str," % ");
507         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
508         str_free(fstr);
509         numeric = 1;
510         break;
511     case OPOSTINCR:
512         prec = P_AUTO;
513         str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
514         str_cat(str,"++");
515         numeric = 1;
516         break;
517     case OPOSTDECR:
518         prec = P_AUTO;
519         str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
520         str_cat(str,"--");
521         numeric = 1;
522         break;
523     case OPREINCR:
524         prec = P_AUTO;
525         str = str_new(0);
526         str_set(str,"++");
527         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
528         str_free(fstr);
529         numeric = 1;
530         break;
531     case OPREDECR:
532         prec = P_AUTO;
533         str = str_new(0);
534         str_set(str,"--");
535         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
536         str_free(fstr);
537         numeric = 1;
538         break;
539     case OUMINUS:
540         prec = P_UNARY;
541         str = str_new(0);
542         str_set(str,"-");
543         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
544         str_free(fstr);
545         numeric = 1;
546         break;
547     case OUPLUS:
548         numeric = 1;
549         goto def;
550     case OPAREN:
551         str = str_new(0);
552         str_set(str,"(");
553         str_scat(str,
554           fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
555         str_free(fstr);
556         str_cat(str,")");
557         numeric |= numarg;
558         break;
559     case OGETLINE:
560         str = str_new(0);
561         if (useval)
562             str_cat(str,"(");
563         if (len > 0) {
564             str_cat(str,"$");
565             str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
566             if (!*fstr->str_ptr) {
567                 str_cat(str,"_");
568                 len = 2;                /* a legal fiction */
569             }
570             str_free(fstr);
571         }
572         else
573             str_cat(str,"$_");
574         if (len > 1) {
575             tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
576             fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
577             if (!do_fancy_opens) {
578                 t = tmpstr->str_ptr;
579                 if (*t == '"' || *t == '\'')
580                     t = cpytill(tokenbuf,t+1,*t);
581                 else
582                     fatal("Internal error: OGETLINE %s", t);
583                 d = savestr(t);
584                 s = savestr(tokenbuf);
585                 for (t = tokenbuf; *t; t++) {
586                     *t &= 127;
587                     if (!isalpha(*t) && !isdigit(*t))
588                         *t = '_';
589                 }
590                 if (!index(tokenbuf,'_'))
591                     strcpy(t,"_fh");
592                 tmp3str = hfetch(symtab,tokenbuf);
593                 if (!tmp3str) {
594                     do_opens = TRUE;
595                     str_cat(opens,"open(");
596                     str_cat(opens,tokenbuf);
597                     str_cat(opens,", ");
598                     d[1] = '\0';
599                     str_cat(opens,d);
600                     str_cat(opens,tmpstr->str_ptr+1);
601                     opens->str_cur--;
602                     if (*fstr->str_ptr == '|')
603                         str_cat(opens,"|");
604                     str_cat(opens,d);
605                     if (*fstr->str_ptr == '|')
606                         str_cat(opens,") || die 'Cannot pipe from \"");
607                     else
608                         str_cat(opens,") || die 'Cannot open file \"");
609                     if (*d == '"')
610                         str_cat(opens,"'.\"");
611                     str_cat(opens,s);
612                     if (*d == '"')
613                         str_cat(opens,"\".'");
614                     str_cat(opens,"\".';\n");
615                     hstore(symtab,tokenbuf,str_make("x"));
616                 }
617                 safefree(s);
618                 safefree(d);
619                 str_set(tmpstr,"'");
620                 str_cat(tmpstr,tokenbuf);
621                 str_cat(tmpstr,"'");
622             }
623             if (*fstr->str_ptr == '|')
624                 str_cat(tmpstr,", '|'");
625             str_free(fstr);
626         }
627         else
628             tmpstr = str_make("");
629         sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
630         str_cat(str,tokenbuf); 
631         str_free(tmpstr);
632         if (useval)
633             str_cat(str,",$getline_ok)");
634         saw_getline |= 1 << len;
635         break;
636     case OSPRINTF:
637         str = str_new(0);
638         str_set(str,"sprintf(");
639         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
640         str_free(fstr);
641         str_cat(str,")");
642         break;
643     case OSUBSTR:
644         str = str_new(0);
645         str_set(str,"substr(");
646         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
647         str_free(fstr);
648         str_cat(str,", ");
649         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
650         str_free(fstr);
651         str_cat(str,", ");
652         if (len == 3) {
653             str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
654             str_free(fstr);
655         }
656         else
657             str_cat(str,"999999");
658         str_cat(str,")");
659         break;
660     case OSTRING:
661         str = str_new(0);
662         str_set(str,ops[node+1].cval);
663         break;
664     case OSPLIT:
665         str = str_new(0);
666         numeric = 1;
667         tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
668         if (useval)
669             str_set(str,"(@");
670         else
671             str_set(str,"@");
672         str_scat(str,tmpstr);
673         str_cat(str," = split(");
674         if (len == 3) {
675             fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
676             if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
677                 i = fstr->str_ptr[1] & 127;
678                 if (index("*+?.[]()|^$\\",i))
679                     sprintf(tokenbuf,"/\\%c/",i);
680                 else if (i == ' ')
681                     sprintf(tokenbuf,"' '");
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,", 9999)");
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': case '$':
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 || !*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]/, $_, 9999);\n",const_FS);
1591         str_cat(str,tokenbuf);
1592     }
1593     else if (saw_FS)
1594         str_cat(str," = split($FS, $_, 9999);\n");
1595     else
1596         str_cat(str," = split(' ', $_, 9999);\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 }