Skip to content

Instantly share code, notes, and snippets.

@cognominal
Last active March 25, 2021 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cognominal/d181082b41595d6f41588faf6d51a42d to your computer and use it in GitHub Desktop.
Save cognominal/d181082b41595d6f41588faf6d51a42d to your computer and use it in GitHub Desktop.
proposal about slangs
=begin pod
=head1 Slangs
This material complements existing docs about slangs. Mainly, it
describes the consequences of using C<~slang>, especially writing the
intuitive <~slang.rule> instead of the cryptic C<LANG('slang',
'rule')>. Also in C<&LANG> implementation, the relationship between
grammar and actions is hardwired which is plain wrong:
my $*ACTIONS := %*LANG{$lang ~ '-actions'};
=head2 slang variables
C<%~> is a magic dynamic variable is used to associate names with slangs
so it is of type Slang.
Similarly to C<$/>, C<$~my-slang> is just a short for
C<< %~<my-slang> >> and is implicitely of Slang type.
Setting a slang variable:
$~my-slang := Slang.new(:$grammar, :$actions).
Using C<a-rule> of C<~my-slang> within a rule looks like a method call
and captures the match in C<< $<a-rule> >>.
<my-slang.a-rule>
<my-slang.a-rule: 'an argument'>
<my-slang.a-rule('an argument')>
Use an initial dot if you don't want to capture
<.my-slang.a-rule>
=for comment
initially, I was in favor of <$~my-slang.a-rule>syntax, but FROGGS noted thatit would break the convention
that rules starting with non alphanumeric are not capturing
Typically, slang variables are set in the TOP method of a grammar
method TOP() {
...
my %~;
$~MAIN := Slang.new NQP::Regex( :grammar(NQP::Grammar), :actions(NQP::Actions);
$~Regex := Slang.new NQP::Regex( :grammar(NQP::Regex), :actions(NQP::RegexActions);
}
This is a mouthful.
=comment FROGGS find the following convention too magic
An assignement operator uses a shorter form to create a slang from the
grammar and actions classes. Parentheses are necessary because
C<$~MAIN> is scalar, so scalar C<< infix:<=> >> is tighter than C<<
infix<:=> >>. NQP does not support multiple dispatch so we fake
it.
$~MAIN = (Perl6::Grammar, Perl6::Actions);
The C<HLL::Grammar> C<.LANG> method is deprecated. Within rules, one
should use C<< <NQP.deflongname> >> instead of C<< <LANG('NQP', deflongname)> >>.
To make clear from the outset what slang rules will be used, on can write a
use declaration, then utilize the said rules as if they belonged to the current
grammar. Below we "import" rules C<&rules-1> and C<&rule-2> from slang C<$~slang-1>.
use $~slang-1 < rule-1 rule-2 >;
To avoid name conflicts we can use an alias for importation.
Below C<&rule-1> from C<$~slang-2> is aliased to C<&alias>
use $~slang-2 :rule-1<alias>
Now instead of
rule foo { ... <slang-1.rule-1> ... }
rule bar { ... <slang-2.rule-1> ... }
On can write
rule foo { ... <rule-1> ... }
rule bar { ... <alias> ... }
=head2 $~HOST and $~MAIN
A slang can be hosted by different languages and may call back a rule in
the host language. A hosting language must set C<$~MAIN> to itself, that is
the main slang. With that information, within hosted slang, C<$~HOST> is used
to refer to rules in the main language.
<HOST.variable> # using the C<&variable> rule in the host language.
Likely, using rules coming from potential different hosting
languages will work if the hosting languages are similar because the
syntax defined by the host rule used in the host slang must harmoniouly blend with slang
syntax. We nevertheless encourage languages implementors to use
existings rulenames from nqp or rakudo when it makes sense.
=end pod
@raiph
Copy link

raiph commented Jun 20, 2016

Why can't foo::bar::baz.rule work such that foo::bar::baz can be a grammar, class, or slang?

Setting a slang variable:

$~my-slang := Slang.new(:$grammar, :$actions).

Why do we need user-visible slang variables?

What kind of type are slangs? Are they roles or classes or some new kind of type?

Why create an instance of a slang? What per-instance storage does it need?

Are $~MAIN et al dynamic variables?

@cognominal
Copy link
Author

thx for commenting.

Why can't foo::bar::baz.rule work such that foo::bar::baz can be a grammar, class, or slang?

I first thought writing <$~slang.rule> but FROGGS told me that would break the convention 👍 non starting by a alphanumeric don't capture.
Writing <slang.rule> as I do now conflicts with your proposal because slang can refer here to slang the package or $~slang.
Need to think if it makes sense to use <slang.rule> for anything but slangs. The advantage of slang is to be dynamically scoped.
Also there is probably some setup involved as implied by my thought as slang as compilers.

Are $~MAIN et al dynamic variables?
%~ is a dynamic variable so ipso facto $~MAIN and the like are.

Why do we need user-visible slang variables?

For composing slang in a grammar and calling their TOP or even subrules (maybe problematic is stateful slang).

I will not adress individually your other questions because they boil down to the same problem.
I originally thought that would be Slang instances as per current rakudo core.
I now think that slangs must be somehow derived from the Compiler class.
Slang as compilers would allow to test a slang without host class. One could have compilation option per slang, maybe so
if the optimizer of a slang is broken, one could leave out the optimisation without affecting its host.
Need to learn more about the compilation chain to update my proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment