Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'multis'
  • Loading branch information
pmichaud committed Jun 3, 2010
2 parents 5fb2d58 + c6c97e8 commit eba2f2b
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
27 changes: 26 additions & 1 deletion src/NQP/Actions.pm
Expand Up @@ -389,7 +389,9 @@ method scope_declarator:sym<our>($/) { make $<scoped>.ast; }
method scope_declarator:sym<has>($/) { make $<scoped>.ast; }

method scoped($/) {
make $<declarator>.ast;
make $<declarator>
?? $<declarator>.ast
!! $<multi_declarator>.ast;
}

method declarator($/) {
Expand All @@ -398,6 +400,10 @@ method declarator($/) {
!! $<variable_declarator>.ast;
}

method multi_declarator:sym<multi>($/) { make $<declarator> ?? $<declarator>.ast !! $<routine_def>.ast }
method multi_declarator:sym<null>($/) { make $<declarator>.ast }


method variable_declarator($/) {
my $past := $<variable>.ast;
my $sigil := $<variable><sigil>;
Expand Down Expand Up @@ -463,7 +469,18 @@ method method_def($/) {

method signature($/) {
my $BLOCKINIT := @BLOCK[0][0];

for $<parameter> { $BLOCKINIT.push($_.ast); }

# Generate :multi pragma
if $*MULTINESS eq "multi" {
my @params;
@params.push('_') if $*METHODTYPE eq "Method";
for $BLOCKINIT.list {
@params.push($_.multitype // '_');
}
@BLOCK[0].multi(@params);
}
}

method parameter($/) {
Expand Down Expand Up @@ -495,6 +512,14 @@ method parameter($/) {
$past.viviself( $<default_value>[0]<EXPR>.ast );
}
unless $past.viviself { @BLOCK[0].arity( +@BLOCK[0].arity + 1 ); }

# We don't have support for multitype in PAST::Var (yet)
if $<typename> {
my @multitype;
for $<typename>[0]<name><identifier> { @multitype.push(~$_); }
$past.multitype(@multitype);
}

make $past;
}

Expand Down
18 changes: 16 additions & 2 deletions src/NQP/Grammar.pm
Expand Up @@ -7,7 +7,9 @@ method TOP() {
%*LANG<Regex-actions> := NQP::RegexActions;
%*LANG<MAIN> := NQP::Grammar;
%*LANG<MAIN-actions> := NQP::Actions;
my $*SCOPE := '';
my $*SCOPE := '';
my $*MULTINESS := '';
my $*METHODTYPE := '';
self.comp_unit;
}

Expand Down Expand Up @@ -226,6 +228,7 @@ token term:sym<variable> { <variable> }
token term:sym<package_declarator> { <package_declarator> }
token term:sym<scope_declarator> { <scope_declarator> }
token term:sym<routine_declarator> { <routine_declarator> }
token term:sym<multi_declarator> { <?before 'multi'|'proto'|'only'> <multi_declarator> }
token term:sym<regex_declarator> { <regex_declarator> }
token term:sym<statement_prefix> { <statement_prefix> }
token term:sym<lambda> { <?lambda> <pblock> }
Expand Down Expand Up @@ -274,7 +277,7 @@ token scope_declarator:sym<has> { <sym> <scoped('has')> }

rule scoped($*SCOPE) {
| <declarator>
| <typename>+ <declarator> # eventually <multi_declarator>
| <multi_declarator>
}

token typename { <name> }
Expand All @@ -299,13 +302,24 @@ rule routine_def {
}

rule method_def {
:my $*METHODTYPE := 'Method';
<deflongname>?
<.newpad>
[ '(' <signature> ')'
|| <.panic: 'Routine declaration requires a signature'> ]
<blockoid>
}

proto token multi_declarator { <...> }
token multi_declarator:sym<multi> {
<sym> :my $*MULTINESS := 'multi';
<.ws> [ <declarator> || <routine_def> || <.panic: 'Malformed multi'> ]
}
token multi_declarator:sym<null> {
:my $*MULTINESS := '';
<declarator>
}

token signature { [ [<.ws><parameter><.ws>] ** ',' ]? }

token parameter {
Expand Down
34 changes: 34 additions & 0 deletions t/nqp/49-multis.t
@@ -0,0 +1,34 @@
#! nqp

say("1..5");

our multi sub foo(Float $f) {
say("ok 1");
}

our multi sub foo(NQP::Grammar $f) {
say("ok 2");
}

our multi sub foo($def) {
say($def);
}

foo(42.01);
foo(NQP::Grammar.new);
foo("ok 3");

class Foo {
our multi method bar(Float $f) {
say("ok 4");
};

our multi method bar($f) {
say($f);
};
};

my $f := Foo.new;
$f.bar(43.5 - 0.5);
$f.bar("ok 5");

0 comments on commit eba2f2b

Please sign in to comment.