zsh-workers
 help / color / mirror / code / Atom feed
* RFC PATCH: Sketch at :@ subscripting
@ 2020-12-18 13:18 Mikael Magnusson
  2020-12-19  9:13 ` Stephane Chazelas
  2021-03-27 19:41 ` Lawrence Velázquez
  0 siblings, 2 replies; 10+ messages in thread
From: Mikael Magnusson @ 2020-12-18 13:18 UTC (permalink / raw)
  To: zsh-workers

As the subject says, this is in a very early idea stage, but it does work for basic cases at least.

The idea is that you can do this:
% typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
% echo ${somearray:@idx}
data here etc 1

The way it currently works also lets you do this:
% typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=( '(r)<->' '(I)etc' )
% echo ${somearray:@idx}
1 4

Not decided on if that's desirable :).

Anyway, the code as it is written now is very hacky and I'm wondering if I missed the existence of some useful functions, or if the stuff I'm using now would need to be refactored a bit to make this actually possible without doing stupid things like zhtricat("[", *sub_it, "]").

Also curious why getindex() unconditionally *writes* '[' to the first character in the input string passed to it...

---
 Src/subst.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/Src/subst.c b/Src/subst.c
index 8de201b663..943b2546c4 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3167,6 +3167,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 	    }
 	    break;
 	}
+    } else if (inbrace && (*s == '@')) {
+	/* use every element of the array specified by @ as a subscript */
+	char **idx;
+	++s;
+	if (*itype_end(s, IIDENT, 0)) {
+	    untokenize(s);
+	    zerr("not an identifier: %s", s);
+	    return NULL;
+	}
+	if (vunset) {
+	    if (vunset > 0 && unset(UNSET)) {
+		*idend = '\0';
+		zerr("%s: parameter not set", idbeg);
+		return NULL;
+	    }
+	    isarr = 0;
+	    val = dupstring("");
+	} else {
+	    char *sval;
+	    idx = getaparam(s);
+	    if (!idx) {
+		sval = getsparam(s);
+		if (sval)
+		    idx = hmkarray(sval);
+	    }
+	    if (idx) {
+		if (isarr) {
+		    if (PM_TYPE(vbuf.pm->node.flags) & PM_ARRAY) {
+			/* actual code is here */
+			LinkList list = newlinklist();
+			char **sub_it, **val_it;
+			for (sub_it = idx; *sub_it; sub_it++) {
+			    char *tmp = zhtricat("[", *sub_it, "]");
+			    /* getindex() modifies vbuf in ways that break further
+			     * subscripting with differing flags, so better not to
+			     * touch it at all. */
+			    struct value vbuf_copy = vbuf;
+			    getindex(&tmp, &vbuf_copy, 0);
+			    for (val_it = getarrvalue(&vbuf_copy); *val_it; val_it++) {
+				addlinknode(list, *val_it);
+			    }
+			}
+			aval = hlinklist2array(list, !copied);
+			copied = 1;
+		    } else {
+			zerr("assoc @ not implemented");
+		    }
+		} else {
+		    zerr("scalar @ not implemented");
+		}
+	    } else {
+
+		if (unset(UNSET)) {
+		    zerr("%s: parameter not set", s);
+		    return NULL;
+		}
+		isarr = 0;
+		val = dupstring("");
+	    }
+	}
     } else if (inbrace && (*s == '^' || *s == Hat)) {
 	char **zip;
 	int shortest = 1;
-- 
2.15.1



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

* Re: RFC PATCH: Sketch at :@ subscripting
  2020-12-18 13:18 RFC PATCH: Sketch at :@ subscripting Mikael Magnusson
@ 2020-12-19  9:13 ` Stephane Chazelas
  2021-03-27 20:27   ` Bart Schaefer
  2021-03-27 19:41 ` Lawrence Velázquez
  1 sibling, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2020-12-19  9:13 UTC (permalink / raw)
  To: Mikael Magnusson; +Cc: zsh-workers

2020-12-18 14:18:15 +0100, Mikael Magnusson:
[...]
> The idea is that you can do this:
> % typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
> % echo ${somearray:@idx}
> data here etc 1
[...]

Hi Mikael,

I can't help but think that allowing to specify the indexes
directly as perl does for instance in:

print @list[1, 4, 2, 7..10, @idx, -1];

And in assignments as well:

@list[@idx] = qw(new values here);

would be more useful.

It's unfortunate that "," is used for ranges in $a[1,3] in zsh
especially considering that "," is also an arithmetic operator
(btw:
  $ a=({a..z})
  $ echo ${a[1,3]}
  a b c
  $ i=1,3
  $ echo ${a[i]}
  c
  $ echo ${a[$i]}
  a
??) and that {1,3,{5..7}} otherwise follows the perl semantics
(and extends it as it allows backward ranges).

${list[2 6 8]} in zsh wouldn't work as ${list[2 -1]} already
means something different, but maybe ${list[2;6,9;${(j[;])idx},-1]}
would?

That would mean no backward range as $a[3,1] ATM is the empty
list but backward sets would still be possible with $a[3;2;1].

Maybe another option could be $a[{1,4,{8..2},$^idx}] so as to
reuse an already known syntax?

Except that:

$ i=(a b)
$ echo {1,2,$^i}.
1. 2. a. 1. 2. b.
$ echo {1,2,{a,b}}.
1. 2. a. b.

Syntax would also have to be restricted to a[{...}], no
a[{1,2}0] for instance.

a[{${(f)^"$(shuf -n 5 -i 1-100)"}]=({a..e})
soon becomes awkward as well.

There's also the question of

a[1;5]=(a b c)
a[1;5]=(a)
...

Having a syntax that could also apply to associative arrays
would be best.

-- 
Stephane


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2020-12-18 13:18 RFC PATCH: Sketch at :@ subscripting Mikael Magnusson
  2020-12-19  9:13 ` Stephane Chazelas
@ 2021-03-27 19:41 ` Lawrence Velázquez
  1 sibling, 0 replies; 10+ messages in thread
From: Lawrence Velázquez @ 2021-03-27 19:41 UTC (permalink / raw)
  To: zsh-workers; +Cc: Mikael Magnusson

On Fri, Dec 18, 2020, at 8:18 AM, Mikael Magnusson wrote:
> As the subject says, this is in a very early idea stage, but it does 
> work for basic cases at least.
> 
> The idea is that you can do this:
> % typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
> % echo ${somearray:@idx}
> data here etc 1
> 
> The way it currently works also lets you do this:
> % typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) 
> idx=( '(r)<->' '(I)etc' )
> % echo ${somearray:@idx}
> 1 4
> 
> Not decided on if that's desirable :).

Any further feedback on this?

vq


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2020-12-19  9:13 ` Stephane Chazelas
@ 2021-03-27 20:27   ` Bart Schaefer
  2021-04-03 19:48     ` Lawrence Velázquez
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2021-03-27 20:27 UTC (permalink / raw)
  To: Mikael Magnusson, Zsh hackers list

On Sat, Dec 19, 2020 at 1:13 AM Stephane Chazelas <stephane@chazelas.org> wrote:
>
> 2020-12-18 14:18:15 +0100, Mikael Magnusson:
> [...]
> > The idea is that you can do this:
> > % typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
> > % echo ${somearray:@idx}
> > data here etc 1
> [...]
>
> Hi Mikael,
>
> I can't help but think that allowing to specify the indexes
> directly as perl does for instance in:
>
> print @list[1, 4, 2, 7..10, @idx, -1];

The way to do this (syntactically speaking) would be with a subscript
flag.  E.g.:
  print $array[(^)1,3,7]
would change the interpretation of the commas to select a set of
elements instead of a range.  I chose (^) because of symmetry with
$^array and to avoid confusion with for example $array[@].

I haven't looked into how difficult that might be to implement,
particularly in assignment context.

Another possibility is to handle $array[{1,3,7}] specially since "{"
is already a syntax error in math context.

Both of those options could apply to associative arrays, although keys
 would need to respect quoting to avoid troubles with an embedded ",".

>   $ i=1,3
>   $ echo ${a[i]}
>   c

Here [i] is interpreted in math context so the comma becomes an
operator (the collision you already noted) so this becomes $a[3]

>   $ echo ${a[$i]}
>   a

This one is confusing and a bug ... it should be the same as
${a[$[$i]]} but instead it's ${a[,3]}.  I haven't tracked down exactly
what's skipping everything up to but not including the first comma (it
is not, for example, just dropping one character).


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-03-27 20:27   ` Bart Schaefer
@ 2021-04-03 19:48     ` Lawrence Velázquez
  2021-04-04 17:30       ` Daniel Shahaf
  0 siblings, 1 reply; 10+ messages in thread
From: Lawrence Velázquez @ 2021-04-03 19:48 UTC (permalink / raw)
  To: zsh-workers

On Sat, Mar 27, 2021, at 4:27 PM, Bart Schaefer wrote:
> On Sat, Dec 19, 2020 at 1:13 AM Stephane Chazelas <stephane@chazelas.org> wrote:
> >
> > 2020-12-18 14:18:15 +0100, Mikael Magnusson:
> > [...]
> > > The idea is that you can do this:
> > > % typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
> > > % echo ${somearray:@idx}
> > > data here etc 1
> > [...]
> >
> > Hi Mikael,
> >
> > I can't help but think that allowing to specify the indexes
> > directly as perl does for instance in:
> >
> > print @list[1, 4, 2, 7..10, @idx, -1];
> 
> The way to do this (syntactically speaking) would be with a subscript
> flag.  E.g.:
>   print $array[(^)1,3,7]
> would change the interpretation of the commas to select a set of
> elements instead of a range.  I chose (^) because of symmetry with
> $^array and to avoid confusion with for example $array[@].
> 
> I haven't looked into how difficult that might be to implement,
> particularly in assignment context.
> 
> Another possibility is to handle $array[{1,3,7}] specially since "{"
> is already a syntax error in math context.
> 
> Both of those options could apply to associative arrays, although keys
>  would need to respect quoting to avoid troubles with an embedded ",".
> 
> >   $ i=1,3
> >   $ echo ${a[i]}
> >   c
> 
> Here [i] is interpreted in math context so the comma becomes an
> operator (the collision you already noted) so this becomes $a[3]
> 
> >   $ echo ${a[$i]}
> >   a
> 
> This one is confusing and a bug ... it should be the same as
> ${a[$[$i]]} but instead it's ${a[,3]}.  I haven't tracked down exactly
> what's skipping everything up to but not including the first comma (it
> is not, for example, just dropping one character).

bump

vq


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-04-03 19:48     ` Lawrence Velázquez
@ 2021-04-04 17:30       ` Daniel Shahaf
  2021-04-10 20:38         ` Lawrence Velázquez
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Shahaf @ 2021-04-04 17:30 UTC (permalink / raw)
  To: zsh-workers, Lawrence Velázquez

Lawrence Velázquez wrote on Sat, Apr 03, 2021 at 15:48:03 -0400:
> On Sat, Mar 27, 2021, at 4:27 PM, Bart Schaefer wrote:
> > On Sat, Dec 19, 2020 at 1:13 AM Stephane Chazelas <stephane@chazelas.org> wrote:
> > >   $ echo ${a[$i]}
> > >   a
> > 
> > This one is confusing and a bug ... it should be the same as
> > ${a[$[$i]]} but instead it's ${a[,3]}.  I haven't tracked down exactly
> > what's skipping everything up to but not including the first comma (it
> > is not, for example, just dropping one character).
> 
> bump

Could someone add that as an XFail test (one with the 'F' flag)?
Test/list-XFails complements Etc/BUGS as a list of known defects.

And thanks for catching everything you did, Lawrence!

Cheers,

Daniel


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-04-04 17:30       ` Daniel Shahaf
@ 2021-04-10 20:38         ` Lawrence Velázquez
  2021-04-10 21:59           ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Lawrence Velázquez @ 2021-04-10 20:38 UTC (permalink / raw)
  To: zsh-workers

On Sun, Apr 4, 2021, at 1:30 PM, Daniel Shahaf wrote:
> Lawrence Velázquez wrote on Sat, Apr 03, 2021 at 15:48:03 -0400:
> > bump
> 
> Could someone add that as an XFail test (one with the 'F' flag)?
> Test/list-XFails complements Etc/BUGS as a list of known defects.

humpty BUMPty

vq


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-04-10 20:38         ` Lawrence Velázquez
@ 2021-04-10 21:59           ` Bart Schaefer
  2021-04-13 11:54             ` Daniel Shahaf
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2021-04-10 21:59 UTC (permalink / raw)
  To: Lawrence Velázquez; +Cc: Zsh hackers list

On Sat, Apr 10, 2021 at 1:39 PM Lawrence Velázquez <larryv@zsh.org> wrote:
>
> > Could someone add that as an XFail test (one with the 'F' flag)?

This OK?

diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst
index c1a8d79cf..4225c543c 100644
--- a/Test/D06subscript.ztst
+++ b/Test/D06subscript.ztst
@@ -289,3 +289,8 @@ F:Regression test for workers/42297
 >14 24
 >b b
 >b?rbaz foob?r
+
+  i=1,3
+  [[ ${a[$i]} = ${a[i]} ]]
+0f:Math evaluation of commas in array subscripts
+F:In math, (($i)) should be the same as ((i)).


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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-04-10 21:59           ` Bart Schaefer
@ 2021-04-13 11:54             ` Daniel Shahaf
  2021-04-13 21:25               ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Shahaf @ 2021-04-13 11:54 UTC (permalink / raw)
  To: Zsh hackers list; +Cc: Lawrence Velázquez

Bart Schaefer wrote on Sat, Apr 10, 2021 at 14:59:28 -0700:
> On Sat, Apr 10, 2021 at 1:39 PM Lawrence Velázquez <larryv@zsh.org> wrote:
> >
> > > Could someone add that as an XFail test (one with the 'F' flag)?
> 
> This OK?

+1.  The expectations are minimal, so the test will start to XPass as
soon as zsh's behaviour changes.  If the behaviour has changed because
the bug was fixed, we can extend the test's expectations then.

I'll only suggest to add this thread's X-Seq to the ztst file somewhere,
for ease of reference.

Thanks,

Daniel

> diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst
> index c1a8d79cf..4225c543c 100644
> --- a/Test/D06subscript.ztst
> +++ b/Test/D06subscript.ztst
> @@ -289,3 +289,8 @@ F:Regression test for workers/42297
>  >14 24
>  >b b
>  >b?rbaz foob?r
> +
> +  i=1,3
> +  [[ ${a[$i]} = ${a[i]} ]]
> +0f:Math evaluation of commas in array subscripts
> +F:In math, (($i)) should be the same as ((i)).



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

* Re: RFC PATCH: Sketch at :@ subscripting
  2021-04-13 11:54             ` Daniel Shahaf
@ 2021-04-13 21:25               ` Bart Schaefer
  0 siblings, 0 replies; 10+ messages in thread
From: Bart Schaefer @ 2021-04-13 21:25 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Zsh hackers list, Lawrence Velázquez

On Tue, Apr 13, 2021 at 4:54 AM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
>
> I'll only suggest to add this thread's X-Seq to the ztst file somewhere,
> for ease of reference.

Will do so when committing.


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

end of thread, other threads:[~2021-04-13 21:25 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-18 13:18 RFC PATCH: Sketch at :@ subscripting Mikael Magnusson
2020-12-19  9:13 ` Stephane Chazelas
2021-03-27 20:27   ` Bart Schaefer
2021-04-03 19:48     ` Lawrence Velázquez
2021-04-04 17:30       ` Daniel Shahaf
2021-04-10 20:38         ` Lawrence Velázquez
2021-04-10 21:59           ` Bart Schaefer
2021-04-13 11:54             ` Daniel Shahaf
2021-04-13 21:25               ` Bart Schaefer
2021-03-27 19:41 ` Lawrence Velázquez

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).