Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
possible fix for multi-method import bug
This patch allows you to import multi methods from several modules.
It merges the dispachtee lists. Two identical dispatchee signatures
dont clash yet, since I am unable to compare signatures.
  • Loading branch information
FROGGS committed Jan 2, 2013
1 parent 13e8052 commit 763a621
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions src/Perl6/World.pm
Expand Up @@ -264,14 +264,67 @@ class Perl6::World is HLL::World {
my %to_install;
my @clash;
for %stash {
if $target.symbol($_.key) {
# XXX TODO: Merge handling.
nqp::push(@clash, $_.key);
my $foreign_proto; # of the package we import
my $installed_proto; # of the current lexpad (target)

try {
$foreign_proto := self.find_symbol([$_.key]);
}

# It is a multi, so we need to install a proto in the lexpad and add dispatchees.
# Note: NQPCursorRole does not support get_bool, therefor skipped.
if $_.key ne 'NQPCursorRole' && $foreign_proto && $foreign_proto.is_dispatcher {
if $_.value && $_.value.is_dispatcher {
$foreign_proto := $_.value;
}

my @installed_dispatchees;

# Symbol is known, we need to add dispatchees to the proto that is already there.
if $target.symbol($_.key) {
# reuse the already installed proto
$installed_proto := $target.symbol($_.key)<value>;

# remember the installed dispatchees so that we dont add duplicates
for $installed_proto.dispatchees -> $dispatchee {
@installed_dispatchees.push: $dispatchee;
}
}
# Symbol not yet known, we should install a proto here.
else {
# we will add dispatchees to this later
$installed_proto := self.derive_dispatcher( $foreign_proto );

# install the foreign symbol (proto?) into our lexpad
self.install_lexical_symbol($target, $_.key, $_.value, :clone(1));
}

if $foreign_proto.dispatchees {
for $foreign_proto.dispatchees -> $foreign_dispatchee {
my $found_new := 0;
for @installed_dispatchees -> $installed_dispatchee {
if $installed_dispatchee =:= $foreign_dispatchee {
$found_new := 1;
last;
}
}

unless $found_new {
self.add_dispatchee_to_proto($installed_proto, $foreign_dispatchee);
}
}
}
}
else {
$target.symbol($_.key, :scope('lexical'), :value($_.value));
$target[0].push(QAST::Var.new( :scope('lexical'), :name($_.key), :decl('var') ));
%to_install{$_.key} := $_.value;
if $target.symbol($_.key) {
# If it is not a multi and the symbol is already there, it is a redeclaration.
nqp::push(@clash, $_.key);
}
else {
$target.symbol($_.key, :scope('lexical'), :value($_.value));
$target[0].push(QAST::Var.new( :scope('lexical'), :name($_.key), :decl('var') ));
%to_install{$_.key} := $_.value;
}
}
}
if +@clash {
Expand Down

0 comments on commit 763a621

Please sign in to comment.