Skip to content

Instantly share code, notes, and snippets.

@bacek
Created May 17, 2010 09:34
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 bacek/403587 to your computer and use it in GitHub Desktop.
Save bacek/403587 to your computer and use it in GitHub Desktop.
diff --git a/src/NQP/Actions.pm b/src/NQP/Actions.pm
index 6a345c0..b404c48 100644
--- a/src/NQP/Actions.pm
+++ b/src/NQP/Actions.pm
@@ -380,7 +380,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($/) {
@@ -389,6 +391,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>;
@@ -454,7 +460,36 @@ method method_def($/) {
method signature($/) {
my $BLOCKINIT := @BLOCK[0][0];
+
for $<parameter> { $BLOCKINIT.push($_.ast); }
+
+ # Generate :multi pragma
+ if $*MULTINESS eq "multi" {
+ my $BLOCK := @BLOCK[0];
+ my @params;
+ for $BLOCKINIT.list {
+ @params.push(convert_multitype($_<multitype>));
+ }
+ my $signature := ":multi(" ~ pir::join(",", @params) ~ ")";
+ @BLOCK[0].pirflags($signature);
+ }
+}
+
+sub convert_multitype($type) {
+ my $multitype;
+ if !pir::defined($type) || !$type {
+ $multitype := '_';
+ }
+ else {
+ # Convert Foo::Bar into key representation ['Foo';'Bar']
+ $multitype := pir::new__Ps('StringBuilder');
+ my @parts;
+ for pir::split__Pss('::', $type) {
+ @parts.push("'" ~ $_ ~ "'");
+ }
+ $multitype := '[' ~ pir::join(';', @parts) ~ ']';
+ }
+ $multitype;
}
method parameter($/) {
@@ -486,6 +521,12 @@ 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> {
+ $past<multitype> := ~$<typename>[0];
+ }
+
make $past;
}
diff --git a/src/NQP/Grammar.pm b/src/NQP/Grammar.pm
index be2ae22..f5cab9e 100644
--- a/src/NQP/Grammar.pm
+++ b/src/NQP/Grammar.pm
@@ -7,7 +7,8 @@ method TOP() {
%*LANG<Regex-actions> := NQP::RegexActions;
%*LANG<MAIN> := NQP::Grammar;
%*LANG<MAIN-actions> := NQP::Actions;
- my $*SCOPE := '';
+ my $*SCOPE := '';
+ my $*MULTINESS := '';
self.comp_unit;
}
@@ -224,6 +225,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> }
@@ -272,7 +274,7 @@ token scope_declarator:sym<has> { <sym> <scoped('has')> }
rule scoped($*SCOPE) {
| <declarator>
- | <typename>+ <declarator> # eventually <multi_declarator>
+ | <multi_declarator>
}
token typename { <name> }
@@ -304,6 +306,16 @@ rule method_def {
<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 {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment