1 /* $Header: walk.c,v 3.0 89/10/18 15:35:48 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0 89/10/18 15:35:48 lwall
20 bool realexit = FALSE;
21 bool saw_getline = FALSE;
22 bool subretnum = FALSE;
24 bool saw_argv0 = FALSE;
29 STR *curargs = Nullstr;
32 walk(useval,level,node,numericptr,minprec)
37 int minprec; /* minimum precedence without parens */
51 int prec = P_MAX; /* assume no parens needed */
58 type = ops[node].ival;
65 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
66 if (do_split && need_entire && !absmaxfld)
67 split_to_array = TRUE;
68 if (do_split && split_to_array)
69 set_array_base = TRUE;
71 str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
73 if (fswitch && !const_FS)
75 if (saw_FS > 1 || saw_RS)
77 if (saw_ORS && need_entire)
80 str_cat(str,"$FS = '");
81 if (index("*+?.[]()|^$\\",fswitch))
83 sprintf(tokenbuf,"%c",fswitch);
84 str_cat(str,tokenbuf);
85 str_cat(str,"';\t\t# field separator from -F switch\n");
87 else if (saw_FS && !const_FS) {
88 str_cat(str,"$FS = ' ';\t\t# set field separator\n");
91 str_cat(str,"$, = ' ';\t\t# set output field separator\n");
94 str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
97 str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
99 if (str->str_cur > 20)
101 if (ops[node+2].ival) {
102 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
106 fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
107 if (*fstr->str_ptr) {
109 str_cat(str,"line: ");
110 str_cat(str,"while (<>) {\n");
112 if (saw_FS && !const_FS)
115 str_cat(str,"chop;\t# strip record separator\n");
120 while (isalpha(*namelist)) {
121 for (d = tokenbuf,s=namelist;
122 isalpha(*s) || isdigit(*s) || *s == '_';
125 while (*s && !isalpha(*s)) s++;
127 nameary[++arymax] = savestr(tokenbuf);
133 emit_split(str,level);
139 str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
142 str_cat(str,"# (no line actions)\n");
143 if (ops[node+4].ival) {
147 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
152 str_cat(str,"exit ExitValue;\n");
158 for (len = 0; len < 4; len++) {
159 if (saw_getline & (1 << len)) {
160 sprintf(tokenbuf,"\nsub Getline%d {\n",len);
161 str_cat(str, tokenbuf);
164 str_cat(str," &Pick('',@_);\n");
166 str_cat(str," ($fh) = @_;\n");
170 str_cat(str," $FNRbase = $. if eof;\n");
173 str_cat(str," local($_)\n");
176 " if ($getline_ok = (($_ = <$fh>) ne ''))");
179 " if ($getline_ok = (($_ = <>) ne ''))");
180 str_cat(str, " {\n");
186 str_cat(str,"chop;\t# strip record separator\n");
189 if (do_split && !(len & 1)) {
191 emit_split(str,level);
196 str_cat(str,"}\n $_;\n}\n");
201 if (do_fancy_opens) {
204 local($mode,$name,$pipe) = @_;\n\
205 $fh = $opened{$name};\n\
207 $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
208 open($fh,$mode.$name.$pipe);\n\
215 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
216 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
219 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
227 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
229 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
237 tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
238 /* translate \nnn to [\nnn] */
239 for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
240 if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
252 for (d=tokenbuf; *d; d++)
254 str_cat(str,tokenbuf);
261 str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
263 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
268 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
269 if (*tmpstr->str_ptr) {
272 str_scat(str,tmpstr);
273 str_cat(str,") {\n");
275 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
282 str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
289 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
295 str = walk(1,level,ops[node+1].ival,&numarg,prec);
297 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
299 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
304 str = walk(1,level,ops[node+1].ival,&numarg,prec);
306 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
308 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
315 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
321 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
328 str = walk(1,level,ops[node+1].ival,&numarg,prec);
331 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
333 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
338 str = walk(1,level,ops[node+1].ival,&numarg,prec);
341 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
343 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
350 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
356 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
358 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
359 tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
362 (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
365 str_set(tmpstr,"eq");
366 else if (strEQ(t,"!="))
367 str_set(tmpstr,"ne");
368 else if (strEQ(t,"<"))
369 str_set(tmpstr,"lt");
370 else if (strEQ(t,"<="))
371 str_set(tmpstr,"le");
372 else if (strEQ(t,">"))
373 str_set(tmpstr,"gt");
374 else if (strEQ(t,">="))
375 str_set(tmpstr,"ge");
376 if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
377 !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
381 if (numeric & 1) /* numeric is very good guess */
389 str_scat(str,tmpstr);
392 str_scat(str,tmp2str);
399 str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
406 str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
408 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
409 if (strEQ(tmpstr->str_ptr,"~"))
412 str_scat(str,tmpstr);
416 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
424 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
431 type = ops[ops[node+1].ival].ival & 255;
432 str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
434 type = ops[ops[node+2].ival].ival & 255;
436 fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
441 str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
443 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
444 str_scat(str,tmpstr);
445 if (str_len(tmpstr) > 1)
449 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
455 str = walk(1,level,ops[node+1].ival,&numarg,prec);
457 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
463 str = walk(1,level,ops[node+1].ival,&numarg,prec);
465 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
471 str = walk(1,level,ops[node+1].ival,&numarg,prec);
473 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
479 str = walk(1,level,ops[node+1].ival,&numarg,prec);
481 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
487 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
489 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
495 str = walk(1,level,ops[node+1].ival,&numarg,prec);
497 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
503 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
509 str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
517 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
525 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
533 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
544 fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
555 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
556 if (!*fstr->str_ptr) {
558 len = 2; /* a legal fiction */
565 tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
566 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
567 if (!do_fancy_opens) {
569 if (*t == '"' || *t == '\'')
570 t = cpytill(tokenbuf,t+1,*t);
572 fatal("Internal error: OGETLINE %s", t);
574 s = savestr(tokenbuf);
575 for (t = tokenbuf; *t; t++) {
577 if (!isalpha(*t) && !isdigit(*t))
580 if (!index(tokenbuf,'_'))
582 tmp3str = hfetch(symtab,tokenbuf);
585 str_cat(opens,"open(");
586 str_cat(opens,tokenbuf);
590 str_cat(opens,tmpstr->str_ptr+1);
592 if (*fstr->str_ptr == '|')
595 if (*fstr->str_ptr == '|')
596 str_cat(opens,") || die 'Cannot pipe from \"");
598 str_cat(opens,") || die 'Cannot open file \"");
600 str_cat(opens,"'.\"");
603 str_cat(opens,"\".'");
604 str_cat(opens,"\".';\n");
605 hstore(symtab,tokenbuf,str_make("x"));
610 str_cat(tmpstr,tokenbuf);
613 if (*fstr->str_ptr == '|')
614 str_cat(tmpstr,", '|'");
618 tmpstr = str_make("");
619 sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
620 str_cat(str,tokenbuf);
623 str_cat(str,",$getline_ok)");
624 saw_getline |= 1 << len;
628 str_set(str,"sprintf(");
629 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
635 str_set(str,"substr(");
636 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
639 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
643 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
647 str_cat(str,"999999");
652 str_set(str,ops[node+1].cval);
657 tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
662 str_scat(str,tmpstr);
663 str_cat(str," = split(");
665 fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
666 if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
667 i = fstr->str_ptr[1] & 127;
668 if (index("*+?.[]()|^$\\",i))
669 sprintf(tokenbuf,"/\\%c/",i);
671 sprintf(tokenbuf,"/%c/",i);
672 str_cat(str,tokenbuf);
679 sprintf(tokenbuf,"/[%c\\n]/",const_FS);
680 str_cat(str,tokenbuf);
687 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
689 str_cat(str,", 999)");
697 str_set(str,"index(");
698 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
701 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
709 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
712 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
714 str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
720 fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
721 curargs = str_new(0);
722 str_sset(curargs,fstr);
723 str_cat(curargs,",");
724 tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
730 t = tmp2str->str_ptr;
731 while (t = instr(t,"return "))
735 for (t = s+7; *t; t++) {
736 if (*t == ';' || *t == '}')
741 tmp2str->str_cur -= 7;
747 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
751 str_cat(str,"local(");
753 str_cat(str,") = @_;");
756 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
759 str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
762 str_scat(str,tmp2str);
770 tmp2str = str_new(0);
772 str_set(tmp2str,"1");
773 hstore(symtab,tmpstr->str_ptr,tmp2str);
780 str_cat(str,"return ");
781 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
787 str_cat(str,"return");
792 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
795 tmpstr = hfetch(symtab,str->str_ptr+3);
796 if (tmpstr && tmpstr->str_ptr)
797 numeric |= atoi(tmpstr->str_ptr);
798 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
812 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
813 if (strNE(tmpstr->str_ptr,"$_")) {
814 str_cat(tmpstr, " =~ s");
818 str_set(tmpstr, "s");
821 str_set(tmpstr, "s");
822 type = ops[ops[node+2].ival].ival;
825 tmp3str = str_new(0);
827 tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
828 for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
836 str_set(tmp2str,tokenbuf);
839 tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
840 str_set(tmp3str,"($s_ = '\"'.(");
841 str_scat(tmp3str,tmp2str);
842 str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
843 str_set(tmp2str,"eval $s_");
844 s = (*s == 'g' ? "ge" : "e");
847 type = ops[ops[node+1].ival].ival;
850 fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
851 if (type == OREGEX) {
854 str_scat(str,tmp3str);
855 str_scat(str,tmpstr);
857 str_scat(str,tmp2str);
861 else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
864 str_scat(str,tmp3str);
865 str_scat(str,tmpstr);
869 str_scat(str,tmp2str);
877 str_cat(str,"$s = ");
880 str_scat(str,tmp3str);
881 str_scat(str,tmpstr);
883 str_scat(str,tmp2str);
896 str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
900 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
902 for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
905 else if (*t == '\\') {
909 case '\\': case '"': case 'n': case 't':
911 default: /* hide this from perl */
920 str_cat(str,tokenbuf);
927 str_set(str,"defined $");
931 str_set(str,"delete $");
941 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
943 tmp2str = hfetch(symtab,tmpstr->str_ptr);
944 if (tmp2str && atoi(tmp2str->str_ptr))
946 if (strEQ(str->str_ptr,"$FNR")) {
949 str_set(str,"($.-$FNRbase)");
951 else if (strEQ(str->str_ptr,"$NR")) {
955 else if (strEQ(str->str_ptr,"$NF")) {
957 str_set(str,"$#Fld");
959 else if (strEQ(str->str_ptr,"$0"))
961 else if (strEQ(str->str_ptr,"$ARGC"))
962 str_set(str,"($#ARGV+1)");
967 sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
968 ??? if (instr(curargs->str_ptr,tokenbuf))
969 str_cat(str,"\377"); /* can't translate yet */
972 str_cat(tmpstr,"[]");
973 tmp2str = hfetch(symtab,tmpstr->str_ptr);
974 if (tmp2str && atoi(tmp2str->str_ptr))
978 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
980 if (strEQ(str->str_ptr,"$ARGV[0")) {
981 str_set(str,"$ARGV0");
985 if (tmp2str && atoi(tmp2str->str_ptr))
986 strcpy(tokenbuf,"]");
988 strcpy(tokenbuf,"}");
990 str_cat(str,tokenbuf);
997 if (split_to_array) {
1000 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1005 i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
1007 sprintf(tokenbuf,"$%s",nameary[i]);
1009 sprintf(tokenbuf,"$Fld%d",i);
1010 str_set(str,tokenbuf);
1015 str_set(str,"$Fld[");
1016 i = ops[node+1].ival;
1017 if ((ops[i].ival & 255) == OPAREN)
1019 tmpstr=walk(1,level,i,&numarg,P_MIN);
1020 str_scat(str,tmpstr);
1039 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1040 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1042 str_scat(str,tmpstr);
1048 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1049 for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
1051 str_scat(str,tmpstr);
1057 str = walk(1,level,ops[node+1].ival,&numarg,prec);
1059 str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
1061 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
1070 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1071 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1077 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1080 tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
1081 if (*tmpstr->str_ptr == ';') {
1083 str_cat(str,tmpstr->str_ptr+1);
1090 str = str_make("close(");
1091 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1092 if (!do_fancy_opens) {
1093 t = tmpstr->str_ptr;
1094 if (*t == '"' || *t == '\'')
1095 t = cpytill(tokenbuf,t+1,*t);
1097 fatal("Internal error: OCLOSE %s",t);
1098 s = savestr(tokenbuf);
1099 for (t = tokenbuf; *t; t++) {
1101 if (!isalpha(*t) && !isdigit(*t))
1104 if (!index(tokenbuf,'_'))
1108 str_set(str,"close ");
1109 str_cat(str,tokenbuf);
1112 sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
1115 str_set(str,tokenbuf);
1120 lparen = ""; /* set to parens if necessary */
1123 if (len == 3) { /* output redirection */
1124 tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
1125 tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1126 if (!do_fancy_opens) {
1127 t = tmpstr->str_ptr;
1128 if (*t == '"' || *t == '\'')
1129 t = cpytill(tokenbuf,t+1,*t);
1131 fatal("Internal error: OPRINT");
1133 s = savestr(tokenbuf);
1134 for (t = tokenbuf; *t; t++) {
1136 if (!isalpha(*t) && !isdigit(*t))
1139 if (!index(tokenbuf,'_'))
1141 tmp3str = hfetch(symtab,tokenbuf);
1143 str_cat(opens,"open(");
1144 str_cat(opens,tokenbuf);
1145 str_cat(opens,", ");
1148 str_scat(opens,tmp2str);
1149 str_cat(opens,tmpstr->str_ptr+1);
1150 if (*tmp2str->str_ptr == '|')
1151 str_cat(opens,") || die 'Cannot pipe to \"");
1153 str_cat(opens,") || die 'Cannot create file \"");
1155 str_cat(opens,"'.\"");
1158 str_cat(opens,"\".'");
1159 str_cat(opens,"\".';\n");
1160 hstore(symtab,tokenbuf,str_make("x"));
1168 sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
1169 tmp2str->str_ptr, tmpstr->str_ptr);
1170 str_cat(str,tokenbuf);
1172 strcpy(tokenbuf,"$fh");
1180 strcpy(tokenbuf,"");
1181 str_cat(str,lparen); /* may be null */
1182 if (type == OPRINTF)
1183 str_cat(str,"printf");
1185 str_cat(str,"print");
1186 if (len == 3 || do_fancy_opens) {
1189 str_cat(str,tokenbuf);
1191 tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
1192 if (!*tmpstr->str_ptr && lval_field) {
1193 t = saw_OFS ? "$," : "' '";
1194 if (split_to_array) {
1195 sprintf(tokenbuf,"join(%s,@Fld)",t);
1196 str_cat(tmpstr,tokenbuf);
1199 for (i = 1; i < maxfld; i++) {
1201 sprintf(tokenbuf,"$%s, ",nameary[i]);
1203 sprintf(tokenbuf,"$Fld%d, ",i);
1204 str_cat(tmpstr,tokenbuf);
1206 if (maxfld <= arymax)
1207 sprintf(tokenbuf,"$%s",nameary[maxfld]);
1209 sprintf(tokenbuf,"$Fld%d",maxfld);
1210 str_cat(tmpstr,tokenbuf);
1213 if (*tmpstr->str_ptr) {
1215 str_scat(str,tmpstr);
1220 str_cat(str,rparen); /* may be null */
1224 str = str_make("rand(1)");
1227 str = str_make("srand(");
1230 str = str_make("atan2(");
1233 str = str_make("sin(");
1236 str = str_make("cos(");
1239 str = str_make("system(");
1242 str = str_make("length(");
1245 str = str_make("log(");
1248 str = str_make("exp(");
1251 str = str_make("sqrt(");
1254 str = str_make("int(");
1258 tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
1260 tmpstr = str_new(0);;
1261 if (!*tmpstr->str_ptr) {
1263 t = saw_OFS ? "$," : "' '";
1264 if (split_to_array) {
1265 sprintf(tokenbuf,"join(%s,@Fld)",t);
1266 str_cat(tmpstr,tokenbuf);
1269 sprintf(tokenbuf,"join(%s, ",t);
1270 str_cat(tmpstr,tokenbuf);
1271 for (i = 1; i < maxfld; i++) {
1273 sprintf(tokenbuf,"$%s,",nameary[i]);
1275 sprintf(tokenbuf,"$Fld%d,",i);
1276 str_cat(tmpstr,tokenbuf);
1278 if (maxfld <= arymax)
1279 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1281 sprintf(tokenbuf,"$Fld%d)",maxfld);
1282 str_cat(tmpstr,tokenbuf);
1286 str_cat(tmpstr,"$_");
1288 if (strEQ(tmpstr->str_ptr,"$_")) {
1289 if (type == OLENGTH && !do_chop) {
1290 str = str_make("(length(");
1291 str_cat(tmpstr,") - 1");
1294 str_scat(str,tmpstr);
1300 str_set(str,"last");
1304 str_set(str,"next line");
1310 str_set(str,"exit");
1315 fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
1321 str_set(str,"ExitValue = ");
1324 fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
1328 str_cat(str,"last line");
1333 str_set(str,"next");
1339 str_set(str,"if (");
1340 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1343 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1346 i = ops[node+3].ival;
1348 if ((ops[i].ival & 255) == OBLOCK) {
1351 if ((ops[i].ival & 255) != OIF)
1360 str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
1364 str_cat(str,"else ");
1365 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1372 str_set(str,"while (");
1373 str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1376 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1381 str_set(str,"for (");
1382 str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1385 t = s = tmpstr->str_ptr;
1386 while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
1393 fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
1394 if (i && (t = index(fstr->str_ptr,0377))) {
1395 if (strnEQ(fstr->str_ptr,s,i))
1402 str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
1405 str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
1409 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1410 d = index(tmpstr->str_ptr,'$');
1412 fatal("Illegal for loop: %s",tmpstr->str_ptr);
1417 fatal("Illegal for loop: %s",d);
1419 t = index(s,'}' + 128);
1421 t = index(s,']' + 128);
1427 tmp2str = hfetch(symtab,str->str_ptr);
1428 if (tmp2str && atoi(tmp2str->str_ptr)) {
1430 "foreach %s (@%s) ",
1436 "foreach %s (keys %%%s) ",
1440 str_set(str,tokenbuf);
1441 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1448 if (len >= 2 && ops[node+2].ival) {
1449 str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
1452 fixtab(str,++level);
1453 str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
1456 fixtab(str,--level);
1460 str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
1468 fatal("Garbage length in walk");
1469 str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1470 for (i = 2; i<= len; i++) {
1471 str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
1483 if (useval && prec < minprec) { /* need parens? */
1484 fstr = str_new(str->str_cur+2);
1485 str_nset(fstr,"(",1);
1487 str_ncat(fstr,")",1);
1492 *numericptr = numeric;
1495 printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
1496 for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
1499 else if (*t == '\t')
1527 /* strip trailing white space */
1529 s = str->str_ptr+str->str_cur - 1;
1530 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1533 str->str_cur = s + 1 - str->str_ptr;
1534 if (s >= str->str_ptr && *s != '\n')
1545 s = str->str_ptr+str->str_cur - 1;
1546 while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
1548 if (s >= str->str_ptr && *s != ';' && *s != '}')
1552 emit_split(str,level)
1559 str_cat(str,"@Fld");
1562 for (i = 1; i < maxfld; i++) {
1564 sprintf(tokenbuf,"$%s,",nameary[i]);
1566 sprintf(tokenbuf,"$Fld%d,",i);
1567 str_cat(str,tokenbuf);
1569 if (maxfld <= arymax)
1570 sprintf(tokenbuf,"$%s)",nameary[maxfld]);
1572 sprintf(tokenbuf,"$Fld%d)",maxfld);
1573 str_cat(str,tokenbuf);
1576 sprintf(tokenbuf," = split(/[%c\\n]/, $_, 999);\n",const_FS);
1577 str_cat(str,tokenbuf);
1580 str_cat(str," = split($FS, $_, 999);\n");
1582 str_cat(str," = split(' ', $_, 999);\n");
1586 prewalk(numit,level,node,numericptr)
1598 int numeric = FALSE;
1606 type = ops[node].ival;
1611 prewalk(0,level,ops[node+1].ival,&numarg);
1612 if (ops[node+2].ival) {
1613 prewalk(0,level,ops[node+2].ival,&numarg);
1616 prewalk(0,level,ops[node+3].ival,&numarg);
1618 if (ops[node+3].ival) {
1619 prewalk(0,level,ops[node+4].ival,&numarg);
1623 prewalk(0,level,ops[node+1].ival,&numarg);
1624 prewalk(0,level,ops[node+2].ival,&numarg);
1626 prewalk(0,level,ops[node+3].ival,&numarg);
1630 prewalk(1,level,ops[node+1].ival,&numarg);
1631 prewalk(1,level,ops[node+2].ival,&numarg);
1636 prewalk(0,level,ops[node+1].ival,&numarg);
1640 prewalk(0,level,ops[node+1].ival,&numarg);
1643 i = prewalk(0,level,ops[node+1].ival,&numarg);
1646 prewalk(0,level,ops[node+2].ival,&numarg);
1650 prewalk(0,level,ops[node+2].ival,&numarg);
1655 prewalk(0,level,ops[node+1].ival,&numarg);
1658 prewalk(0,level,ops[node+1].ival,&numarg);
1659 prewalk(0,level,ops[node+2].ival,&numarg);
1662 prewalk(0,level,ops[node+1].ival,&numarg);
1663 prewalk(0,level,ops[node+2].ival,&numarg);
1666 prewalk(0,level,ops[node+1].ival,&numarg);
1669 prewalk(0,level,ops[node+1].ival,&numarg);
1673 prewalk(0,level,ops[node+1].ival,&numarg);
1675 prewalk(0,level,ops[node+2].ival,&numarg);
1678 prewalk(0,level,ops[node+1].ival,&numarg);
1680 prewalk(0,level,ops[node+2].ival,&numarg);
1683 prewalk(0,level,ops[node+1].ival,&numarg);
1687 prewalk(0,level,ops[node+2].ival,&numarg);
1689 prewalk(0,level,ops[node+1].ival,&numarg);
1690 prewalk(0,level,ops[node+3].ival,&numarg);
1695 prewalk(0,level,ops[node+1].ival,&numarg);
1699 prewalk(0,level,ops[node+2].ival,&numarg);
1700 prewalk(0,level,ops[node+1].ival,&numarg);
1701 prewalk(0,level,ops[node+3].ival,&numarg);
1705 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+2].ival,&numarg);
1714 prewalk(0,level,ops[node+1].ival,&numarg);
1715 prewalk(0,level,ops[node+3].ival,&numarg);
1716 if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
1717 numericize(ops[node+2].ival);
1719 numericize(ops[node+3].ival);
1724 prewalk(1,level,ops[node+1].ival,&numarg);
1725 prewalk(1,level,ops[node+2].ival,&numarg);
1729 prewalk(1,level,ops[node+1].ival,&numarg);
1730 prewalk(1,level,ops[node+2].ival,&numarg);
1734 prewalk(1,level,ops[node+1].ival,&numarg);
1735 prewalk(1,level,ops[node+2].ival,&numarg);
1739 prewalk(1,level,ops[node+1].ival,&numarg);
1740 prewalk(1,level,ops[node+2].ival,&numarg);
1744 prewalk(1,level,ops[node+1].ival,&numarg);
1745 prewalk(1,level,ops[node+2].ival,&numarg);
1749 prewalk(1,level,ops[node+1].ival,&numarg);
1750 prewalk(1,level,ops[node+2].ival,&numarg);
1754 prewalk(1,level,ops[node+1].ival,&numarg);
1758 prewalk(1,level,ops[node+1].ival,&numarg);
1762 prewalk(1,level,ops[node+1].ival,&numarg);
1766 prewalk(1,level,ops[node+1].ival,&numarg);
1770 prewalk(1,level,ops[node+1].ival,&numarg);
1774 prewalk(1,level,ops[node+1].ival,&numarg);
1778 prewalk(0,level,ops[node+1].ival,&numarg);
1784 prewalk(0,level,ops[node+1].ival,&numarg);
1787 prewalk(0,level,ops[node+1].ival,&numarg);
1788 prewalk(1,level,ops[node+2].ival,&numarg);
1790 prewalk(1,level,ops[node+3].ival,&numarg);
1797 prewalk(0,level,ops[node+2].ival,&numarg);
1799 prewalk(0,level,ops[node+3].ival,&numarg);
1800 prewalk(0,level,ops[node+1].ival,&numarg);
1803 prewalk(0,level,ops[node+1].ival,&numarg);
1804 prewalk(0,level,ops[node+2].ival,&numarg);
1808 prewalk(0,level,ops[node+1].ival,&numarg);
1809 prewalk(0,level,ops[node+2].ival,&numarg);
1815 tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
1817 prewalk(0,level,ops[node+2].ival,&numarg);
1818 prewalk(0,level,ops[node+4].ival,&numarg);
1819 prewalk(0,level,ops[node+5].ival,&numarg);
1821 str_cat(tmpstr,"(");
1822 tmp2str = str_new(0);
1823 if (subretnum || numarg)
1824 str_set(tmp2str,"1");
1825 hstore(symtab,tmpstr->str_ptr,tmp2str);
1831 prewalk(0,level,ops[node+1].ival,&numarg);
1837 tmp2str = str_new(0);
1838 str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
1839 fixrargs(tmpstr->str_ptr,ops[node+2],0);
1841 str_cat(tmp2str,"(");
1842 tmpstr = hfetch(symtab,tmp2str->str_ptr);
1843 if (tmpstr && tmpstr->str_ptr)
1844 numeric |= atoi(tmpstr->str_ptr);
1845 prewalk(0,level,ops[node+2].ival,&numarg);
1851 prewalk(0,level,ops[node+3].ival,&numarg);
1852 prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
1853 prewalk(0,level,ops[node+1].ival,&numarg);
1857 prewalk(0,level,ops[node+1].ival,&numarg);
1861 prewalk(0,level,ops[node+1].ival,&numarg);
1867 prewalk(0,level,ops[node+1].ival,&numarg);
1873 prewalk(0,level,ops[node+2].ival,&numarg);
1877 prewalk(0,level,ops[node+1].ival,&numarg);
1880 i = ops[node+1].ival;
1881 prewalk(0,level,i,&numarg);
1894 prewalk(0,level,ops[node+1].ival,&numarg);
1895 prewalk(0,level,ops[node+2].ival,&numarg);
1896 prewalk(0,level,ops[node+3].ival,&numarg);
1901 prewalk(0,level,ops[node+1].ival,&numarg);
1902 prewalk(0,level,ops[node+2].ival,&numarg);
1906 prewalk(0,level,ops[node+1].ival,&numarg);
1908 prewalk(0,level,ops[node+2].ival,&numarg);
1913 prewalk(0,level,ops[node+1].ival,&numarg);
1917 if (len == 3) { /* output redirection */
1918 prewalk(0,level,ops[node+3].ival,&numarg);
1919 prewalk(0,level,ops[node+2].ival,&numarg);
1921 prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
1947 prewalk(type != OLENGTH && type != OSYSTEM,
1948 level,ops[node+1].ival,&numarg);
1956 prewalk(1,level,ops[node+1].ival,&numarg);
1964 prewalk(0,level,ops[node+1].ival,&numarg);
1965 prewalk(0,level,ops[node+2].ival,&numarg);
1967 prewalk(0,level,ops[node+3].ival,&numarg);
1971 prewalk(0,level,ops[node+1].ival,&numarg);
1972 prewalk(0,level,ops[node+2].ival,&numarg);
1975 prewalk(0,level,ops[node+1].ival,&numarg);
1976 prewalk(0,level,ops[node+2].ival,&numarg);
1977 prewalk(0,level,ops[node+3].ival,&numarg);
1978 prewalk(0,level,ops[node+4].ival,&numarg);
1981 prewalk(0,level,ops[node+2].ival,&numarg);
1982 prewalk(0,level,ops[node+1].ival,&numarg);
1986 prewalk(0,level,ops[node+2].ival,&numarg);
1989 prewalk(0,level,ops[node+1].ival,&numarg);
1996 fatal("Garbage length in prewalk");
1997 prewalk(0,level,ops[node+1].ival,&numarg);
1998 for (i = 2; i<= len; i++) {
1999 prewalk(0,level,ops[node+i].ival,&numarg);
2004 *numericptr = numeric;
2018 type = ops[node].ival;
2021 if (type == OVAR && len == 1) {
2022 tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
2023 tmp2str = str_make("1");
2024 hstore(symtab,tmpstr->str_ptr,tmp2str);