zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: 4.1: multi-parameter for loop
@ 2001-06-20 14:45 Peter Stephenson
  2001-06-20 16:11 ` Peter Stephenson
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Peter Stephenson @ 2001-06-20 14:45 UTC (permalink / raw)
  To: Zsh hackers list

This is meddling with things one probably shouldn't touch, unless one's
working on a particularly annoying and sporadic bug in something else.

This extends the for syntax to take multiple parameters after it; they take
multiple words from the argument list.  The main intended use of this is
for imitating perl's `each' feature:

  typeset -A assoc
  assoc=(key1 val1 key2 val2)
  for key value in ${(kv)assoc}; do
    print $key $value
  done

prints
  
  key1 val1
  key2 val2

(though ordering of elements isn't guaranteed, of course).

My main worry is that the wordcode stuff is as clear as mud to me.  In
particular, I don't know what WC_FOR_SKIP is doing, why it divides the data
size(?) by 4, and whether it needs changing when there's more stuff in
the for structure.

I probably won't be committing this for a while, if at all.  All tests
still pass, though.

Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.4
diff -u -r1.4 loop.c
--- Src/loop.c	2000/06/17 17:05:53	1.4
+++ Src/loop.c	2001/06/20 14:34:48
@@ -52,15 +52,15 @@
     Wordcode end, loop;
     wordcode code = state->pc[-1];
     int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
+    int last = 0;
     char *name, *str, *cond = NULL, *advance = NULL;
     zlong val = 0;
-    LinkList args = NULL;
+    LinkList vars = NULL, args = NULL;
 
-    name = ecgetstr(state, EC_NODUP, NULL);
     end = state->pc + WC_FOR_SKIP(code);
 
     if (iscond) {
-	str = dupstring(name);
+	str = dupstring(ecgetstr(state, EC_NODUP, NULL));
 	singsub(&str);
 	if (isset(XTRACE)) {
 	    char *str2 = dupstring(str);
@@ -77,28 +77,32 @@
 	}
 	cond = ecgetstr(state, EC_NODUP, &ctok);
 	advance = ecgetstr(state, EC_NODUP, &atok);
-    } else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
-	int htok = 0;
-
-	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
-	    state->pc = end;
-	    return 0;
-	}
-	if (htok)
-	    execsubst(args);
     } else {
-	char **x;
+	vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);
+
+	if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
+	    int htok = 0;
+
+	    if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
+		state->pc = end;
+		return 0;
+	    }
+	    if (htok)
+		execsubst(args);
+	} else {
+	    char **x;
 
-	args = newlinklist();
-	for (x = pparams; *x; x++)
-	    addlinknode(args, dupstring(*x));
+	    args = newlinklist();
+	    for (x = pparams; *x; x++)
+		addlinknode(args, dupstring(*x));
+	}
     }
     lastval = 0;
     loops++;
     pushheap();
     cmdpush(CS_FOR);
     loop = state->pc;
-    for (;;) {
+    while (!last) {
 	if (iscond) {
 	    if (ctok) {
 		str = dupstring(cond);
@@ -127,14 +131,29 @@
 	    if (!val)
 		break;
 	} else {
-	    if (!args || !(str = (char *) ugetnode(args)))
-		break;
-	    if (isset(XTRACE)) {
-		printprompt4();
-		fprintf(xtrerr, "%s=%s\n", name, str);
-		fflush(xtrerr);
+	    LinkNode node;
+	    int count = 0;
+	    for (node = firstnode(vars); node; incnode(node))
+	    {
+		name = (char *)getdata(node);
+		if (!args || !(str = (char *) ugetnode(args)))
+		{
+		    if (count) { 
+			str = "";
+			last = 1;
+		    } else
+			break;
+		}
+		if (isset(XTRACE)) {
+		    printprompt4();
+		    fprintf(xtrerr, "%s=%s\n", name, str);
+		    fflush(xtrerr);
+		}
+		setsparam(name, ztrdup(str));
+		count++;
 	    }
-	    setsparam(name, ztrdup(str));
+	    if (!count)
+		break;
 	}
 	state->pc = loop;
 	execlist(state, 1, do_exec && args && empty(args));
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.23
diff -u -r1.23 parse.c
--- Src/parse.c	2001/06/18 07:34:34	1.23
+++ Src/parse.c	2001/06/20 14:34:49
@@ -903,15 +903,25 @@
 	yylex();
 	type = WC_FOR_COND;
     } else {
+	int np, n, isin = 0;
 	infor = 0;
 	if (tok != STRING || !isident(tokstr))
 	    YYERRORV(oecused);
-	ecstr(tokstr);
+	np = ecadd(0);
+	n = 0;
 	incmdpos = 1;
-	yylex();
-	if (tok == STRING && !strcmp(tokstr, "in")) {
-	    int np, n;
+	for (;;) {
+	    n++;
+	    ecstr(tokstr);
+	    yylex();	
+	    if (tok != STRING || (isin = !strcmp(tokstr, "in")) || sel)
+		break;
+	    if (!isident(tokstr))
+		YYERRORV(oecused);
+	}
+	ecbuf[np] = n;
 
+	if (isin) {
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
@@ -921,8 +931,6 @@
 	    ecbuf[np] = n;
 	    type = (sel ? WC_SELECT_LIST : WC_FOR_LIST);
 	} else if (tok == INPAR) {
-	    int np, n;
-
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
Index: Doc/Zsh/grammar.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/grammar.yo,v
retrieving revision 1.4
diff -u -r1.4 grammar.yo
--- Doc/Zsh/grammar.yo	2000/08/29 06:35:40	1.4
+++ Doc/Zsh/grammar.yo	2001/06/20 14:34:49
@@ -149,12 +149,20 @@
 findex(for)
 cindex(for loops)
 cindex(loops, for)
-item(tt(for) var(name) [ tt(in) var(word) ... var(term) ] tt(do) var(list) tt(done))(
+item(tt(for) var(name) ... [ tt(in) var(word) ... ] var(term) tt(do) var(list) tt(done))(
 where var(term) is at least one newline or tt(;).
 Expand the list of var(word)s, and set the parameter
 var(name) to each of them in turn, executing
 var(list) each time.  If the tt(in) var(word) is omitted,
 use the positional parameters instead of the var(word)s.
+
+More than one parameter var(name) can appear before the list of
+var(word)s.  If var(N) var(name)s are given, then on each execution of the
+loop the next tt(N) var(word)s are assigned to the corresponding
+parameters.  If there are more var(name)s than remaining var(word)s, the
+remaining parameters are each set to the empty string.  Execution of the
+loop ends when there is no remaining var(word) to assign to the first
+var(name).
 )
 item(tt(for LPAR()LPAR()) [var(expr1)] tt(;) [var(expr2)] tt(;) [var(expr3)] tt(RPAR()RPAR() do) var(list) tt(done))(
 The arithmetic expression var(expr1) is evaluated first (see

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 14:45 PATCH: 4.1: multi-parameter for loop Peter Stephenson
@ 2001-06-20 16:11 ` Peter Stephenson
  2001-06-20 18:01 ` Andrej Borsenkow
  2001-06-21  8:33 ` Sven Wischnowsky
  2 siblings, 0 replies; 18+ messages in thread
From: Peter Stephenson @ 2001-06-20 16:11 UTC (permalink / raw)
  To: Zsh hackers list

Peter Stephenson wrote:
> This extends the for syntax to take multiple parameters after it; they take
> multiple words from the argument list.

Sorry, I didn't send the text.c chunk, without which this will crash
horribly.  Here's the complete thing.

Index: Doc/Zsh/grammar.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/grammar.yo,v
retrieving revision 1.4
diff -u -r1.4 grammar.yo
--- Doc/Zsh/grammar.yo	2000/08/29 06:35:40	1.4
+++ Doc/Zsh/grammar.yo	2001/06/20 16:09:33
@@ -149,12 +149,20 @@
 findex(for)
 cindex(for loops)
 cindex(loops, for)
-item(tt(for) var(name) [ tt(in) var(word) ... var(term) ] tt(do) var(list) tt(done))(
+item(tt(for) var(name) ... [ tt(in) var(word) ... ] var(term) tt(do) var(list) tt(done))(
 where var(term) is at least one newline or tt(;).
 Expand the list of var(word)s, and set the parameter
 var(name) to each of them in turn, executing
 var(list) each time.  If the tt(in) var(word) is omitted,
 use the positional parameters instead of the var(word)s.
+
+More than one parameter var(name) can appear before the list of
+var(word)s.  If var(N) var(name)s are given, then on each execution of the
+loop the next tt(N) var(word)s are assigned to the corresponding
+parameters.  If there are more var(name)s than remaining var(word)s, the
+remaining parameters are each set to the empty string.  Execution of the
+loop ends when there is no remaining var(word) to assign to the first
+var(name).
 )
 item(tt(for LPAR()LPAR()) [var(expr1)] tt(;) [var(expr2)] tt(;) [var(expr3)] tt(RPAR()RPAR() do) var(list) tt(done))(
 The arithmetic expression var(expr1) is evaluated first (see
Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.4
diff -u -r1.4 loop.c
--- Src/loop.c	2000/06/17 17:05:53	1.4
+++ Src/loop.c	2001/06/20 16:09:33
@@ -52,15 +52,15 @@
     Wordcode end, loop;
     wordcode code = state->pc[-1];
     int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
+    int last = 0;
     char *name, *str, *cond = NULL, *advance = NULL;
     zlong val = 0;
-    LinkList args = NULL;
+    LinkList vars = NULL, args = NULL;
 
-    name = ecgetstr(state, EC_NODUP, NULL);
     end = state->pc + WC_FOR_SKIP(code);
 
     if (iscond) {
-	str = dupstring(name);
+	str = dupstring(ecgetstr(state, EC_NODUP, NULL));
 	singsub(&str);
 	if (isset(XTRACE)) {
 	    char *str2 = dupstring(str);
@@ -77,28 +77,32 @@
 	}
 	cond = ecgetstr(state, EC_NODUP, &ctok);
 	advance = ecgetstr(state, EC_NODUP, &atok);
-    } else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
-	int htok = 0;
-
-	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
-	    state->pc = end;
-	    return 0;
-	}
-	if (htok)
-	    execsubst(args);
     } else {
-	char **x;
+	vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);
+
+	if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
+	    int htok = 0;
+
+	    if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
+		state->pc = end;
+		return 0;
+	    }
+	    if (htok)
+		execsubst(args);
+	} else {
+	    char **x;
 
-	args = newlinklist();
-	for (x = pparams; *x; x++)
-	    addlinknode(args, dupstring(*x));
+	    args = newlinklist();
+	    for (x = pparams; *x; x++)
+		addlinknode(args, dupstring(*x));
+	}
     }
     lastval = 0;
     loops++;
     pushheap();
     cmdpush(CS_FOR);
     loop = state->pc;
-    for (;;) {
+    while (!last) {
 	if (iscond) {
 	    if (ctok) {
 		str = dupstring(cond);
@@ -127,14 +131,29 @@
 	    if (!val)
 		break;
 	} else {
-	    if (!args || !(str = (char *) ugetnode(args)))
-		break;
-	    if (isset(XTRACE)) {
-		printprompt4();
-		fprintf(xtrerr, "%s=%s\n", name, str);
-		fflush(xtrerr);
+	    LinkNode node;
+	    int count = 0;
+	    for (node = firstnode(vars); node; incnode(node))
+	    {
+		name = (char *)getdata(node);
+		if (!args || !(str = (char *) ugetnode(args)))
+		{
+		    if (count) { 
+			str = "";
+			last = 1;
+		    } else
+			break;
+		}
+		if (isset(XTRACE)) {
+		    printprompt4();
+		    fprintf(xtrerr, "%s=%s\n", name, str);
+		    fflush(xtrerr);
+		}
+		setsparam(name, ztrdup(str));
+		count++;
 	    }
-	    setsparam(name, ztrdup(str));
+	    if (!count)
+		break;
 	}
 	state->pc = loop;
 	execlist(state, 1, do_exec && args && empty(args));
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.23
diff -u -r1.23 parse.c
--- Src/parse.c	2001/06/18 07:34:34	1.23
+++ Src/parse.c	2001/06/20 16:09:34
@@ -903,15 +903,25 @@
 	yylex();
 	type = WC_FOR_COND;
     } else {
+	int np, n, isin = 0;
 	infor = 0;
 	if (tok != STRING || !isident(tokstr))
 	    YYERRORV(oecused);
-	ecstr(tokstr);
+	np = ecadd(0);
+	n = 0;
 	incmdpos = 1;
-	yylex();
-	if (tok == STRING && !strcmp(tokstr, "in")) {
-	    int np, n;
+	for (;;) {
+	    n++;
+	    ecstr(tokstr);
+	    yylex();	
+	    if (tok != STRING || (isin = !strcmp(tokstr, "in")) || sel)
+		break;
+	    if (!isident(tokstr))
+		YYERRORV(oecused);
+	}
+	ecbuf[np] = n;
 
+	if (isin) {
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
@@ -921,8 +931,6 @@
 	    ecbuf[np] = n;
 	    type = (sel ? WC_SELECT_LIST : WC_FOR_LIST);
 	} else if (tok == INPAR) {
-	    int np, n;
-
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
Index: Src/text.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/text.c,v
retrieving revision 1.5
diff -u -r1.5 text.c
--- Src/text.c	2000/12/05 10:34:23	1.5
+++ Src/text.c	2001/06/20 16:09:34
@@ -415,7 +415,7 @@
 		    taddstr(ecgetstr(state, EC_NODUP, NULL));
 		    taddstr(")) do");
 		} else {
-		    taddstr(ecgetstr(state, EC_NODUP, NULL));
+		    taddlist(state, *state->pc++);
 		    if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
 			taddstr(" in ");
 			taddlist(state, *state->pc++);

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 14:45 PATCH: 4.1: multi-parameter for loop Peter Stephenson
  2001-06-20 16:11 ` Peter Stephenson
@ 2001-06-20 18:01 ` Andrej Borsenkow
  2001-06-20 18:20   ` Bart Schaefer
  2001-06-21  8:33 ` Sven Wischnowsky
  2 siblings, 1 reply; 18+ messages in thread
From: Andrej Borsenkow @ 2001-06-20 18:01 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

On Wed, 20 Jun 2001, Peter Stephenson wrote:

>
> This extends the for syntax to take multiple parameters after it; they take
> multiple words from the argument list.  The main intended use of this is
> for imitating perl's `each' feature:
>
>   typeset -A assoc
>   assoc=(key1 val1 key2 val2)
>   for key value in ${(kv)assoc}; do
>     print $key $value
>   done
>

This for sure is incompatible with POSIX and all known shells. It does
not make legal scripts fail, but it makes illegal scripts legal. Should we
care about it?

-andrej


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 18:01 ` Andrej Borsenkow
@ 2001-06-20 18:20   ` Bart Schaefer
  2001-06-20 18:39     ` Peter Stephenson
  0 siblings, 1 reply; 18+ messages in thread
From: Bart Schaefer @ 2001-06-20 18:20 UTC (permalink / raw)
  To: Andrej Borsenkow; +Cc: Zsh hackers list

On Jun 20, 10:01pm, Andrej Borsenkow wrote:
} Subject: Re: PATCH: 4.1: multi-parameter for loop
}
} On Wed, 20 Jun 2001, Peter Stephenson wrote:
} 
} > This extends the for syntax to take multiple parameters after it
} 
} This for sure is incompatible with POSIX and all known shells. It
} does not make legal scripts fail, but it makes illegal scripts legal.
} Should we care about it?

In general we've taken the position that this is OK.  Consider the
"foreach" form, or "if [[ test ]] { command }", etc.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 18:20   ` Bart Schaefer
@ 2001-06-20 18:39     ` Peter Stephenson
  2001-06-20 18:55       ` Bart Schaefer
  0 siblings, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2001-06-20 18:39 UTC (permalink / raw)
  To: Zsh hackers list

"Bart Schaefer" wrote:
> On Jun 20, 10:01pm, Andrej Borsenkow wrote:
> } Subject: Re: PATCH: 4.1: multi-parameter for loop
> }
> } On Wed, 20 Jun 2001, Peter Stephenson wrote:
> } 
> } > This extends the for syntax to take multiple parameters after it
> } 
> } This for sure is incompatible with POSIX and all known shells. It
> } does not make legal scripts fail, but it makes illegal scripts legal.
> } Should we care about it?
> 
> In general we've taken the position that this is OK.  Consider the
> "foreach" form, or "if [[ test ]] { command }", etc.

I've always considered the shell is already riddled with this sort of
extension.  I much more concerned that there's some valid POSIXy case I've
missed that this screws up.  I'm perfectly happy to attach it to some
relevant option, but I don't think there is a good one; NO_KSH_ARRAYS would
be very marginal, probably too unexpected.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 18:39     ` Peter Stephenson
@ 2001-06-20 18:55       ` Bart Schaefer
  2001-06-20 19:12         ` Peter Stephenson
  2001-06-22 23:49         ` PATCH: 4.1: multi-parameter for loop Zefram
  0 siblings, 2 replies; 18+ messages in thread
From: Bart Schaefer @ 2001-06-20 18:55 UTC (permalink / raw)
  To: Peter Stephenson, Zsh hackers list

On Jun 20,  7:39pm, Peter Stephenson wrote:
} Subject: Re: PATCH: 4.1: multi-parameter for loop
}
} I much more concerned that there's some valid POSIXy case I've missed
} that this screws up.

Well, there's this:

	for in in in in; do echo $in; done

I haven't applied your patch yet, so I don't know whether it fouls up
the above, but clearly a parameter named "in" can only appear in the first
position, and everything else has to be taken as a keyword first and only
a parameter name otherwise.

} I'm perfectly happy to attach it to some
} relevant option, but I don't think there is a good one;

What if you attached it to the "foreach" keyword, but not "for"?  So then
one would have to write

	foreach x y z (p d q) ...

Just a thought.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 18:55       ` Bart Schaefer
@ 2001-06-20 19:12         ` Peter Stephenson
  2001-06-20 22:56           ` Danek Duvall
  2001-06-22 23:49         ` PATCH: 4.1: multi-parameter for loop Zefram
  1 sibling, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2001-06-20 19:12 UTC (permalink / raw)
  To: Zsh hackers list

"Bart Schaefer" wrote:
> Well, there's this:
> 
> 	for in in in in; do echo $in; done
> 
> I haven't applied your patch yet, so I don't know whether it fouls up
> the above, but clearly a parameter named "in" can only appear in the first
> position, and everything else has to be taken as a keyword first and only
> a parameter name otherwise.

It will stop reading parameters when it reaches the second `in'.  I meant
to document this, although it should be pretty obvious.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 19:12         ` Peter Stephenson
@ 2001-06-20 22:56           ` Danek Duvall
  2001-06-21  7:19             ` Andrej Borsenkow
  0 siblings, 1 reply; 18+ messages in thread
From: Danek Duvall @ 2001-06-20 22:56 UTC (permalink / raw)
  To: Zsh hackers list

On Wed, Jun 20, 2001 at 08:12:09PM +0100, Peter Stephenson wrote:

> "Bart Schaefer" wrote:
> > Well, there's this:
> > 
> > 	for in in in in; do echo $in; done
> 
> It will stop reading parameters when it reaches the second `in'.  I meant
> to document this, although it should be pretty obvious.

Right.  That lacks ambiguity because multiple distinct parameters can't
have the same name.  But that ambiguity is missing in

    for i in in in; do ....

Do you set $i to "in" and "in" or do you set $i and $in set to "in" and ""?
Posix presumably would simply use the first interpretation, and if you want
something like the second, just don't use a parameter named in?  Or am I
missing the disambiguation?

Danek


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: PATCH: 4.1: multi-parameter for loop
  2001-06-20 22:56           ` Danek Duvall
@ 2001-06-21  7:19             ` Andrej Borsenkow
  2001-06-21  9:52               ` Peter Stephenson
  2001-06-21  9:55               ` PATCH: POSIX " Bart Schaefer
  0 siblings, 2 replies; 18+ messages in thread
From: Andrej Borsenkow @ 2001-06-21  7:19 UTC (permalink / raw)
  To: Danek Duvall, Zsh hackers list



>
> On Wed, Jun 20, 2001 at 08:12:09PM +0100, Peter Stephenson wrote:
>
> > "Bart Schaefer" wrote:
> > > Well, there's this:
> > >
> > > 	for in in in in; do echo $in; done
> >
> > It will stop reading parameters when it reaches the second
> `in'.  I meant
> > to document this, although it should be pretty obvious.
>
> Right.  That lacks ambiguity because multiple distinct parameters can't
> have the same name.  But that ambiguity is missing in
>
>     for i in in in; do ....
>
> Do you set $i to "in" and "in" or do you set $i and $in set to
> "in" and ""?

Which opens up a question of odd number of list elements. It is invalid in
assignment to hash - shuld it be invalid here as well?

> Posix presumably would simply use the first interpretation,

Yes. Here are grammar rules:

for_clause       : For name linebreak                            do_group
                 | For name linebreak in wordlist sequential_sep do_group
name             : NAME                     /* Apply rule 5 */
                 ;
in               : In                       /* Apply rule 6 */

5. [NAME in for]
When the TOKEN meets the requirements for a name (see name in the XBD
specification, Glossary  ), the token identifier NAME will result.
Otherwise, the token WORD will be returned.

6. [Third word of for and case]
When the TOKEN is exactly the reserved word In, the token identifier for In
will result. Otherwise, the token WORD will be returned. (As indicated in
the grammar, a linebreak precedes the token In. If newline characters are
present at the indicated location, it is the token after them that is
treated in this fashion.)

Note linebreak here. Definition is:

linebreak        : newline_list
                 | /* empty */
                 ;

It means, that the following is valid:

fot i
in a b c
do
...

it is currently does not work in zsh:

bor@itsrm2% for i
for> in a b c
bor@itsrm2%
^^^^^^^^^^^^^^^ Oops!

as opposed to sh:

$ for i
> in a b c
> do
> echo $i
> done
a
b
c

 and
> if you want
> something like the second, just don't use a parameter named in?  Or am I
> missing the disambiguation?
>

I guess, Bart suggestion (use foreach) is better. And more Perlish :-)

Is there any feasible way to do something like

foreach key val hash

or even

foreach val array

i.e. do *not* expand $hash/%array value? For large arrays it may result in
significant speedup.

-andrej


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 14:45 PATCH: 4.1: multi-parameter for loop Peter Stephenson
  2001-06-20 16:11 ` Peter Stephenson
  2001-06-20 18:01 ` Andrej Borsenkow
@ 2001-06-21  8:33 ` Sven Wischnowsky
  2 siblings, 0 replies; 18+ messages in thread
From: Sven Wischnowsky @ 2001-06-21  8:33 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson wrote:

> ...
> 
> My main worry is that the wordcode stuff is as clear as mud to me.  In
> particular, I don't know what WC_FOR_SKIP is doing, why it divides the data
> size(?) by 4, and whether it needs changing when there's more stuff in
> the for structure.

>From zsh.h:

  #define WC_FOR_TYPE(C)      (wc_data(C) & 3)
  #define WC_FOR_PPARAM       0
  #define WC_FOR_LIST         1
  #define WC_FOR_COND         2
  #define WC_FOR_SKIP(C)      (wc_data(C) >> 2)
  #define WCB_FOR(T,O)        wc_bld(WC_FOR, ((T) | ((O) << 2)))


For for-loops the data field contains 1) the type of the loop
(positional params, a list of values or a condition) and 2) the offset
to the code after the loop.  The type is stored in the lowest two bits,
the offset is the rest, hence the `>> 2' to get the offset.

And since par_for() calculates the offset at the very end, it already
takes into account your parameter list.


I'd like to have something like this *a lot*.  I've missed it several
times already, I just didn't think of enhancing the for loop syntax.
I don't have any strong feelings pro or contra one of the suggested
syntaxes.  Similar like Bart's `foreach' suggestion, one could also use
`for (a b) in ...' to make this `save', trying to make it look like one
of these tuple assignments that are possible in some languages.  Of
course, people could then come and think that `(a b)=(1 2)' should work,
too.


Bye
  Sven


-- 
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-21  7:19             ` Andrej Borsenkow
@ 2001-06-21  9:52               ` Peter Stephenson
  2001-06-21 10:34                 ` PATCH (redux): POSIX `for' syntax Bart Schaefer
  2001-06-21  9:55               ` PATCH: POSIX " Bart Schaefer
  1 sibling, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2001-06-21  9:52 UTC (permalink / raw)
  To: Zsh hackers list

"Andrej Borsenkow" wrote:
> Which opens up a question of odd number of list elements. It is invalid in
> assignment to hash - shuld it be invalid here as well?

This is covered in the manual page.

  for p1 p2 in foo bar something else rubbish; do
    print $p1 $p2
  done

prints (I cut and pasted this from actually trying it out):

  foo bar
  something else
  rubbish

and you get an empty string for the final $p2.  I didn't thing there was
any point in doing too many sums --- particularly since you can use more
than two parameters; here's a way of naming a set of function arguments:

  fn() {
    local nam cmd val dsc
    for nam cmd val dsc; do; break; done;

    print "$nam, $cmd, $val, $dsc"
  }

Then `fn Me nothing none dunno' prints `Me, nothing, none, dunno'.

With regard to `in', the standard interpretation is the one taken in all
the suggestions I've seen so far.  I should make this clear in the manual,
though.

> bor@itsrm2% for i
> for> in a b c
> bor@itsrm2%
> ^^^^^^^^^^^^^^^ Oops!

That shouldn't be too hard to fix, and wouldn't affect the new syntax:  we
just terminate the argument list at the end of the first line.  Currently
it thinks the newline means you're not going to give an `in' and are using
positional parameters.  I don't know why there's no syntax error, though,
but you get one if you set NO_SHORT_LOOPS.

> I guess, Bart suggestion (use foreach) is better. And more Perlish :-)

I'm not so convinced, since `for' and `foreach' currently do the same
thing, and I don't really like dividing the syntax to make people use the
non-standard variant just for one use.  foreach is automatically handled at
the moment, as well as for, by the way.

> foreach key val hash
> 
> or even
> 
> foreach val array
> 
> i.e. do *not* expand $hash/%array value? For large arrays it may result in
> significant speedup.

It's possible, but actually not that effective for hashes, since to iterate
through them they have to be flattened, and that only happens once in the
current system anyway.

By the way, I discovered a problem:  alias expansion is turned on for
parameter names after the first;

  alias h='history -f'
  for g h in foo bar; do; done

turns `h' into `history -f' and the -f causes an unexpected parse error.
This is because of the csh-style syntax --- the shell is looking for a `('
which it needs to parse as a single token, so it uses the parsing rules for
command position.  But now I know about it I can turn alias expansion off
explicitly for that bit.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* PATCH: POSIX `for' syntax
  2001-06-21  7:19             ` Andrej Borsenkow
  2001-06-21  9:52               ` Peter Stephenson
@ 2001-06-21  9:55               ` Bart Schaefer
  2001-06-22  6:29                 ` PATCH: test case for " Andrej Borsenkow
  1 sibling, 1 reply; 18+ messages in thread
From: Bart Schaefer @ 2001-06-21  9:55 UTC (permalink / raw)
  To: Zsh hackers list

On Jun 21, 11:19am, Andrej Borsenkow wrote:
}
} for_clause       : For name linebreak                            do_group
}                  | For name linebreak in wordlist sequential_sep do_group
} name             : NAME                     /* Apply rule 5 */
}                  ;
} in               : In                       /* Apply rule 6 */
} 
} It means, that the following is valid:
} 
} fot i
} in a b c
} do
} ...
} 
} it is currently does not work in zsh:
} 
} bor@itsrm2% for i
} for> in a b c
} bor@itsrm2%
} ^^^^^^^^^^^^^^^ Oops!

The following patch (which almost certainly conflicts with Peter's)
makes zsh accept any number of newlines preceding the "in" token.  This
also applies to `select', which I presumed it ought to.

--- zsh-forge/current/Src/parse.c	Mon Jun 18 01:05:17 2001
+++ zsh-4.0/Src/parse.c	Thu Jun 21 02:45:23 2001
@@ -909,6 +909,8 @@
 	ecstr(tokstr);
 	incmdpos = 1;
 	yylex();
+	while (isnewlin && !csh)
+	  yylex();
 	if (tok == STRING && !strcmp(tokstr, "in")) {
 	    int np, n;
 

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 18+ messages in thread

* PATCH (redux): POSIX `for' syntax
  2001-06-21  9:52               ` Peter Stephenson
@ 2001-06-21 10:34                 ` Bart Schaefer
  2001-06-21 15:31                   ` PATCH (redux): non-POSIX " Peter Stephenson
  0 siblings, 1 reply; 18+ messages in thread
From: Bart Schaefer @ 2001-06-21 10:34 UTC (permalink / raw)
  To: Zsh hackers list

On Jun 21, 10:52am, Peter Stephenson wrote:
} Subject: Re: PATCH: 4.1: multi-parameter for loop
}
} > I guess, Bart suggestion (use foreach) is better. And more Perlish :-)
} 
} I'm not so convinced, since `for' and `foreach' currently do the same
} thing, and I don't really like dividing the syntax to make people use the
} non-standard variant just for one use.  foreach is automatically handled at
} the moment, as well as for, by the way.

Hrm.  The patch I just sent makes

	for x
	(a b c)

behave as `for x (a b c)' used to, but

	foreach x
	(a b c)

is taken as a short-loop to run the command "a b c" in a subshell once for
each positional parameter.  I think they should both behave that way; so
the change to parse.c has to be fractionally more complicated.

This goes on top of the last one.

--- zsh-forge/current/Src/parse.c	Thu Jun 21 03:06:36 2001
+++ zsh-4.0/Src/parse.c	Thu Jun 21 03:31:04 2001
@@ -903,13 +903,15 @@
 	yylex();
 	type = WC_FOR_COND;
     } else {
+	int posix_in;
 	infor = 0;
 	if (tok != STRING || !isident(tokstr))
 	    YYERRORV(oecused);
 	ecstr(tokstr);
 	incmdpos = 1;
 	yylex();
-	while (isnewlin && !csh)
+	posix_in = isnewlin;
+	while (isnewlin)
 	  yylex();
 	if (tok == STRING && !strcmp(tokstr, "in")) {
 	    int np, n;
@@ -922,7 +924,7 @@
 		YYERRORV(oecused);
 	    ecbuf[np] = n;
 	    type = (sel ? WC_SELECT_LIST : WC_FOR_LIST);
-	} else if (tok == INPAR) {
+	} else if (!posix_in && tok == INPAR) {
 	    int np, n;
 
 	    incmdpos = 0;

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   


^ permalink raw reply	[flat|nested] 18+ messages in thread

* PATCH (redux): non-POSIX `for' syntax
  2001-06-21 10:34                 ` PATCH (redux): POSIX `for' syntax Bart Schaefer
@ 2001-06-21 15:31                   ` Peter Stephenson
  2001-06-25 16:05                     ` Peter Stephenson
  0 siblings, 1 reply; 18+ messages in thread
From: Peter Stephenson @ 2001-06-21 15:31 UTC (permalink / raw)
  To: Zsh hackers list

"Bart Schaefer" wrote:
> This goes on top of the last one.

This is my patch relative to the foregoing.  It improves the documentation,
and adds the fix not to expand aliases in parameter names after the first.

Index: Doc/Zsh/grammar.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/grammar.yo,v
retrieving revision 1.4
diff -u -r1.4 grammar.yo
--- Doc/Zsh/grammar.yo	2000/08/29 06:35:40	1.4
+++ Doc/Zsh/grammar.yo	2001/06/21 15:27:31
@@ -149,12 +149,21 @@
 findex(for)
 cindex(for loops)
 cindex(loops, for)
-item(tt(for) var(name) [ tt(in) var(word) ... var(term) ] tt(do) var(list) tt(done))(
+item(tt(for) var(name) ... [ tt(in) var(word) ... ] var(term) tt(do) var(list) tt(done))(
 where var(term) is at least one newline or tt(;).
 Expand the list of var(word)s, and set the parameter
 var(name) to each of them in turn, executing
 var(list) each time.  If the tt(in) var(word) is omitted,
 use the positional parameters instead of the var(word)s.
+
+More than one parameter var(name) can appear before the list of
+var(word)s.  If var(N) var(name)s are given, then on each execution of the
+loop the next tt(N) var(word)s are assigned to the corresponding
+parameters.  If there are more var(name)s than remaining var(word)s, the
+remaining parameters are each set to the empty string.  Execution of the
+loop ends when there is no remaining var(word) to assign to the first
+var(name).  It is only possible for tt(in) to appear as the first var(name)
+in the list, else it will be treated as marking the end of the list.
 )
 item(tt(for LPAR()LPAR()) [var(expr1)] tt(;) [var(expr2)] tt(;) [var(expr3)] tt(RPAR()RPAR() do) var(list) tt(done))(
 The arithmetic expression var(expr1) is evaluated first (see
@@ -289,17 +298,17 @@
 item(tt(if) var(list) var(sublist))(
 A short form of the alternate `if'.
 )
-item(tt(for) var(name) tt(LPAR()) var(word) ... tt(RPAR()) var(sublist))(
+item(tt(for) var(name) ... tt(LPAR()) var(word) ... tt(RPAR()) var(sublist))(
 A short form of tt(for).
 )
-item(tt(for) var(name) [ tt(in) var(word) ... var(term) ] var(sublist))(
+item(tt(for) var(name) ... [ tt(in) var(word) ... ] var(term) var(sublist))(
 where var(term) is at least one newline or tt(;).
 Another short form of tt(for).
 )
 item(tt(for LPAR()LPAR()) [var(expr1)] tt(;) [var(expr2)] tt(;) [var(expr3)] tt(RPAR()RPAR()) var(sublist))(
 A short form of the arithmetic tt(for) command.
 )
-item(tt(foreach) var(name) tt(LPAR()) var(word) ... tt(RPAR()) var(list) tt(end))(
+item(tt(foreach) var(name) ... tt(LPAR()) var(word) ... tt(RPAR()) var(list) tt(end))(
 Another form of tt(for).
 )
 item(tt(while) var(list) tt({) var(list) tt(}))(
Index: Src/loop.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/loop.c,v
retrieving revision 1.4
diff -u -r1.4 loop.c
--- Src/loop.c	2000/06/17 17:05:53	1.4
+++ Src/loop.c	2001/06/21 15:27:31
@@ -52,15 +52,15 @@
     Wordcode end, loop;
     wordcode code = state->pc[-1];
     int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
+    int last = 0;
     char *name, *str, *cond = NULL, *advance = NULL;
     zlong val = 0;
-    LinkList args = NULL;
+    LinkList vars = NULL, args = NULL;
 
-    name = ecgetstr(state, EC_NODUP, NULL);
     end = state->pc + WC_FOR_SKIP(code);
 
     if (iscond) {
-	str = dupstring(name);
+	str = dupstring(ecgetstr(state, EC_NODUP, NULL));
 	singsub(&str);
 	if (isset(XTRACE)) {
 	    char *str2 = dupstring(str);
@@ -77,28 +77,32 @@
 	}
 	cond = ecgetstr(state, EC_NODUP, &ctok);
 	advance = ecgetstr(state, EC_NODUP, &atok);
-    } else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
-	int htok = 0;
-
-	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
-	    state->pc = end;
-	    return 0;
-	}
-	if (htok)
-	    execsubst(args);
     } else {
-	char **x;
+	vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);
+
+	if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
+	    int htok = 0;
+
+	    if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
+		state->pc = end;
+		return 0;
+	    }
+	    if (htok)
+		execsubst(args);
+	} else {
+	    char **x;
 
-	args = newlinklist();
-	for (x = pparams; *x; x++)
-	    addlinknode(args, dupstring(*x));
+	    args = newlinklist();
+	    for (x = pparams; *x; x++)
+		addlinknode(args, dupstring(*x));
+	}
     }
     lastval = 0;
     loops++;
     pushheap();
     cmdpush(CS_FOR);
     loop = state->pc;
-    for (;;) {
+    while (!last) {
 	if (iscond) {
 	    if (ctok) {
 		str = dupstring(cond);
@@ -127,14 +131,29 @@
 	    if (!val)
 		break;
 	} else {
-	    if (!args || !(str = (char *) ugetnode(args)))
-		break;
-	    if (isset(XTRACE)) {
-		printprompt4();
-		fprintf(xtrerr, "%s=%s\n", name, str);
-		fflush(xtrerr);
+	    LinkNode node;
+	    int count = 0;
+	    for (node = firstnode(vars); node; incnode(node))
+	    {
+		name = (char *)getdata(node);
+		if (!args || !(str = (char *) ugetnode(args)))
+		{
+		    if (count) { 
+			str = "";
+			last = 1;
+		    } else
+			break;
+		}
+		if (isset(XTRACE)) {
+		    printprompt4();
+		    fprintf(xtrerr, "%s=%s\n", name, str);
+		    fflush(xtrerr);
+		}
+		setsparam(name, ztrdup(str));
+		count++;
 	    }
-	    setsparam(name, ztrdup(str));
+	    if (!count)
+		break;
 	}
 	state->pc = loop;
 	execlist(state, 1, do_exec && args && empty(args));
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.25
diff -u -r1.25 parse.c
--- Src/parse.c	2001/06/21 10:54:49	1.25
+++ Src/parse.c	2001/06/21 15:27:31
@@ -878,7 +878,7 @@
 par_for(int *complex)
 {
     int oecused = ecused, csh = (tok == FOREACH), p, sel = (tok == SELECT);
-    int type;
+    int type, ona = noaliases;
 
     p = ecadd(0);
 
@@ -903,19 +903,32 @@
 	yylex();
 	type = WC_FOR_COND;
     } else {
-	int posix_in;
+	int np, n, posix_in;
 	infor = 0;
 	if (tok != STRING || !isident(tokstr))
 	    YYERRORV(oecused);
-	ecstr(tokstr);
+	np = ecadd(0);
+	n = 0;
 	incmdpos = 1;
-	yylex();
+	noaliases = 1;
+	for (;;) {
+	    n++;
+	    ecstr(tokstr);
+	    yylex();	
+	    if (tok != STRING || !strcmp(tokstr, "in") || sel)
+		break;
+	    if (!isident(tokstr))
+	    {
+		noaliases = ona;
+		YYERRORV(oecused);
+	    }
+	}
+	noaliases = ona;
+	ecbuf[np] = n;
 	posix_in = isnewlin;
 	while (isnewlin)
-	  yylex();
-	if (tok == STRING && !strcmp(tokstr, "in")) {
-	    int np, n;
-
+	    yylex();
+        if (tok == STRING && !strcmp(tokstr, "in")) {
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
@@ -925,8 +938,6 @@
 	    ecbuf[np] = n;
 	    type = (sel ? WC_SELECT_LIST : WC_FOR_LIST);
 	} else if (!posix_in && tok == INPAR) {
-	    int np, n;
-
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
Index: Src/text.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/text.c,v
retrieving revision 1.5
diff -u -r1.5 text.c
--- Src/text.c	2000/12/05 10:34:23	1.5
+++ Src/text.c	2001/06/21 15:27:31
@@ -415,7 +415,7 @@
 		    taddstr(ecgetstr(state, EC_NODUP, NULL));
 		    taddstr(")) do");
 		} else {
-		    taddstr(ecgetstr(state, EC_NODUP, NULL));
+		    taddlist(state, *state->pc++);
 		    if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
 			taddstr(" in ");
 			taddlist(state, *state->pc++);


-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

* PATCH: test case for  POSIX `for' syntax
  2001-06-21  9:55               ` PATCH: POSIX " Bart Schaefer
@ 2001-06-22  6:29                 ` Andrej Borsenkow
  0 siblings, 0 replies; 18+ messages in thread
From: Andrej Borsenkow @ 2001-06-22  6:29 UTC (permalink / raw)
  To: Zsh hackers list

Index: Test/A01grammar.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/A01grammar.ztst,v
retrieving revision 1.1
diff -u -r1.1 A01grammar.ztst
--- Test/A01grammar.ztst        2001/04/02 12:29:57     1.1
+++ Test/A01grammar.ztst        2001/06/22 06:28:05
@@ -118,6 +118,15 @@
 >to
 >term
 
+  for name
+  in word to term; do
+    print $name
+  done
+0:`for' loop with newline before in keyword
+>word
+>to
+>term
+
   for (( name = 0; name < 3; name++ )); do
     print $name
   done

-andrej


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-20 18:55       ` Bart Schaefer
  2001-06-20 19:12         ` Peter Stephenson
@ 2001-06-22 23:49         ` Zefram
  2001-06-23  0:04           ` Bart Schaefer
  1 sibling, 1 reply; 18+ messages in thread
From: Zefram @ 2001-06-22 23:49 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
>               clearly a parameter named "in" can only appear in the first
>position,

for out 'in' in a b c d; do ...

-zefram


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH: 4.1: multi-parameter for loop
  2001-06-22 23:49         ` PATCH: 4.1: multi-parameter for loop Zefram
@ 2001-06-23  0:04           ` Bart Schaefer
  0 siblings, 0 replies; 18+ messages in thread
From: Bart Schaefer @ 2001-06-23  0:04 UTC (permalink / raw)
  To: Zefram, zsh-workers

On Jun 23, 12:49am, Zefram wrote:
> Subject: Re: PATCH: 4.1: multi-parameter for loop
> Bart Schaefer wrote:
> >               clearly a parameter named "in" can only appear in the first
> >position,
> 
> for out 'in' in a b c d; do ...

That requires even more changes to the parser ...

bash$ for 'in' in a b c d; do break; done
bash: `'in'' is not a valid identifier

zsh% for 'in' in a b c d; do break; done
zsh: parse error near `'in''

I.e. you can't use a quoted string as the NAME in `for NAME in WORD'.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: PATCH (redux): non-POSIX `for' syntax
  2001-06-21 15:31                   ` PATCH (redux): non-POSIX " Peter Stephenson
@ 2001-06-25 16:05                     ` Peter Stephenson
  0 siblings, 0 replies; 18+ messages in thread
From: Peter Stephenson @ 2001-06-25 16:05 UTC (permalink / raw)
  To: Zsh hackers list

Peter Stephenson wrote:
> This is my [for more than one parameter in ...] patch relative to the
> foregoing.  It improves the documentation, and adds the fix not to expand
> aliases in parameter names after the first.

Looks like the dust has settled somewhat.  I'm going to commit this (on the
4.1 branch, obviously) and we'll see what happens.  (P.S. it doesn't expand
aliases for the first parameter name either, but it never did that.)

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR Ltd., Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2001-06-25 16:05 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-20 14:45 PATCH: 4.1: multi-parameter for loop Peter Stephenson
2001-06-20 16:11 ` Peter Stephenson
2001-06-20 18:01 ` Andrej Borsenkow
2001-06-20 18:20   ` Bart Schaefer
2001-06-20 18:39     ` Peter Stephenson
2001-06-20 18:55       ` Bart Schaefer
2001-06-20 19:12         ` Peter Stephenson
2001-06-20 22:56           ` Danek Duvall
2001-06-21  7:19             ` Andrej Borsenkow
2001-06-21  9:52               ` Peter Stephenson
2001-06-21 10:34                 ` PATCH (redux): POSIX `for' syntax Bart Schaefer
2001-06-21 15:31                   ` PATCH (redux): non-POSIX " Peter Stephenson
2001-06-25 16:05                     ` Peter Stephenson
2001-06-21  9:55               ` PATCH: POSIX " Bart Schaefer
2001-06-22  6:29                 ` PATCH: test case for " Andrej Borsenkow
2001-06-22 23:49         ` PATCH: 4.1: multi-parameter for loop Zefram
2001-06-23  0:04           ` Bart Schaefer
2001-06-21  8:33 ` Sven Wischnowsky

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).