1 /* $RCSfile: walk.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:31 $
3 * Copyright (c) 1991, Larry Wall
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.
16 bool realexit = FALSE;
17 bool saw_getline = FALSE;
18 bool subretnum = FALSE;
20 bool saw_argv0 = FALSE;
27 STR *curargs = Nullstr;
29 void addsemi _(( STR *str ));
30 void emit_split _(( STR *str, int level ));
31 void fixtab _(( STR *str, int lvl ));
32 void numericize _(( int node ));
33 int prewalk _(( int numit, int level, int node, int *numericptr ));
34 void tab _(( STR *str, int lvl ));
35 STR * walk _(( int useval, int level, int node, int *numericptr, int minprec ));
39 walk(useval,level,node,numericptr,minprec)
44 int minprec; /* minimum precedence without parens */
58 int prec = P_MAX; /* assume no parens needed */
64 type = ops[node].ival;
71 while (isalpha(*namelist)) {
72 for (d = tokenbuf,s=namelist;
73 isalpha(*s) || isdigit(*s) || *s == '_';
76 while (*s && !isalpha(*s)) s++;
78 nameary[++arymax] = savestr(tokenbuf);
85 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
86 if (do_split && need_entire && !absmaxfld)
87 split_to_array = TRUE;
88 if (do_split && split_to_array)
89 set_array_base = TRUE;
91 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
93 if (fswitch && !const_FS)
95 if (saw_FS > 1 || saw_RS)
97 if (saw_ORS && need_entire)
100 str_cat(str,"$FS = '");
101 if (strchr("*+?.[]()|^$\\",fswitch))
103 sprintf(tokenbuf,"%c",fswitch);
104 str_cat(str,tokenbuf);
105 str_cat(str,"';\t\t# field separator from -F switch\n");
107 else if (saw_FS && !const_FS) {
108 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
111 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
114 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
117 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
119 if (str->str_cur > 20)
121 if (ops[node+2].ival) {
122 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
126 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
127 if (*fstr->str_ptr) {
129 str_cat(str,"line: ");
130 str_cat(str,"while (<>) {\n");
132 if (saw_FS && !const_FS)
135 str_cat(str,"chop;\t# strip record separator\n");
139 emit_split(str,level);
145 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
148 str_cat(str,"while (<>) { } # (no line actions)\n");
149 if (ops[node+4].ival) {
153 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
158 str_cat(str,"exit $ExitValue;\n");
164 for (len = 0; len < 4; len++) {
165 if (saw_getline & (1 << len)) {
166 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
167 str_cat(str, tokenbuf);
170 str_cat(str," &Pick('',@_);\n");
172 str_cat(str," ($fh) = @_;\n");
176 str_cat(str," $FNRbase = $. if eof;\n");
179 str_cat(str," local($_);\n");
182 " if ($getline_ok = (($_ = <$fh>) ne ''))");
185 " if ($getline_ok = (($_ = <>) ne ''))");
186 str_cat(str, " {\n");
192 str_cat(str,"chop;\t# strip record separator\n");
195 if (do_split && !(len & 1)) {
197 emit_split(str,level);
202 str_cat(str,"}\n $_;\n}\n");
207 if (do_fancy_opens) {
210 local($mode,$name,$pipe) = @_;\n\
212 open($name,$mode.$name.$pipe) unless $opened{$name}++;\n\
218 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
219 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
222 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
230 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
232 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
240 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
241 /* translate \nnn to [\nnn] */
242 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
243 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
255 for (d=tokenbuf; *d; d++)
257 str_cat(str,tokenbuf);
264 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
266 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
271 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
272 if (*tmpstr->str_ptr) {
275 str_scat(str,tmpstr);
276 str_cat(str,") {\n");
278 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
285 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
292 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
298 str = walk(1,level,ops[node+1].ival,&numarg,prec);
300 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
302 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
307 str = walk(1,level,ops[node+1].ival,&numarg,prec);
309 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
311 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
318 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
323 str = walk(1,level,ops[node+1].ival,&numarg,prec);
325 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
328 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
334 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
341 str = walk(1,level,ops[node+1].ival,&numarg,prec);
344 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
346 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
351 str = walk(1,level,ops[node+1].ival,&numarg,prec);
354 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
356 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
363 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
369 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
371 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
372 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
375 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
378 str_set(tmpstr,"eq");
379 else if (strEQ(t,"!="))
380 str_set(tmpstr,"ne");
381 else if (strEQ(t,"<"))
382 str_set(tmpstr,"lt");
383 else if (strEQ(t,"<="))
384 str_set(tmpstr,"le");
385 else if (strEQ(t,">"))
386 str_set(tmpstr,"gt");
387 else if (strEQ(t,">="))
388 str_set(tmpstr,"ge");
389 if (!strchr(tmpstr->str_ptr,'\'') && !strchr(tmpstr->str_ptr,'"') &&
390 !strchr(tmp2str->str_ptr,'\'') && !strchr(tmp2str->str_ptr,'"') )
394 if (numeric & 1) /* numeric is very good guess */
402 str_scat(str,tmpstr);
405 str_scat(str,tmp2str);
412 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
419 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
421 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
422 if (strEQ(tmpstr->str_ptr,"~"))
425 str_scat(str,tmpstr);
429 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
437 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
444 type = ops[ops[node+1].ival].ival & 255;
445 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
447 type = ops[ops[node+2].ival].ival & 255;
449 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
454 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
456 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
457 str_scat(str,tmpstr);
458 if (str_len(tmpstr) > 1)
462 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
465 if (strEQ(str->str_ptr,"$/ = ''"))
466 str_set(str, "$/ = \"\\n\\n\"");
470 str = walk(1,level,ops[node+1].ival,&numarg,prec);
472 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
478 str = walk(1,level,ops[node+1].ival,&numarg,prec);
480 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
486 str = walk(1,level,ops[node+1].ival,&numarg,prec);
488 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
494 str = walk(1,level,ops[node+1].ival,&numarg,prec);
496 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
502 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
504 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
510 str = walk(1,level,ops[node+1].ival,&numarg,prec);
512 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
518 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
524 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
532 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
540 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
548 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
559 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
569 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
570 if (!*fstr->str_ptr) {
572 len = 2; /* a legal fiction */
579 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
580 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
581 if (!do_fancy_opens) {
583 if (*t == '"' || *t == '\'')
584 t = cpytill(tokenbuf,t+1,*t);
586 fatal("Internal error: OGETLINE %s", t);
588 s = savestr(tokenbuf);
589 for (t = tokenbuf; *t; t++) {
593 if (!isalpha(*t) && !isdigit(*t))
596 if (!strchr(tokenbuf,'_'))
598 tmp3str = hfetch(symtab,tokenbuf);
601 str_cat(opens,"open(");
602 str_cat(opens,tokenbuf);
606 str_cat(opens,tmpstr->str_ptr+1);
608 if (*fstr->str_ptr == '|')
611 if (*fstr->str_ptr == '|')
612 str_cat(opens,") || die 'Cannot pipe from \"");
614 str_cat(opens,") || die 'Cannot open file \"");
616 str_cat(opens,"'.\"");
619 str_cat(opens,"\".'");
620 str_cat(opens,"\".';\n");
621 hstore(symtab,tokenbuf,str_make("x"));
626 str_cat(tmpstr,tokenbuf);
629 if (*fstr->str_ptr == '|')
630 str_cat(tmpstr,", '|'");
634 tmpstr = str_make("");
635 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
636 str_cat(str,tokenbuf);
639 str_cat(str,",$getline_ok)");
640 saw_getline |= 1 << len;
644 str_set(str,"sprintf(");
645 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
651 str_set(str,"substr(");
652 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
655 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
659 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
663 str_cat(str,"999999");
668 str_set(str,ops[node+1].cval);
674 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
679 str_scat(str,tmpstr);
680 str_cat(str," = split(");
682 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
683 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
684 i = fstr->str_ptr[1] & 127;
685 if (strchr("*+?.[]()|^$\\",i))
686 sprintf(tokenbuf,"/\\%c/",i);
688 sprintf(tokenbuf,"' '");
690 sprintf(tokenbuf,"/%c/",i);
691 str_cat(str,tokenbuf);
698 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
699 str_cat(str,tokenbuf);
708 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
718 str_set(str,"index(");
719 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
722 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
730 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
733 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
735 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
741 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
742 curargs = str_new(0);
743 str_sset(curargs,fstr);
744 str_cat(curargs,",");
745 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
751 t = tmp2str->str_ptr;
752 while (t = instr(t,"return "))
756 for (t = s+7; *t; t++) {
757 if (*t == ';' || *t == '}')
762 tmp2str->str_cur -= 7;
768 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
772 str_cat(str,"local(");
774 str_cat(str,") = @_;");
777 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
780 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
783 str_scat(str,tmp2str);
791 tmp2str = str_new(0);
793 str_set(tmp2str,"1");
794 hstore(symtab,tmpstr->str_ptr,tmp2str);
801 str_cat(str,"return ");
802 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
808 str_cat(str,"return");
813 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
816 tmpstr = hfetch(symtab,str->str_ptr+3);
817 if (tmpstr && tmpstr->str_ptr)
818 numeric |= atoi(tmpstr->str_ptr);
819 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
833 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
834 if (strNE(tmpstr->str_ptr,"$_")) {
835 str_cat(tmpstr, " =~ s");
839 str_set(tmpstr, "s");
842 str_set(tmpstr, "s");
843 type = ops[ops[node+2].ival].ival;
846 tmp3str = str_new(0);
848 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
849 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
857 str_set(tmp2str,tokenbuf);
860 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
861 str_set(tmp3str,"($s_ = '\"'.(");
862 str_scat(tmp3str,tmp2str);
863 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
864 str_set(tmp2str,"eval $s_");
865 s = (*s == 'g' ? "ge" : "e");
868 type = ops[ops[node+1].ival].ival;
871 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
872 if (type == OREGEX) {
875 str_scat(str,tmp3str);
876 str_scat(str,tmpstr);
878 str_scat(str,tmp2str);
882 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
885 str_scat(str,tmp3str);
886 str_scat(str,tmpstr);
890 str_scat(str,tmp2str);
898 str_cat(str,"$s = ");
901 str_scat(str,tmp3str);
902 str_scat(str,tmpstr);
904 str_scat(str,tmp2str);
917 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
921 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
923 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
926 else if (*t == '\\') {
930 case '\\': case '"': case 'n': case 't': case '$':
932 default: /* hide this from perl */
941 str_cat(str,tokenbuf);
948 str_set(str,"defined $");
952 str_set(str,"delete $");
962 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
964 tmp2str = hfetch(symtab,tmpstr->str_ptr);
965 if (tmp2str && atoi(tmp2str->str_ptr))
967 if (strEQ(str->str_ptr,"$FNR")) {
970 str_set(str,"($.-$FNRbase)");
972 else if (strEQ(str->str_ptr,"$NR")) {
976 else if (strEQ(str->str_ptr,"$NF")) {
978 str_set(str,"$#Fld");
980 else if (strEQ(str->str_ptr,"$0"))
982 else if (strEQ(str->str_ptr,"$ARGC"))
983 str_set(str,"($#ARGV+1)");
988 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
989 ??? if (instr(curargs->str_ptr,tokenbuf))
990 str_cat(str,"\377"); /* can't translate yet */
993 str_cat(tmpstr,"[]");
994 tmp2str = hfetch(symtab,tmpstr->str_ptr);
995 if (tmp2str && atoi(tmp2str->str_ptr))
999 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1001 if (strEQ(str->str_ptr,"$ARGV[0")) {
1002 str_set(str,"$ARGV0");
1006 if (tmp2str && atoi(tmp2str->str_ptr))
1007 strcpy(tokenbuf,"]");
1009 strcpy(tokenbuf,"}");
1011 str_cat(str,tokenbuf);
1018 if (split_to_array) {
1019 str_set(str,"$Fld");
1021 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1026 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1028 sprintf(tokenbuf,"$%s",nameary[i]);
1030 sprintf(tokenbuf,"$Fld%d",i);
1031 str_set(str,tokenbuf);
1036 str_set(str,"$Fld[");
1037 i = ops[node+1].ival;
1038 if ((ops[i].ival & 255) == OPAREN)
1040 tmpstr=walk(1,level,i,&numarg,P_MIN);
1041 str_scat(str,tmpstr);
1060 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1061 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1063 str_scat(str,tmpstr);
1069 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1070 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1072 str_scat(str,tmpstr);
1078 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1080 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1082 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1091 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1092 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1098 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1101 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1102 if (*tmpstr->str_ptr == ';') {
1104 str_cat(str,tmpstr->str_ptr+1);
1111 str = str_make("close(");
1112 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1113 if (!do_fancy_opens) {
1114 t = tmpstr->str_ptr;
1115 if (*t == '"' || *t == '\'')
1116 t = cpytill(tokenbuf,t+1,*t);
1118 fatal("Internal error: OCLOSE %s",t);
1119 s = savestr(tokenbuf);
1120 for (t = tokenbuf; *t; t++) {
1124 if (!isalpha(*t) && !isdigit(*t))
1127 if (!strchr(tokenbuf,'_'))
1131 str_set(str,"close ");
1132 str_cat(str,tokenbuf);
1135 sprintf(tokenbuf,"delete $opened{%s} && close(%s)",
1136 tmpstr->str_ptr, tmpstr->str_ptr);
1138 str_set(str,tokenbuf);
1143 lparen = ""; /* set to parens if necessary */
1146 if (len == 3) { /* output redirection */
1147 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1148 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1149 if (!do_fancy_opens) {
1150 t = tmpstr->str_ptr;
1151 if (*t == '"' || *t == '\'')
1152 t = cpytill(tokenbuf,t+1,*t);
1154 fatal("Internal error: OPRINT");
1156 s = savestr(tokenbuf);
1157 for (t = tokenbuf; *t; t++) {
1161 if (!isalpha(*t) && !isdigit(*t))
1164 if (!strchr(tokenbuf,'_'))
1166 tmp3str = hfetch(symtab,tokenbuf);
1168 str_cat(opens,"open(");
1169 str_cat(opens,tokenbuf);
1170 str_cat(opens,", ");
1173 str_scat(opens,tmp2str);
1174 str_cat(opens,tmpstr->str_ptr+1);
1175 if (*tmp2str->str_ptr == '|')
1176 str_cat(opens,") || die 'Cannot pipe to \"");
1178 str_cat(opens,") || die 'Cannot create file \"");
1180 str_cat(opens,"'.\"");
1183 str_cat(opens,"\".'");
1184 str_cat(opens,"\".';\n");
1185 hstore(symtab,tokenbuf,str_make("x"));
1193 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1194 tmp2str->str_ptr, tmpstr->str_ptr);
1195 str_cat(str,tokenbuf);
1197 strcpy(tokenbuf,"$fh");
1205 strcpy(tokenbuf,"");
1206 str_cat(str,lparen); /* may be null */
1207 if (type == OPRINTF)
1208 str_cat(str,"printf");
1210 str_cat(str,"print");
1212 if (len == 3 || do_fancy_opens) {
1217 str_cat(str,tokenbuf);
1219 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1220 if (!*tmpstr->str_ptr && lval_field) {
1221 t = saw_OFS ? "$," : "' '";
1222 if (split_to_array) {
1223 sprintf(tokenbuf,"join(%s,@Fld)",t);
1224 str_cat(tmpstr,tokenbuf);
1227 for (i = 1; i < maxfld; i++) {
1229 sprintf(tokenbuf,"$%s, ",nameary[i]);
1231 sprintf(tokenbuf,"$Fld%d, ",i);
1232 str_cat(tmpstr,tokenbuf);
1234 if (maxfld <= arymax)
1235 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1237 sprintf(tokenbuf,"$Fld%d",maxfld);
1238 str_cat(tmpstr,tokenbuf);
1241 if (*tmpstr->str_ptr) {
1243 if (!saw_fh && *tmpstr->str_ptr == '(') {
1245 str_scat(str,tmpstr);
1249 str_scat(str,tmpstr);
1254 str_cat(str,rparen); /* may be null */
1258 str = str_make("rand(1)");
1261 str = str_make("srand(");
1264 str = str_make("atan2(");
1267 str = str_make("sin(");
1270 str = str_make("cos(");
1273 str = str_make("system(");
1276 str = str_make("length(");
1279 str = str_make("log(");
1282 str = str_make("exp(");
1285 str = str_make("sqrt(");
1288 str = str_make("int(");
1292 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1294 tmpstr = str_new(0);;
1295 if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
1297 t = saw_OFS ? "$," : "' '";
1298 if (split_to_array) {
1299 sprintf(tokenbuf,"join(%s,@Fld)",t);
1300 str_cat(tmpstr,tokenbuf);
1303 sprintf(tokenbuf,"join(%s, ",t);
1304 str_cat(tmpstr,tokenbuf);
1305 for (i = 1; i < maxfld; i++) {
1307 sprintf(tokenbuf,"$%s,",nameary[i]);
1309 sprintf(tokenbuf,"$Fld%d,",i);
1310 str_cat(tmpstr,tokenbuf);
1312 if (maxfld <= arymax)
1313 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1315 sprintf(tokenbuf,"$Fld%d)",maxfld);
1316 str_cat(tmpstr,tokenbuf);
1320 str_cat(tmpstr,"$_");
1322 if (strEQ(tmpstr->str_ptr,"$_")) {
1323 if (type == OLENGTH && !do_chop) {
1324 str = str_make("(length(");
1325 str_cat(tmpstr,") - 1");
1328 str_scat(str,tmpstr);
1334 str_set(str,"last");
1338 str_set(str,"next line");
1344 str_set(str,"exit");
1349 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1355 str_set(str,"$ExitValue = ");
1358 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1362 str_cat(str,"last line");
1367 str_set(str,"next");
1373 str_set(str,"if (");
1374 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1377 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1380 i = ops[node+3].ival;
1382 if ((ops[i].ival & 255) == OBLOCK) {
1385 if ((ops[i].ival & 255) != OIF)
1394 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1398 str_cat(str,"else ");
1399 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1406 str_set(str,"while (");
1407 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1410 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1416 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1418 if (str->str_ptr[str->str_cur - 1] == '\n')
1420 str_cat(str," while (");
1421 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1427 str_set(str,"for (");
1428 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1431 t = s = tmpstr->str_ptr;
1432 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1439 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1440 if (i && (t = strchr(fstr->str_ptr,0377))) {
1441 if (strnEQ(fstr->str_ptr,s,i))
1448 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1451 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1455 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1456 d = strchr(tmpstr->str_ptr,'$');
1458 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1463 fatal("Illegal for loop: %s",d);
1465 for (t = s; i = *t; t++) {
1467 if (i == '}' || i == ']')
1475 tmp2str = hfetch(symtab,str->str_ptr);
1476 if (tmp2str && atoi(tmp2str->str_ptr)) {
1478 "foreach %s ($[ .. $#%s) ",
1484 "foreach %s (keys %%%s) ",
1488 str_set(str,tokenbuf);
1489 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1496 if (len >= 2 && ops[node+2].ival) {
1497 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1500 fixtab(str,++level);
1501 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1504 fixtab(str,--level);
1508 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1516 fatal("Garbage length in walk");
1517 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1518 for (i = 2; i<= len; i++) {
1519 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1531 if (useval && prec < minprec) { /* need parens? */
1532 fstr = str_new(str->str_cur+2);
1533 str_nset(fstr,"(",1);
1535 str_ncat(fstr,")",1);
1540 *numericptr = numeric;
1543 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1544 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1547 else if (*t == '\t')
1577 /* strip trailing white space */
1579 s = str->str_ptr+str->str_cur - 1;
1580 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1583 str->str_cur = s + 1 - str->str_ptr;
1584 if (s >= str->str_ptr && *s != '\n')
1596 s = str->str_ptr+str->str_cur - 1;
1597 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1599 if (s >= str->str_ptr && *s != ';' && *s != '}')
1604 emit_split(str,level)
1611 str_cat(str,"@Fld");
1614 for (i = 1; i < maxfld; i++) {
1616 sprintf(tokenbuf,"$%s,",nameary[i]);
1618 sprintf(tokenbuf,"$Fld%d,",i);
1619 str_cat(str,tokenbuf);
1621 if (maxfld <= arymax)
1622 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1624 sprintf(tokenbuf,"$Fld%d)",maxfld);
1625 str_cat(str,tokenbuf);
1628 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
1629 str_cat(str,tokenbuf);
1632 str_cat(str," = split($FS, $_, 9999);\n");
1634 str_cat(str," = split(' ', $_, 9999);\n");
1639 prewalk(numit,level,node,numericptr)
1649 int numeric = FALSE;
1657 type = ops[node].ival;
1662 prewalk(0,level,ops[node+1].ival,&numarg);
1663 if (ops[node+2].ival) {
1664 prewalk(0,level,ops[node+2].ival,&numarg);
1667 prewalk(0,level,ops[node+3].ival,&numarg);
1669 if (ops[node+3].ival) {
1670 prewalk(0,level,ops[node+4].ival,&numarg);
1674 prewalk(0,level,ops[node+1].ival,&numarg);
1675 prewalk(0,level,ops[node+2].ival,&numarg);
1677 prewalk(0,level,ops[node+3].ival,&numarg);
1681 prewalk(1,level,ops[node+1].ival,&numarg);
1682 prewalk(1,level,ops[node+2].ival,&numarg);
1687 prewalk(0,level,ops[node+1].ival,&numarg);
1691 prewalk(0,level,ops[node+1].ival,&numarg);
1694 i = prewalk(0,level,ops[node+1].ival,&numarg);
1697 prewalk(0,level,ops[node+2].ival,&numarg);
1701 prewalk(0,level,ops[node+2].ival,&numarg);
1706 prewalk(0,level,ops[node+1].ival,&numarg);
1709 prewalk(0,level,ops[node+1].ival,&numarg);
1710 prewalk(0,level,ops[node+2].ival,&numarg);
1713 prewalk(0,level,ops[node+1].ival,&numarg);
1714 prewalk(0,level,ops[node+2].ival,&numarg);
1717 prewalk(0,level,ops[node+1].ival,&numarg);
1720 prewalk(0,level,ops[node+1].ival,&numarg);
1724 prewalk(0,level,ops[node+1].ival,&numarg);
1726 prewalk(0,level,ops[node+2].ival,&numarg);
1729 prewalk(0,level,ops[node+1].ival,&numarg);
1731 prewalk(0,level,ops[node+2].ival,&numarg);
1734 prewalk(0,level,ops[node+1].ival,&numarg);
1738 prewalk(0,level,ops[node+2].ival,&numarg);
1740 prewalk(0,level,ops[node+1].ival,&numarg);
1741 prewalk(0,level,ops[node+3].ival,&numarg);
1746 prewalk(0,level,ops[node+1].ival,&numarg);
1750 prewalk(0,level,ops[node+2].ival,&numarg);
1751 prewalk(0,level,ops[node+1].ival,&numarg);
1752 prewalk(0,level,ops[node+3].ival,&numarg);
1756 prewalk(0,level,ops[node+1].ival,&numarg);
1760 prewalk(0,level,ops[node+1].ival,&numarg);
1761 prewalk(0,level,ops[node+2].ival,&numarg);
1764 prewalk(0,level,ops[node+2].ival,&numarg);
1765 prewalk(0,level,ops[node+1].ival,&numarg);
1766 prewalk(0,level,ops[node+3].ival,&numarg);
1767 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > (Size_t)1) {
1768 numericize(ops[node+2].ival);
1770 numericize(ops[node+3].ival);
1775 prewalk(1,level,ops[node+1].ival,&numarg);
1776 prewalk(1,level,ops[node+2].ival,&numarg);
1780 prewalk(1,level,ops[node+1].ival,&numarg);
1781 prewalk(1,level,ops[node+2].ival,&numarg);
1785 prewalk(1,level,ops[node+1].ival,&numarg);
1786 prewalk(1,level,ops[node+2].ival,&numarg);
1790 prewalk(1,level,ops[node+1].ival,&numarg);
1791 prewalk(1,level,ops[node+2].ival,&numarg);
1795 prewalk(1,level,ops[node+1].ival,&numarg);
1796 prewalk(1,level,ops[node+2].ival,&numarg);
1800 prewalk(1,level,ops[node+1].ival,&numarg);
1801 prewalk(1,level,ops[node+2].ival,&numarg);
1805 prewalk(1,level,ops[node+1].ival,&numarg);
1809 prewalk(1,level,ops[node+1].ival,&numarg);
1813 prewalk(1,level,ops[node+1].ival,&numarg);
1817 prewalk(1,level,ops[node+1].ival,&numarg);
1821 prewalk(1,level,ops[node+1].ival,&numarg);
1825 prewalk(1,level,ops[node+1].ival,&numarg);
1829 prewalk(0,level,ops[node+1].ival,&numarg);
1835 prewalk(0,level,ops[node+1].ival,&numarg);
1838 prewalk(0,level,ops[node+1].ival,&numarg);
1839 prewalk(1,level,ops[node+2].ival,&numarg);
1841 prewalk(1,level,ops[node+3].ival,&numarg);
1848 prewalk(0,level,ops[node+2].ival,&numarg);
1850 prewalk(0,level,ops[node+3].ival,&numarg);
1851 prewalk(0,level,ops[node+1].ival,&numarg);
1854 prewalk(0,level,ops[node+1].ival,&numarg);
1855 prewalk(0,level,ops[node+2].ival,&numarg);
1859 prewalk(0,level,ops[node+1].ival,&numarg);
1860 prewalk(0,level,ops[node+2].ival,&numarg);
1866 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1868 prewalk(0,level,ops[node+2].ival,&numarg);
1869 prewalk(0,level,ops[node+4].ival,&numarg);
1870 prewalk(0,level,ops[node+5].ival,&numarg);
1872 str_cat(tmpstr,"(");
1873 tmp2str = str_new(0);
1874 if (subretnum || numarg)
1875 str_set(tmp2str,"1");
1876 hstore(symtab,tmpstr->str_ptr,tmp2str);
1882 prewalk(0,level,ops[node+1].ival,&numarg);
1888 tmp2str = str_new(0);
1889 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1890 fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
1892 str_cat(tmp2str,"(");
1893 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1894 if (tmpstr && tmpstr->str_ptr)
1895 numeric |= atoi(tmpstr->str_ptr);
1896 prewalk(0,level,ops[node+2].ival,&numarg);
1902 prewalk(0,level,ops[node+3].ival,&numarg);
1903 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1904 prewalk(0,level,ops[node+1].ival,&numarg);
1908 prewalk(0,level,ops[node+1].ival,&numarg);
1912 prewalk(0,level,ops[node+1].ival,&numarg);
1918 prewalk(0,level,ops[node+1].ival,&numarg);
1924 prewalk(0,level,ops[node+2].ival,&numarg);
1928 prewalk(0,level,ops[node+1].ival,&numarg);
1931 i = ops[node+1].ival;
1932 prewalk(0,level,i,&numarg);
1945 prewalk(0,level,ops[node+1].ival,&numarg);
1946 prewalk(0,level,ops[node+2].ival,&numarg);
1947 prewalk(0,level,ops[node+3].ival,&numarg);
1952 prewalk(0,level,ops[node+1].ival,&numarg);
1953 prewalk(0,level,ops[node+2].ival,&numarg);
1957 prewalk(0,level,ops[node+1].ival,&numarg);
1959 prewalk(0,level,ops[node+2].ival,&numarg);
1964 prewalk(0,level,ops[node+1].ival,&numarg);
1968 if (len == 3) { /* output redirection */
1969 prewalk(0,level,ops[node+3].ival,&numarg);
1970 prewalk(0,level,ops[node+2].ival,&numarg);
1972 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1998 prewalk(type != OLENGTH && type != OSYSTEM,
1999 level,ops[node+1].ival,&numarg);
2007 prewalk(1,level,ops[node+1].ival,&numarg);
2015 prewalk(0,level,ops[node+1].ival,&numarg);
2016 prewalk(0,level,ops[node+2].ival,&numarg);
2018 prewalk(0,level,ops[node+3].ival,&numarg);
2022 prewalk(0,level,ops[node+1].ival,&numarg);
2023 prewalk(0,level,ops[node+2].ival,&numarg);
2026 prewalk(0,level,ops[node+1].ival,&numarg);
2027 prewalk(0,level,ops[node+2].ival,&numarg);
2028 prewalk(0,level,ops[node+3].ival,&numarg);
2029 prewalk(0,level,ops[node+4].ival,&numarg);
2032 prewalk(0,level,ops[node+2].ival,&numarg);
2033 prewalk(0,level,ops[node+1].ival,&numarg);
2037 prewalk(0,level,ops[node+2].ival,&numarg);
2040 prewalk(0,level,ops[node+1].ival,&numarg);
2047 fatal("Garbage length in prewalk");
2048 prewalk(0,level,ops[node+1].ival,&numarg);
2049 for (i = 2; i<= len; i++) {
2050 prewalk(0,level,ops[node+i].ival,&numarg);
2055 *numericptr = numeric;
2069 type = ops[node].ival;
2072 if (type == OVAR && len == 1) {
2073 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2074 tmp2str = str_make("1");
2075 hstore(symtab,tmpstr->str_ptr,tmp2str);