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