Using $/ is not exactly the same as using any other variable in grammar actions
Asked Answered
H

1

8

In theory, and according to the documentation, you can use any argument for methods in grammar actions.

grammar G {
    token TOP { \w+ }
}

class Action-Arg {
    method TOP ($match) { $match.make: ~$match }
}

class Action {
    method TOP ($/) { make ~$/ }
}

class Action-Fails {
    method TOP ($match) { make ~$match }
}

say G.parse( "zipi", actions => Action-Arg );
say G.parse( "zape", actions => Action );
say G.parse( "pantuflo", actions => Action-Fails );

However, the two first versions work as expected. But the third one (which would be a direct translation of the second), fails with

Cannot bind attributes in a Nil type object
  in method TOP at match-and-match.p6 line 19
  in regex TOP at match-and-match.p6 line 7
  in block <unit> at match-and-match.p6 line 24

There's probably some special syntax going on (in the sense of make being actually $/.make, probably), but I'd just like to clarify if this is according to spec or is a bug.

Heedful answered 1/7, 2019 at 10:11 Comment(1)
A friendly reminder for readers and writers. (This is unrelated to JJ's real question.) In computing there is a distinction between A) a value that is passed as part of a function call and B) a variable that the value is bound to in the signature of a function's definition. The term most commonly used by programmers for the former is argument. For the latter, in several programming language cultures, including P6, the preferred term is parameter to avoid confusion. In the above question, JJ meant "parameter" when he wrote "argument".Doglike
S
8

That is because the make subroutine is one of those rare cases in Rakudo where it actually tries to access the $/ variable from the scope it is called from. Which is also how it is documented:

The sub form operates on the current $/

(from the documentation)

Salubrious answered 1/7, 2019 at 10:16 Comment(3)
Right, I'll have to link that description from the other. Also, Match appears twice, which is a document generation bug I'll have to fix...Heedful
The sub form of make magically uses $/ from the "calling" scope but doesn't actually use the argument passed to it? That seems to be true based on some test code I just created. What then is the purpose of requiring an argument be passed to make?Lousewort
What you pass to make is what you want to have made. It tries to bind that to the Match object assumed to exist in $/ in the scope in which the make is called. The "Action-Fails" example of the original question, does not have a $/ that is a Match object: instead it finds a Nil, and then dies because it cannot bind anything to that.Salubrious

© 2022 - 2024 — McMap. All rights reserved.