zsh-workers
 help / color / mirror / code / Atom feed
From: Zoltan Hidvegi <hzoli@frontiernet.net>
To: schaefer@brasslantern.com (Bart Schaefer)
Cc: zsh-workers@math.gatech.edu (Zsh hacking and development)
Subject: Re: RC_EXPAND_PARAM bug
Date: Wed, 30 Jul 1997 01:16:10 -0400 (EDT)	[thread overview]
Message-ID: <199707300516.BAA01180@hzoli.home> (raw)
In-Reply-To: <970729092705.ZM16897@candle.brasslantern.com> from Bart Schaefer at "Jul 29, 97 09:27:05 am"

> } > % echo ${^a}$[i++]$[++j]${^x}....
> } > 
> } > where .... is some arbitary number of other substitutions?  Is it just that
> } > it now does everything from right to left instead of left to right?  Why?
> } 
> } No, it is left to right.  ${^a} is expanded first, then the remaining
> } part, $[i++]$[++j]${^x} is expanded separately, and the result is
> } combined with the expansion of ${^a}.  You can see it if you try
> } 
> } let i=0; echo $[i++]${^a}$[i++]
> } 
> } which gives
> } 
> } 0a1 0b1
> 
> I'm still not comprehending this.
> 
> Are you saying that all the variables are expanded first, left to right,
> and then all the resulting strings are combined?  Whereas before (2.6 and
> earlier) each variable would be expanded and combined with what followed,
> and then the process repeated for each new string?

OK, I tell you what subst.c does.  You have a string of the form

prefix${^a}suffix

Suppose that prefix does not have anything to expand.  paramsubst is
called to expand this string, which expands ${^a}.  There are three
cases:

1. `a' was an empty array.  In that case the expansion is the empty list,
   and suffix is not evaluated (so even if there is a $[i++] in suffix, i
   will not change).

2. `a' had one element: paransubst replaces ${^a} with its value and
   returns and the calling routine, stringsubst, which continues parsing
   the suffix.  If that suffix contains some other parameter expansions,
   paramsubst will be called again.

3. `a' has more than one elements.  In that case stringsubst is called
   for suffix alone (which may call paramsubst again to expand something
   in suffix), and the result will be be a list.  This list is combined
   with the expansion of ${^a}.  If suffix expands to an empty list, the
   result will be empty, otherwise the result is the first element of `a'
   combined with the each element from the expansion of suffix, followed
   by the second element of `a' combined with list etc.  Note that suffix
   can only expand to an empty list as a result of an rc-expansion in
   suffix (that's because null-argument removal is only done in prefork
   after stringsubst).  With this, in ${^a}1${^^x} the expansion of
   1${^^x} gives two elements, 1x y, which is combined with `a'.  If you
   replace 1${^^x} with 1${^x}, it is expanded to 1x 1y instead of 1x y.

This guarantees left to right evaluation, everything is evaluated at most
once, and everything is evaluated once unless there is an rc-expansion of
an empty array which discards everything following that array.

The 2.6-beta16 and earlier behavior:

${^a} was expanded, and a list was created prepending prefix and
appending suffix for each array element.  The resulting list is parsed
again from the beginning.  For example:

a=('${~^a}' '${~^a}')

prefix${~^a}suffix

expands to

prefix${~^a}suffix prefix${~^a}suffix

and the expansion is restarted, the first element of this list is
expanded again, the result is

prefix${~^a}suffix prefix${~^a}suffix prefix${~^a}suffix

and the expansion is restarted...  For this infinite loop, the ~ or the
globsubst option was necessary.

What would be the preferred evaluation of ${^a}1${^^x}?

Alternatives:

1. a1x ay b1x by  (current)

2. a1x y b1x y    (beta16 and older)

3. a1x b1x y      (just an other logical solution).

The current behaviour is the simplest to code solution, I think the other
two are not very hard to implement, but I'm not sure it is worth the
extra effort.

Zoltan


  parent reply	other threads:[~1997-07-30  5:23 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-07-28 13:42 Andrew Main
1997-07-28 16:26 ` Bart Schaefer
1997-07-29  6:04   ` Zoltan Hidvegi
1997-07-29  7:09     ` Bart Schaefer
1997-07-29  7:36       ` Zoltan Hidvegi
1997-07-29  7:47     ` Geoff Wing
1997-07-29 16:27       ` Bart Schaefer
1997-07-30  3:04         ` Geoff Wing
1997-07-30  3:56           ` Bart Schaefer
1997-07-30  5:16         ` Zoltan Hidvegi [this message]
1997-07-30  5:46           ` Andrej Borsenkow
1997-07-30  6:11           ` Bart Schaefer
1997-07-30  6:51             ` Zoltan Hidvegi
1997-07-30  7:33               ` Bart Schaefer
1997-07-30  8:18           ` Andrew Main
1997-07-30 15:54             ` Andrej Borsenkow
1997-07-30 17:05               ` Bart Schaefer
1997-08-01 13:17                 ` Andrej Borsenkow
1997-08-01 18:18                   ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199707300516.BAA01180@hzoli.home \
    --to=hzoli@frontiernet.net \
    --cc=schaefer@brasslantern.com \
    --cc=zsh-workers@math.gatech.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).