source: trunk/third/perl/x2p/walk.c @ 20075

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