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

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