Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<&foo> [REGEX] syntax does not find &foo in the regex's own scope, only in the parent scope #5230

Open
p6rt opened this issue Apr 10, 2016 · 6 comments

Comments

@p6rt
Copy link

p6rt commented Apr 10, 2016

Migrated from rt.perl.org#127872 (status was 'open')

Searchable as RT127872$

@p6rt
Copy link
Author

p6rt commented Apr 10, 2016

From @smls

The following fails to compile with "Undeclared routine​: regex"​:

  my token foo (&another-regex) { <&another-regex> };

Since routine arguments are supposed to become available to the routine body as lexical symbols, and <&foo> is the regex syntax for calling another regex by its lexical name, I assume this error is a bug.

For comparison, the following two variations do compile and work just fine​:

  my token foo ($another-regex) { $another-regex };

  my token foo (&another-regex) { {say &another-regex} };

(This is Rakudo version 2016.03-108-g98b5b8c built on MoarVM version 2016.03-104-g10d3971
implementing Perl 6.c.)

@p6rt
Copy link
Author

p6rt commented Apr 11, 2016

From @smls

UPDATE​:

It's not specific to the & sigil, as it also does not work with $ arguments​:

  my token foo ($a) { <$a> }; # Error​: Variable '$a' is not declared

And it's not specific to arguments, as it also does not work when the variable is declared using a '​:my' directive inside the regex body​:

  my token foo { :my &a = /a/; <&a> } # Error​: Undeclared routine​: a

On the other hand, it *does* work if the variable is declared in the parent scope​:

  my &a = /a/; my token foo { <&a> }

So the problems seems to be, that the < > regex call syntax looks up lexicals only in the *parent* scope of the regex it is used in, and not in the scope of the regex itself.

psch++ suggested that this may be intended behavior​: http://irclog.perlgeek.de/perl6/2016-04-11#i_12317275

psch++ also suggested a work-around by wrapping the regex in a Perl 6 method, so that the parameter becomes part of the parent scope of the regex​:

  my method foo (&a) { self.CALL_SUBRULE​: / <&a> / }

Still, it feels strange that the < > syntax behaves this way.
Needs confirmation from TimToady on the intended behavior.

@p6rt
Copy link
Author

p6rt commented Apr 23, 2016

From @smls

IRC comment <http://irclog.perlgeek.de/perl6/2016-04-22#i_12380115>&#8203;:

  23​:30 TimToady​: looks like a bug to me

@p6rt
Copy link
Author

p6rt commented Jul 10, 2016

From @zoffixznet

Still present in rakudo 405519

<Zoffix> m​: my token foo ($a) { <$a> };
<camelia> rakudo-moar 405519​: OUTPUT«===SORRY!=== Error while compiling <tmp>␤Variable '$a' is not declared␤at <tmp>​:1␤------> my token foo ($a) { <⏏$a> };␤»

@p6rt
Copy link
Author

p6rt commented Aug 23, 2016

@coke - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Sep 7, 2017

From @skids

On Sat, 09 Jul 2016 19​:48​:54 -0700, cpan@​zoffix.com wrote​:

Still present in rakudo 405519

<Zoffix> m​: my token foo ($a) { <$a> };
<camelia> rakudo-moar 405519​: OUTPUT«===SORRY!=== Error while
compiling <tmp>␤Variable '$a' is not declared␤at <tmp>​:1␤------> my
token foo ($a) { <⏏$a> };␤»

In addition to compiling, actually calling the regex presents some additional
restrictions​:

To use arguments with the <&a()> form, you cannot use a sub or method​:

$ perl6 -e 'my method a () { "a" ~~ /aa/ }; my token foo { <&a()> }; say "aa" ~~ /<foo>/'
Cannot look up attributes in a Nil type object
  in regex foo at -e line 1
  in block <unit> at -e line 1

...but regexes work fine.

To use the <&a> form, you merely need to define it in the parent scope​:

$ perl6 -e 'my token foo { :my regex a { a }; <&a> }; "aa" ~~ /<foo>/'
===SORRY!=== Error while compiling -e
Undeclared routine​:
  a used at line 1
$ perl6 -e 'my regex a { a }; my token foo { <&a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」
$ perl6 -e 'my token a { a }; my token foo { <&a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」
$ perl6 -e 'my sub a ($cursor) { "aa" ~~ /a/ }; my token foo { <&a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」
$ perl6 -e 'my method a ($cursor​:) { "aa" ~~ /a/ }; my token foo { <&a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」

...

...however to use the <a> form and hit a lexical method, it can be directly in the scope​:

$ perl6 -e 'my token foo { :my regex a { a }; <a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」
  a => 「a」
bri@​atlas​:~/git/roast$ perl6 -e 'my regex a { a }; my token foo { <a> }; say "aa" ~~ /<foo>/'
「a」
foo => 「a」
  a => 「a」

...but is must be a regex, not a sub or method

$ perl6 -e 'my method a ($cursor​:) { "aa" ~~ /a/ }; my token foo { <a> }; say "aa" ~~ /<foo>/'
No such method 'a' for invocant of type 'Match'. Did you mean 'at'?
  in regex foo at -e line 1
  in block <unit> at -e line 1

$ perl6 -e 'my sub a ($cursor) { "aa" ~~ /a/ }; my token foo { <a> }; say "aa" ~~ /<foo>/'
No such method 'a' for invocant of type 'Match'. Did you mean 'at'?
  in regex foo at -e line 1
  in block <unit> at -e line 1

... that latter part may be to spec. However the spec, after being very careful to only
talk about regexes when describing <a>'s lexical predelictions, if this is indeed intentional,
slips up by dropping the word "routine" in the last paragraph of that section. A bit
of spec clarification would help there.

Internally, <&a> seems to route through assertion​:sym<var> which installs a CALL_SUBRULE invocation,
and <a> routes through assertion​:sym<name> which tacks on a '&' sigil, perfoms a $*W.regex_in_scope
check, verifies that there was no dot preceding it, and then creates a new lexical var of the same
sigiled name, but does not use a CALL_SUBRULE instruction... just sets up RX QAST nodes.

The tests in S05-metasyntax/angle-brackets.t auto-RTed as RT#​124519 through RT#​124523 make a lot
of wrong assumptions about what the return value is and what gets done with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant