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