summaryrefslogtreecommitdiff
path: root/x2p/walk.c
diff options
context:
space:
mode:
authorLarry Wall <larry@wall.org>1989-10-18 00:00:00 +0000
committerLarry Wall <larry@wall.org>1989-10-18 00:00:00 +0000
commita687059cbaf2c6fdccb5e0fae2aee80ec15625a8 (patch)
tree674c8533b7bd942204f23782934c72f8624dd308 /x2p/walk.c
parent13281fa4f8547e0eb31d1986b865d9b7ec7d0dcc (diff)
downloadperl-a687059cbaf2c6fdccb5e0fae2aee80ec15625a8.tar.gz
perl 3.0: (no announcement message available)perl-3.000
A few of the new features: (18 Oct) * Perl can now handle binary data correctly and has functions to pack and unpack binary structures into arrays or lists. You can now do arbitrary ioctl functions. * You can now pass things to subroutines by reference. * Debugger enhancements. * An array or associative array may now appear in a local() list. * Array values may now be interpolated into strings. * Subroutine names are now distinguished by prefixing with &. You can call subroutines without using do, and without passing any argument list at all. * You can use the new -u switch to cause perl to dump core so that you can run undump and produce a binary executable image. Alternately you can use the "dump" operator after initializing any variables and such. * You can now chop lists. * Perl now uses /bin/csh to do filename globbing, if available. This means that filenames with spaces or other strangenesses work right. * New functions: mkdir and rmdir, getppid, getpgrp and setpgrp, getpriority and setpriority, chroot, ioctl and fcntl, flock, readlink, lstat, rindex, pack and unpack, read, warn, dbmopen and dbmclose, dump, reverse, defined, undef.
Diffstat (limited to 'x2p/walk.c')
-rw-r--r--x2p/walk.c967
1 files changed, 753 insertions, 214 deletions
diff --git a/x2p/walk.c b/x2p/walk.c
index 344581ea03..959527de3a 100644
--- a/x2p/walk.c
+++ b/x2p/walk.c
@@ -1,8 +1,13 @@
-/* $Header: walk.c,v 2.0 88/06/05 00:16:12 root Exp $
+/* $Header: walk.c,v 3.0 89/10/18 15:35:48 lwall Locked $
+ *
+ * Copyright (c) 1989, Larry Wall
+ *
+ * You may distribute under the terms of the GNU General Public License
+ * as specified in the README file that comes with the perl 3.0 kit.
*
* $Log: walk.c,v $
- * Revision 2.0 88/06/05 00:16:12 root
- * Baseline version 2.0.
+ * Revision 3.0 89/10/18 15:35:48 lwall
+ * 3.0 baseline
*
*/
@@ -14,16 +19,22 @@
bool exitval = FALSE;
bool realexit = FALSE;
bool saw_getline = FALSE;
+bool subretnum = FALSE;
+bool saw_FNR = FALSE;
+bool saw_argv0 = FALSE;
int maxtmp = 0;
char *lparen;
char *rparen;
+STR *subs;
+STR *curargs = Nullstr;
STR *
-walk(useval,level,node,numericptr)
+walk(useval,level,node,numericptr,minprec)
int useval;
int level;
register int node;
int *numericptr;
+int minprec; /* minimum precedence without parens */
{
register int len;
register STR *str;
@@ -31,11 +42,13 @@ int *numericptr;
register int i;
register STR *tmpstr;
STR *tmp2str;
+ STR *tmp3str;
char *t;
char *d, *s;
int numarg;
int numeric = FALSE;
STR *fstr;
+ int prec = P_MAX; /* assume no parens needed */
char *index();
if (!node) {
@@ -47,8 +60,9 @@ int *numericptr;
type &= 255;
switch (type) {
case OPROG:
- str = walk(0,level,ops[node+1].ival,&numarg);
opens = str_new(0);
+ subs = str_new(0);
+ str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
if (do_split && need_entire && !absmaxfld)
split_to_array = TRUE;
if (do_split && split_to_array)
@@ -79,103 +93,140 @@ int *numericptr;
if (saw_ORS) {
str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
}
+ if (saw_argv0) {
+ str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
+ }
if (str->str_cur > 20)
str_cat(str,"\n");
if (ops[node+2].ival) {
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,"\n\n");
}
- if (saw_line_op)
- str_cat(str,"line: ");
- str_cat(str,"while (<>) {\n");
- tab(str,++level);
- if (saw_FS && !const_FS)
- do_chop = TRUE;
- if (do_chop) {
- str_cat(str,"chop;\t# strip record separator\n");
- tab(str,level);
- }
- arymax = 0;
- if (namelist) {
- while (isalpha(*namelist)) {
- for (d = tokenbuf,s=namelist;
- isalpha(*s) || isdigit(*s) || *s == '_';
- *d++ = *s++) ;
- *d = '\0';
- while (*s && !isalpha(*s)) s++;
- namelist = s;
- nameary[++arymax] = savestr(tokenbuf);
+ fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
+ if (*fstr->str_ptr) {
+ if (saw_line_op)
+ str_cat(str,"line: ");
+ str_cat(str,"while (<>) {\n");
+ tab(str,++level);
+ if (saw_FS && !const_FS)
+ do_chop = TRUE;
+ if (do_chop) {
+ str_cat(str,"chop;\t# strip record separator\n");
+ tab(str,level);
}
+ arymax = 0;
+ if (namelist) {
+ while (isalpha(*namelist)) {
+ for (d = tokenbuf,s=namelist;
+ isalpha(*s) || isdigit(*s) || *s == '_';
+ *d++ = *s++) ;
+ *d = '\0';
+ while (*s && !isalpha(*s)) s++;
+ namelist = s;
+ nameary[++arymax] = savestr(tokenbuf);
+ }
+ }
+ if (maxfld < arymax)
+ maxfld = arymax;
+ if (do_split)
+ emit_split(str,level);
+ str_scat(str,fstr);
+ str_free(fstr);
+ fixtab(str,--level);
+ str_cat(str,"}\n");
+ if (saw_FNR)
+ str_cat(str,"continue {\n $FNRbase = $. if eof;\n}\n");
}
- if (maxfld < arymax)
- maxfld = arymax;
- if (do_split)
- emit_split(str,level);
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
- str_free(fstr);
- fixtab(str,--level);
- str_cat(str,"}\n");
+ else
+ str_cat(str,"# (no line actions)\n");
if (ops[node+4].ival) {
realexit = TRUE;
str_cat(str,"\n");
tab(str,level);
- str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,"\n");
}
if (exitval)
str_cat(str,"exit ExitValue;\n");
+ if (subs->str_ptr) {
+ str_cat(str,"\n");
+ str_scat(str,subs);
+ }
if (saw_getline) {
- str_cat(str,"\nsub Getline {\n $_ = <>;\n");
- tab(str,++level);
- if (do_chop) {
- str_cat(str,"chop;\t# strip record separator\n");
- tab(str,level);
+ for (len = 0; len < 4; len++) {
+ if (saw_getline & (1 << len)) {
+ sprintf(tokenbuf,"\nsub Getline%d {\n",len);
+ str_cat(str, tokenbuf);
+ if (len & 2) {
+ if (do_fancy_opens)
+ str_cat(str," &Pick('',@_);\n");
+ else
+ str_cat(str," ($fh) = @_;\n");
+ }
+ else {
+ if (saw_FNR)
+ str_cat(str," $FNRbase = $. if eof;\n");
+ }
+ if (len & 1)
+ str_cat(str," local($_)\n");
+ if (len & 2)
+ str_cat(str,
+ " if ($getline_ok = (($_ = <$fh>) ne ''))");
+ else
+ str_cat(str,
+ " if ($getline_ok = (($_ = <>) ne ''))");
+ str_cat(str, " {\n");
+ level += 2;
+ tab(str,level);
+ i = 0;
+ if (do_chop) {
+ i++;
+ str_cat(str,"chop;\t# strip record separator\n");
+ tab(str,level);
+ }
+ if (do_split && !(len & 1)) {
+ i++;
+ emit_split(str,level);
+ }
+ if (!i)
+ str_cat(str,";\n");
+ fixtab(str,--level);
+ str_cat(str,"}\n $_;\n}\n");
+ --level;
+ }
}
- if (do_split)
- emit_split(str,level);
- fixtab(str,--level);
- str_cat(str,"}\n");
}
if (do_fancy_opens) {
str_cat(str,"\n\
sub Pick {\n\
- ($name) = @_;\n\
+ local($mode,$name,$pipe) = @_;\n\
$fh = $opened{$name};\n\
if (!$fh) {\n\
- $nextfh == 0 && open(fh_0,$name);\n\
- $nextfh == 1 && open(fh_1,$name);\n\
- $nextfh == 2 && open(fh_2,$name);\n\
- $nextfh == 3 && open(fh_3,$name);\n\
- $nextfh == 4 && open(fh_4,$name);\n\
- $nextfh == 5 && open(fh_5,$name);\n\
- $nextfh == 6 && open(fh_6,$name);\n\
- $nextfh == 7 && open(fh_7,$name);\n\
- $nextfh == 8 && open(fh_8,$name);\n\
- $nextfh == 9 && open(fh_9,$name);\n\
- $fh = $opened{$name} = 'fh_' . $nextfh++;\n\
+ $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
+ open($fh,$mode.$name.$pipe);\n\
}\n\
- select($fh);\n\
}\n\
");
}
break;
case OHUNKS:
- str = walk(0,level,ops[node+1].ival,&numarg);
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
if (len == 3) {
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
str_free(fstr);
}
else {
}
break;
case ORANGE:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_DOTDOT;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
str_cat(str," .. ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
str_free(fstr);
break;
case OPAT:
@@ -183,10 +234,10 @@ sub Pick {\n\
case OREGEX:
str = str_new(0);
str_set(str,"/");
- tmpstr=walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
/* translate \nnn to [\nnn] */
for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
- if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])) {
+ if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
*d++ = '[';
*d++ = *s++;
*d++ = *s++;
@@ -207,92 +258,108 @@ sub Pick {\n\
case OHUNK:
if (len == 1) {
str = str_new(0);
- str = walk(0,level,oper1(OPRINT,0),&numarg);
+ str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
str_cat(str," if ");
- str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,";");
}
else {
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
if (*tmpstr->str_ptr) {
str = str_new(0);
str_set(str,"if (");
str_scat(str,tmpstr);
str_cat(str,") {\n");
tab(str,++level);
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
fixtab(str,--level);
str_cat(str,"}\n");
tab(str,level);
}
else {
- str = walk(0,level,ops[node+2].ival,&numarg);
+ str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
}
}
break;
case OPPAREN:
str = str_new(0);
str_set(str,"(");
- str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,")");
break;
case OPANDAND:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_ANDAND;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," && ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
break;
case OPOROR:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_OROR;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," || ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
break;
case OPNOT:
+ prec = P_UNARY;
str = str_new(0);
str_set(str,"!");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
str_free(fstr);
break;
case OCPAREN:
str = str_new(0);
str_set(str,"(");
- str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
numeric |= numarg;
str_cat(str,")");
break;
case OCANDAND:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_ANDAND;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
numeric = 1;
str_cat(str," && ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
break;
case OCOROR:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_OROR;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
numeric = 1;
str_cat(str," || ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
break;
case OCNOT:
+ prec = P_UNARY;
str = str_new(0);
str_set(str,"!");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
str_free(fstr);
numeric = 1;
break;
case ORELOP:
- str = walk(1,level,ops[node+2].ival,&numarg);
+ prec = P_REL;
+ str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
numeric |= numarg;
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
- tmp2str = walk(1,level,ops[node+3].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
+ tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
numeric |= numarg;
- if (!numeric) {
+ if (!numeric ||
+ (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
t = tmpstr->str_ptr;
if (strEQ(t,"=="))
str_set(tmpstr,"eq");
@@ -329,15 +396,16 @@ sub Pick {\n\
case ORPAREN:
str = str_new(0);
str_set(str,"(");
- str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
numeric |= numarg;
str_cat(str,")");
break;
case OMATCHOP:
- str = walk(1,level,ops[node+2].ival,&numarg);
+ prec = P_MATCH;
+ str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
str_cat(str," ");
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
if (strEQ(tmpstr->str_ptr,"~"))
str_cat(str,"=~");
else {
@@ -345,100 +413,124 @@ sub Pick {\n\
str_free(tmpstr);
}
str_cat(str," ");
- str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case OMPAREN:
str = str_new(0);
str_set(str,"(");
- str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
+ str_scat(str,
+ fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
numeric |= numarg;
str_cat(str,")");
break;
case OCONCAT:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_ADD;
+ type = ops[ops[node+1].ival].ival & 255;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
str_cat(str," . ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ type = ops[ops[node+2].ival].ival & 255;
+ str_scat(str,
+ fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
str_free(fstr);
break;
case OASSIGN:
- str = walk(0,level,ops[node+2].ival,&numarg);
+ prec = P_ASSIGN;
+ str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
str_cat(str," ");
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
str_scat(str,tmpstr);
if (str_len(tmpstr) > 1)
numeric = 1;
str_free(tmpstr);
str_cat(str," ");
- str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
str_free(fstr);
numeric |= numarg;
break;
case OADD:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_ADD;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," + ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
- case OSUB:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ case OSUBTRACT:
+ prec = P_ADD;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," - ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case OMULT:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_MUL;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," * ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case ODIV:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_MUL;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," / ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
+ str_free(fstr);
+ numeric = 1;
+ break;
+ case OPOW:
+ prec = P_POW;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
+ str_cat(str," ** ");
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
str_free(fstr);
numeric = 1;
break;
case OMOD:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_MUL;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str," % ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case OPOSTINCR:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_AUTO;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
str_cat(str,"++");
numeric = 1;
break;
case OPOSTDECR:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_AUTO;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
str_cat(str,"--");
numeric = 1;
break;
case OPREINCR:
+ prec = P_AUTO;
str = str_new(0);
str_set(str,"++");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case OPREDECR:
+ prec = P_AUTO;
str = str_new(0);
str_set(str,"--");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
str_free(fstr);
numeric = 1;
break;
case OUMINUS:
+ prec = P_UNARY;
str = str_new(0);
str_set(str,"-");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
str_free(fstr);
numeric = 1;
break;
@@ -448,34 +540,107 @@ sub Pick {\n\
case OPAREN:
str = str_new(0);
str_set(str,"(");
- str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg));
+ str_scat(str,
+ fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,")");
numeric |= numarg;
break;
case OGETLINE:
str = str_new(0);
- str_set(str,"do Getline()");
- saw_getline = TRUE;
+ if (useval)
+ str_cat(str,"(");
+ if (len > 0) {
+ str_cat(str,"$");
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
+ if (!*fstr->str_ptr) {
+ str_cat(str,"_");
+ len = 2; /* a legal fiction */
+ }
+ str_free(fstr);
+ }
+ else
+ str_cat(str,"$_");
+ if (len > 1) {
+ tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
+ fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
+ if (!do_fancy_opens) {
+ t = tmpstr->str_ptr;
+ if (*t == '"' || *t == '\'')
+ t = cpytill(tokenbuf,t+1,*t);
+ else
+ fatal("Internal error: OGETLINE %s", t);
+ d = savestr(t);
+ s = savestr(tokenbuf);
+ for (t = tokenbuf; *t; t++) {
+ *t &= 127;
+ if (!isalpha(*t) && !isdigit(*t))
+ *t = '_';
+ }
+ if (!index(tokenbuf,'_'))
+ strcpy(t,"_fh");
+ tmp3str = hfetch(symtab,tokenbuf);
+ if (!tmp3str) {
+ do_opens = TRUE;
+ str_cat(opens,"open(");
+ str_cat(opens,tokenbuf);
+ str_cat(opens,", ");
+ d[1] = '\0';
+ str_cat(opens,d);
+ str_cat(opens,tmpstr->str_ptr+1);
+ opens->str_cur--;
+ if (*fstr->str_ptr == '|')
+ str_cat(opens,"|");
+ str_cat(opens,d);
+ if (*fstr->str_ptr == '|')
+ str_cat(opens,") || die 'Cannot pipe from \"");
+ else
+ str_cat(opens,") || die 'Cannot open file \"");
+ if (*d == '"')
+ str_cat(opens,"'.\"");
+ str_cat(opens,s);
+ if (*d == '"')
+ str_cat(opens,"\".'");
+ str_cat(opens,"\".';\n");
+ hstore(symtab,tokenbuf,str_make("x"));
+ }
+ safefree(s);
+ safefree(d);
+ str_set(tmpstr,"'");
+ str_cat(tmpstr,tokenbuf);
+ str_cat(tmpstr,"'");
+ }
+ if (*fstr->str_ptr == '|')
+ str_cat(tmpstr,", '|'");
+ str_free(fstr);
+ }
+ else
+ tmpstr = str_make("");
+ sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
+ str_cat(str,tokenbuf);
+ str_free(tmpstr);
+ if (useval)
+ str_cat(str,",$getline_ok)");
+ saw_getline |= 1 << len;
break;
case OSPRINTF:
str = str_new(0);
str_set(str,"sprintf(");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,")");
break;
case OSUBSTR:
str = str_new(0);
str_set(str,"substr(");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
str_free(fstr);
str_cat(str,", ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
str_free(fstr);
str_cat(str,", ");
if (len == 3) {
- str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
str_free(fstr);
}
else
@@ -489,7 +654,7 @@ sub Pick {\n\
case OSPLIT:
str = str_new(0);
numeric = 1;
- tmpstr = walk(1,level,ops[node+2].ival,&numarg);
+ tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
if (useval)
str_set(str,"(@");
else
@@ -497,7 +662,7 @@ sub Pick {\n\
str_scat(str,tmpstr);
str_cat(str," = split(");
if (len == 3) {
- fstr = walk(1,level,ops[node+3].ival,&numarg);
+ fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
i = fstr->str_ptr[1] & 127;
if (index("*+?.[]()|^$\\",i))
@@ -519,9 +684,9 @@ sub Pick {\n\
else
str_cat(str,"' '");
str_cat(str,", ");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
str_free(fstr);
- str_cat(str,")");
+ str_cat(str,", 999)");
if (useval) {
str_cat(str,")");
}
@@ -530,20 +695,209 @@ sub Pick {\n\
case OINDEX:
str = str_new(0);
str_set(str,"index(");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
str_free(fstr);
str_cat(str,", ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
str_free(fstr);
str_cat(str,")");
numeric = 1;
break;
+ case OMATCH:
+ str = str_new(0);
+ prec = P_ANDAND;
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
+ str_free(fstr);
+ str_cat(str," =~ ");
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
+ str_free(fstr);
+ str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
+ numeric = 1;
+ break;
+ case OUSERDEF:
+ str = str_new(0);
+ subretnum = FALSE;
+ fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
+ curargs = str_new(0);
+ str_sset(curargs,fstr);
+ str_cat(curargs,",");
+ tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
+ str_free(curargs);
+ curargs = Nullstr;
+ level--;
+ subretnum |= numarg;
+ s = Nullch;
+ t = tmp2str->str_ptr;
+ while (t = instr(t,"return "))
+ s = t++;
+ if (s) {
+ i = 0;
+ for (t = s+7; *t; t++) {
+ if (*t == ';' || *t == '}')
+ i++;
+ }
+ if (i == 1) {
+ strcpy(s,s+7);
+ tmp2str->str_cur -= 7;
+ }
+ }
+ str_set(str,"\n");
+ tab(str,level);
+ str_cat(str,"sub ");
+ str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
+ str_cat(str," {\n");
+ tab(str,++level);
+ if (fstr->str_cur) {
+ str_cat(str,"local(");
+ str_scat(str,fstr);
+ str_cat(str,") = @_;");
+ }
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
+ str_free(fstr);
+ fixtab(str,level);
+ str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
+ str_free(fstr);
+ fixtab(str,level);
+ str_scat(str,tmp2str);
+ str_free(tmp2str);
+ fixtab(str,--level);
+ str_cat(str,"}\n");
+ tab(str,level);
+ str_scat(subs,str);
+ str_set(str,"");
+ str_cat(tmpstr,"(");
+ tmp2str = str_new(0);
+ if (subretnum)
+ str_set(tmp2str,"1");
+ hstore(symtab,tmpstr->str_ptr,tmp2str);
+ str_free(tmpstr);
+ level++;
+ break;
+ case ORETURN:
+ str = str_new(0);
+ if (len > 0) {
+ str_cat(str,"return ");
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
+ str_free(fstr);
+ if (numarg)
+ subretnum = TRUE;
+ }
+ else
+ str_cat(str,"return");
+ break;
+ case OUSERFUN:
+ str = str_new(0);
+ str_set(str,"&");
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
+ str_free(fstr);
+ str_cat(str,"(");
+ tmpstr = hfetch(symtab,str->str_ptr+3);
+ if (tmpstr && tmpstr->str_ptr)
+ numeric |= atoi(tmpstr->str_ptr);
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
+ str_free(fstr);
+ str_cat(str,")");
+ break;
+ case OGSUB:
+ case OSUB:
+ if (type == OGSUB)
+ s = "g";
+ else
+ s = "";
+ str = str_new(0);
+ tmpstr = str_new(0);
+ i = 0;
+ if (len == 3) {
+ tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
+ if (strNE(tmpstr->str_ptr,"$_")) {
+ str_cat(tmpstr, " =~ s");
+ i++;
+ }
+ else
+ str_set(tmpstr, "s");
+ }
+ else
+ str_set(tmpstr, "s");
+ type = ops[ops[node+2].ival].ival;
+ len = type >> 8;
+ type &= 255;
+ tmp3str = str_new(0);
+ if (type == OSTR) {
+ tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
+ for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
+ if (*t == '&')
+ *d++ = '$' + 128;
+ else if (*t == '$')
+ *d++ = '\\' + 128;
+ *d = *t + 128;
+ }
+ *d = '\0';
+ str_set(tmp2str,tokenbuf);
+ }
+ else {
+ tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
+ str_set(tmp3str,"($s_ = '\"'.(");
+ str_scat(tmp3str,tmp2str);
+ str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
+ str_set(tmp2str,"eval $s_");
+ s = (*s == 'g' ? "ge" : "e");
+ i++;
+ }
+ type = ops[ops[node+1].ival].ival;
+ len = type >> 8;
+ type &= 255;
+ fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
+ if (type == OREGEX) {
+ if (useval && i)
+ str_cat(str,"(");
+ str_scat(str,tmp3str);
+ str_scat(str,tmpstr);
+ str_scat(str,fstr);
+ str_scat(str,tmp2str);
+ str_cat(str,"/");
+ str_cat(str,s);
+ }
+ else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
+ if (useval && i)
+ str_cat(str,"(");
+ str_scat(str,tmp3str);
+ str_scat(str,tmpstr);
+ str_cat(str,"/");
+ str_scat(str,fstr);
+ str_cat(str,"/");
+ str_scat(str,tmp2str);
+ str_cat(str,"/");
+ str_cat(str,s);
+ }
+ else {
+ i++;
+ if (useval)
+ str_cat(str,"(");
+ str_cat(str,"$s = ");
+ str_scat(str,fstr);
+ str_cat(str,", ");
+ str_scat(str,tmp3str);
+ str_scat(str,tmpstr);
+ str_cat(str,"/$s/");
+ str_scat(str,tmp2str);
+ str_cat(str,"/");
+ str_cat(str,s);
+ }
+ if (useval && i)
+ str_cat(str,")");
+ str_free(fstr);
+ str_free(tmpstr);
+ str_free(tmp2str);
+ str_free(tmp3str);
+ numeric = 1;
+ break;
case ONUM:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
numeric = 1;
break;
case OSTR:
- tmpstr = walk(1,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
s = "'";
for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
if (*t == '\'')
@@ -567,15 +921,34 @@ sub Pick {\n\
str_free(tmpstr);
str_cat(str,s);
break;
+ case ODEFINED:
+ prec = P_UNI;
+ str = str_new(0);
+ str_set(str,"defined $");
+ goto addvar;
+ case ODELETE:
+ str = str_new(0);
+ str_set(str,"delete $");
+ goto addvar;
+ case OSTAR:
+ str = str_new(0);
+ str_set(str,"*");
+ goto addvar;
case OVAR:
str = str_new(0);
str_set(str,"$");
- str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
+ addvar:
+ str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
if (len == 1) {
tmp2str = hfetch(symtab,tmpstr->str_ptr);
if (tmp2str && atoi(tmp2str->str_ptr))
numeric = 2;
- if (strEQ(str->str_ptr,"$NR")) {
+ if (strEQ(str->str_ptr,"$FNR")) {
+ numeric = 1;
+ saw_FNR++;
+ str_set(str,"($.-$FNRbase)");
+ }
+ else if (strEQ(str->str_ptr,"$NR")) {
numeric = 1;
str_set(str,"$.");
}
@@ -585,22 +958,37 @@ sub Pick {\n\
}
else if (strEQ(str->str_ptr,"$0"))
str_set(str,"$_");
+ else if (strEQ(str->str_ptr,"$ARGC"))
+ str_set(str,"($#ARGV+1)");
}
else {
+#ifdef NOTDEF
+ if (curargs) {
+ sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
+ ??? if (instr(curargs->str_ptr,tokenbuf))
+ str_cat(str,"\377"); /* can't translate yet */
+ }
+#endif
str_cat(tmpstr,"[]");
tmp2str = hfetch(symtab,tmpstr->str_ptr);
if (tmp2str && atoi(tmp2str->str_ptr))
str_cat(str,"[");
else
str_cat(str,"{");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
- if (tmp2str && atoi(tmp2str->str_ptr))
- strcpy(tokenbuf,"]");
- else
- strcpy(tokenbuf,"}");
- *tokenbuf += 128;
- str_cat(str,tokenbuf);
+ if (strEQ(str->str_ptr,"$ARGV[0")) {
+ str_set(str,"$ARGV0");
+ saw_argv0++;
+ }
+ else {
+ if (tmp2str && atoi(tmp2str->str_ptr))
+ strcpy(tokenbuf,"]");
+ else
+ strcpy(tokenbuf,"}");
+ *tokenbuf += 128;
+ str_cat(str,tokenbuf);
+ }
}
str_free(tmpstr);
break;
@@ -609,12 +997,12 @@ sub Pick {\n\
if (split_to_array) {
str_set(str,"$Fld");
str_cat(str,"[");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,"]");
}
else {
- i = atoi(walk(1,level,ops[node+1].ival,&numarg)->str_ptr);
+ i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
if (i <= arymax)
sprintf(tokenbuf,"$%s",nameary[i]);
else
@@ -628,7 +1016,7 @@ sub Pick {\n\
i = ops[node+1].ival;
if ((ops[i].ival & 255) == OPAREN)
i = ops[i+1].ival;
- tmpstr=walk(1,level,i,&numarg);
+ tmpstr=walk(1,level,i,&numarg,P_MIN);
str_scat(str,tmpstr);
str_free(tmpstr);
str_cat(str,"]");
@@ -648,7 +1036,7 @@ sub Pick {\n\
case OSCOMMENT:
str = str_new(0);
str_set(str,";");
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
*s += 128;
str_scat(str,tmpstr);
@@ -657,7 +1045,7 @@ sub Pick {\n\
break;
case OCOMMENT:
str = str_new(0);
- tmpstr = walk(0,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
*s += 128;
str_scat(str,tmpstr);
@@ -665,27 +1053,31 @@ sub Pick {\n\
tab(str,level);
break;
case OCOMMA:
- str = walk(1,level,ops[node+1].ival,&numarg);
+ prec = P_COMMA;
+ str = walk(1,level,ops[node+1].ival,&numarg,prec);
str_cat(str,", ");
- str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
+ str_free(fstr);
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
str_free(fstr);
break;
case OSEMICOLON:
str = str_new(1);
- str_set(str,"; ");
+ str_set(str,";\n");
+ tab(str,level);
break;
case OSTATES:
- str = walk(0,level,ops[node+1].ival,&numarg);
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
break;
case OSTATE:
str = str_new(0);
if (len >= 1) {
- str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
if (len >= 2) {
- tmpstr = walk(0,level,ops[node+2].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
if (*tmpstr->str_ptr == ';') {
addsemi(str);
str_cat(str,tmpstr->str_ptr+1);
@@ -694,14 +1086,43 @@ sub Pick {\n\
}
}
break;
+ case OCLOSE:
+ str = str_make("close(");
+ tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
+ if (!do_fancy_opens) {
+ t = tmpstr->str_ptr;
+ if (*t == '"' || *t == '\'')
+ t = cpytill(tokenbuf,t+1,*t);
+ else
+ fatal("Internal error: OCLOSE %s",t);
+ s = savestr(tokenbuf);
+ for (t = tokenbuf; *t; t++) {
+ *t &= 127;
+ if (!isalpha(*t) && !isdigit(*t))
+ *t = '_';
+ }
+ if (!index(tokenbuf,'_'))
+ strcpy(t,"_fh");
+ str_free(tmpstr);
+ safefree(s);
+ str_set(str,"close ");
+ str_cat(str,tokenbuf);
+ }
+ else {
+ sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
+ tmpstr->str_ptr);
+ str_free(tmpstr);
+ str_set(str,tokenbuf);
+ }
+ break;
case OPRINTF:
case OPRINT:
lparen = ""; /* set to parens if necessary */
rparen = "";
str = str_new(0);
if (len == 3) { /* output redirection */
- tmpstr = walk(1,level,ops[node+3].ival,&numarg);
- tmp2str = walk(1,level,ops[node+2].ival,&numarg);
+ tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
+ tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
if (!do_fancy_opens) {
t = tmpstr->str_ptr;
if (*t == '"' || *t == '\'')
@@ -717,34 +1138,38 @@ sub Pick {\n\
}
if (!index(tokenbuf,'_'))
strcpy(t,"_fh");
- str_cat(opens,"open(");
- str_cat(opens,tokenbuf);
- str_cat(opens,", ");
- d[1] = '\0';
- str_cat(opens,d);
- str_scat(opens,tmp2str);
- str_cat(opens,tmpstr->str_ptr+1);
- if (*tmp2str->str_ptr == '|')
- str_cat(opens,") || die 'Cannot pipe to \"");
- else
- str_cat(opens,") || die 'Cannot create file \"");
- if (*d == '"')
- str_cat(opens,"'.\"");
- str_cat(opens,s);
- if (*d == '"')
- str_cat(opens,"\".'");
- str_cat(opens,"\".';\n");
+ tmp3str = hfetch(symtab,tokenbuf);
+ if (!tmp3str) {
+ str_cat(opens,"open(");
+ str_cat(opens,tokenbuf);
+ str_cat(opens,", ");
+ d[1] = '\0';
+ str_cat(opens,d);
+ str_scat(opens,tmp2str);
+ str_cat(opens,tmpstr->str_ptr+1);
+ if (*tmp2str->str_ptr == '|')
+ str_cat(opens,") || die 'Cannot pipe to \"");
+ else
+ str_cat(opens,") || die 'Cannot create file \"");
+ if (*d == '"')
+ str_cat(opens,"'.\"");
+ str_cat(opens,s);
+ if (*d == '"')
+ str_cat(opens,"\".'");
+ str_cat(opens,"\".';\n");
+ hstore(symtab,tokenbuf,str_make("x"));
+ }
str_free(tmpstr);
str_free(tmp2str);
safefree(s);
safefree(d);
}
else {
- sprintf(tokenbuf,"do Pick('%s' . (%s)) &&\n",
+ sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
tmp2str->str_ptr, tmpstr->str_ptr);
str_cat(str,tokenbuf);
tab(str,level+1);
- *tokenbuf = '\0';
+ strcpy(tokenbuf,"$fh");
str_free(tmpstr);
str_free(tmp2str);
lparen = "(";
@@ -752,7 +1177,7 @@ sub Pick {\n\
}
}
else
- strcpy(tokenbuf,"stdout");
+ strcpy(tokenbuf,"");
str_cat(str,lparen); /* may be null */
if (type == OPRINTF)
str_cat(str,"printf");
@@ -763,7 +1188,7 @@ sub Pick {\n\
str_cat(str," ");
str_cat(str,tokenbuf);
}
- tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg);
+ tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
if (!*tmpstr->str_ptr && lval_field) {
t = saw_OFS ? "$," : "' '";
if (split_to_array) {
@@ -795,6 +1220,24 @@ sub Pick {\n\
str_cat(str,rparen); /* may be null */
str_free(tmpstr);
break;
+ case ORAND:
+ str = str_make("rand(1)");
+ break;
+ case OSRAND:
+ str = str_make("srand(");
+ goto maybe0;
+ case OATAN2:
+ str = str_make("atan2(");
+ goto maybe0;
+ case OSIN:
+ str = str_make("sin(");
+ goto maybe0;
+ case OCOS:
+ str = str_make("cos(");
+ goto maybe0;
+ case OSYSTEM:
+ str = str_make("system(");
+ goto maybe0;
case OLENGTH:
str = str_make("length(");
goto maybe0;
@@ -812,7 +1255,7 @@ sub Pick {\n\
maybe0:
numeric = 1;
if (len > 0)
- tmpstr = walk(1,level,ops[node+1].ival,&numarg);
+ tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
else
tmpstr = str_new(0);;
if (!*tmpstr->str_ptr) {
@@ -863,11 +1306,13 @@ sub Pick {\n\
case OEXIT:
str = str_new(0);
if (realexit) {
+ prec = P_UNI;
str_set(str,"exit");
if (len == 1) {
str_cat(str," ");
exitval = TRUE;
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,
+ fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
str_free(fstr);
}
}
@@ -875,7 +1320,8 @@ sub Pick {\n\
if (len == 1) {
str_set(str,"ExitValue = ");
exitval = TRUE;
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,
+ fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
str_free(fstr);
str_cat(str,"; ");
}
@@ -891,10 +1337,10 @@ sub Pick {\n\
case OIF:
str = str_new(0);
str_set(str,"if (");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,") ");
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
if (len == 3) {
i = ops[node+3].ival;
@@ -911,12 +1357,12 @@ sub Pick {\n\
}
if (i) {
str_cat(str,"els");
- str_scat(str,fstr=walk(0,level,i,&numarg));
+ str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
str_free(fstr);
}
else {
str_cat(str,"else ");
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
str_free(fstr);
}
}
@@ -924,16 +1370,16 @@ sub Pick {\n\
case OWHILE:
str = str_new(0);
str_set(str,"while (");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,") ");
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
break;
case OFOR:
str = str_new(0);
str_set(str,"for (");
- str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg));
+ str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
i = numarg;
if (i) {
t = s = tmpstr->str_ptr;
@@ -944,7 +1390,7 @@ sub Pick {\n\
i = 0;
}
str_cat(str,"; ");
- fstr=walk(1,level,ops[node+2].ival,&numarg);
+ fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
if (i && (t = index(fstr->str_ptr,0377))) {
if (strnEQ(fstr->str_ptr,s,i))
*t = ' ';
@@ -953,57 +1399,65 @@ sub Pick {\n\
str_free(fstr);
str_free(tmpstr);
str_cat(str,"; ");
- str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
str_free(fstr);
str_cat(str,") ");
- str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
str_free(fstr);
break;
case OFORIN:
- tmpstr=walk(0,level,ops[node+2].ival,&numarg);
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
+ d = index(tmpstr->str_ptr,'$');
+ if (!d)
+ fatal("Illegal for loop: %s",tmpstr->str_ptr);
+ s = index(d,'{');
+ if (!s)
+ s = index(d,'[');
+ if (!s)
+ fatal("Illegal for loop: %s",d);
+ *s++ = '\0';
+ t = index(s,'}' + 128);
+ if (!t)
+ t = index(s,']' + 128);
+ if (t)
+ *t = '\0';
str = str_new(0);
- str_sset(str,tmpstr);
+ str_set(str,d+1);
str_cat(str,"[]");
tmp2str = hfetch(symtab,str->str_ptr);
if (tmp2str && atoi(tmp2str->str_ptr)) {
- fstr=walk(1,level,ops[node+1].ival,&numarg);
sprintf(tokenbuf,
- "foreach $%s (@%s) ",
- fstr->str_ptr,
- tmpstr->str_ptr);
- str_set(str,tokenbuf);
- str_free(fstr);
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
- str_free(fstr);
+ "foreach %s (@%s) ",
+ s,
+ d+1);
}
else {
- str_set(str,"while (($");
- str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg));
- str_free(fstr);
- str_cat(str,",$junkval) = each(");
- str_scat(str,tmpstr);
- str_cat(str,")) ");
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
- str_free(fstr);
+ sprintf(tokenbuf,
+ "foreach %s (keys %%%s) ",
+ s,
+ d+1);
}
+ str_set(str,tokenbuf);
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
+ str_free(fstr);
str_free(tmpstr);
break;
case OBLOCK:
str = str_new(0);
str_set(str,"{");
if (len >= 2 && ops[node+2].ival) {
- str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
str_free(fstr);
}
fixtab(str,++level);
- str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
str_free(fstr);
addsemi(str);
fixtab(str,--level);
str_cat(str,"}\n");
tab(str,level);
if (len >= 3) {
- str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
str_free(fstr);
}
break;
@@ -1012,9 +1466,9 @@ sub Pick {\n\
if (len) {
if (len > 5)
fatal("Garbage length in walk");
- str = walk(0,level,ops[node+1].ival,&numarg);
+ str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
for (i = 2; i<= len; i++) {
- str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg));
+ str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
str_free(fstr);
}
}
@@ -1025,6 +1479,16 @@ sub Pick {\n\
}
if (!str)
str = str_new(0);
+
+ if (useval && prec < minprec) { /* need parens? */
+ fstr = str_new(str->str_cur+2);
+ str_nset(fstr,"(",1);
+ str_scat(fstr,str);
+ str_ncat(fstr,")",1);
+ str_free(str);
+ str = fstr;
+ }
+
*numericptr = numeric;
#ifdef DEBUGGING
if (debug & 4) {
@@ -1063,7 +1527,7 @@ register int lvl;
/* strip trailing white space */
s = str->str_ptr+str->str_cur - 1;
- while (s >= str->str_ptr && (*s == ' ' || *s == '\t'))
+ while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
s--;
s[1] = '\0';
str->str_cur = s + 1 - str->str_ptr;
@@ -1109,13 +1573,13 @@ int level;
str_cat(str,tokenbuf);
}
if (const_FS) {
- sprintf(tokenbuf," = split(/[%c\\n]/);\n",const_FS);
+ sprintf(tokenbuf," = split(/[%c\\n]/, $_, 999);\n",const_FS);
str_cat(str,tokenbuf);
}
else if (saw_FS)
- str_cat(str," = split($FS);\n");
+ str_cat(str," = split($FS, $_, 999);\n");
else
- str_cat(str," = split(' ');\n");
+ str_cat(str," = split(' ', $_, 999);\n");
tab(str,level);
}
@@ -1132,6 +1596,8 @@ int *numericptr;
char *d, *s;
int numarg;
int numeric = FALSE;
+ STR *tmpstr;
+ STR *tmp2str;
if (!node) {
*numericptr = 0;
@@ -1259,7 +1725,7 @@ int *numericptr;
prewalk(1,level,ops[node+2].ival,&numarg);
numeric = 1;
break;
- case OSUB:
+ case OSUBTRACT:
prewalk(1,level,ops[node+1].ival,&numarg);
prewalk(1,level,ops[node+2].ival,&numarg);
numeric = 1;
@@ -1274,6 +1740,11 @@ int *numericptr;
prewalk(1,level,ops[node+2].ival,&numarg);
numeric = 1;
break;
+ case OPOW:
+ prewalk(1,level,ops[node+1].ival,&numarg);
+ prewalk(1,level,ops[node+2].ival,&numarg);
+ numeric = 1;
+ break;
case OMOD:
prewalk(1,level,ops[node+1].ival,&numarg);
prewalk(1,level,ops[node+2].ival,&numarg);
@@ -1333,6 +1804,55 @@ int *numericptr;
prewalk(0,level,ops[node+2].ival,&numarg);
numeric = 1;
break;
+ case OMATCH:
+ prewalk(0,level,ops[node+1].ival,&numarg);
+ prewalk(0,level,ops[node+2].ival,&numarg);
+ numeric = 1;
+ break;
+ case OUSERDEF:
+ subretnum = FALSE;
+ --level;
+ tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
+ ++level;
+ prewalk(0,level,ops[node+2].ival,&numarg);
+ prewalk(0,level,ops[node+4].ival,&numarg);
+ prewalk(0,level,ops[node+5].ival,&numarg);
+ --level;
+ str_cat(tmpstr,"(");
+ tmp2str = str_new(0);
+ if (subretnum || numarg)
+ str_set(tmp2str,"1");
+ hstore(symtab,tmpstr->str_ptr,tmp2str);
+ str_free(tmpstr);
+ level++;
+ break;
+ case ORETURN:
+ if (len > 0) {
+ prewalk(0,level,ops[node+1].ival,&numarg);
+ if (numarg)
+ subretnum = TRUE;
+ }
+ break;
+ case OUSERFUN:
+ tmp2str = str_new(0);
+ str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
+ fixrargs(tmpstr->str_ptr,ops[node+2],0);
+ str_free(tmpstr);
+ str_cat(tmp2str,"(");
+ tmpstr = hfetch(symtab,tmp2str->str_ptr);
+ if (tmpstr && tmpstr->str_ptr)
+ numeric |= atoi(tmpstr->str_ptr);
+ prewalk(0,level,ops[node+2].ival,&numarg);
+ str_free(tmp2str);
+ break;
+ case OGSUB:
+ case OSUB:
+ if (len >= 3)
+ prewalk(0,level,ops[node+3].ival,&numarg);
+ prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
+ prewalk(0,level,ops[node+1].ival,&numarg);
+ numeric = 1;
+ break;
case ONUM:
prewalk(0,level,ops[node+1].ival,&numarg);
numeric = 1;
@@ -1340,6 +1860,9 @@ int *numericptr;
case OSTR:
prewalk(0,level,ops[node+1].ival,&numarg);
break;
+ case ODEFINED:
+ case ODELETE:
+ case OSTAR:
case OVAR:
prewalk(0,level,ops[node+1].ival,&numarg);
if (len == 1) {
@@ -1370,6 +1893,7 @@ int *numericptr;
case OCOMMA:
prewalk(0,level,ops[node+1].ival,&numarg);
prewalk(0,level,ops[node+2].ival,&numarg);
+ prewalk(0,level,ops[node+3].ival,&numarg);
break;
case OSEMICOLON:
break;
@@ -1385,6 +1909,9 @@ int *numericptr;
}
}
break;
+ case OCLOSE:
+ prewalk(0,level,ops[node+1].ival,&numarg);
+ break;
case OPRINTF:
case OPRINT:
if (len == 3) { /* output redirection */
@@ -1393,6 +1920,18 @@ int *numericptr;
}
prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
break;
+ case ORAND:
+ break;
+ case OSRAND:
+ goto maybe0;
+ case OATAN2:
+ goto maybe0;
+ case OSIN:
+ goto maybe0;
+ case OCOS:
+ goto maybe0;
+ case OSYSTEM:
+ goto maybe0;
case OLENGTH:
goto maybe0;
case OLOG:
@@ -1405,7 +1944,8 @@ int *numericptr;
maybe0:
numeric = 1;
if (len > 0)
- prewalk(type != OLENGTH,level,ops[node+1].ival,&numarg);
+ prewalk(type != OLENGTH && type != OSYSTEM,
+ level,ops[node+1].ival,&numarg);
break;
case OBREAK:
break;
@@ -1440,7 +1980,6 @@ int *numericptr;
case OFORIN:
prewalk(0,level,ops[node+2].ival,&numarg);
prewalk(0,level,ops[node+1].ival,&numarg);
- prewalk(0,level,ops[node+3].ival,&numarg);
break;
case OBLOCK:
if (len == 2) {
@@ -1480,7 +2019,7 @@ register int node;
len = type >> 8;
type &= 255;
if (type == OVAR && len == 1) {
- tmpstr=walk(0,0,ops[node+1].ival,&numarg);
+ tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
tmp2str = str_make("1");
hstore(symtab,tmpstr->str_ptr,tmp2str);
}