Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rewrite Signature:D eqv Signature:D
- no longer uses Parameter.perl, but Parameter:D eqv Parameter:D
- reduces set_multi_sig_comparator to a.signature eqv b.signature
- makes Buf.^pun 300x faster
  • Loading branch information
lizmat committed Mar 4, 2016
1 parent 94780d7 commit 2c552d9
Showing 1 changed file with 59 additions and 12 deletions.
71 changes: 59 additions & 12 deletions src/core/Signature.pm
Expand Up @@ -136,18 +136,65 @@ my class Signature { # declared in BOOTSTRAP
method returns() { $!returns }
}

multi sub infix:<eqv>(Signature $a, Signature $b) { $a.perl eq $b.perl }
multi sub infix:<eqv>(Signature \a, Signature \b) {

# we're us
return True if a =:= b;

# arity or count mismatch
return False if a.arity != b.arity || a.count != b.count;

# different number of parameters or no parameters
my $ap := nqp::getattr(a.params,List,'$!reified');
my $bp := nqp::getattr(b.params,List,'$!reified');
my Int $elems = nqp::elems($ap);
return False if nqp::isne_i($elems,nqp::elems($bp));
return True unless $elems;

# compare all positionals
my Int $i = -1;
Nil
while nqp::islt_i($i = nqp::add_i($i,1),$elems)
&& nqp::atpos($ap,$i) eqv nqp::atpos($bp,$i);

# not all same and different number of positionals
return False
if nqp::islt_i($i,$elems)
&& (!nqp::atpos($ap,$i).named || !nqp::atpos($bp,$i).named);

# create lookup table
my Int $j = $i = $i - 1;
my $lookup := nqp::hash;
while nqp::islt_i($j = nqp::add_i($j,1),$elems) {
my $p := nqp::atpos($ap,$j);
my $nn := nqp::getattr($p,Parameter,'$!named_names');
my str $key =
nqp::isnull($nn) ?? '' !! nqp::elems($nn) ?? nqp::atpos($nn,0) !! '';
die "Found named parameter '{
nqp::chars($key) ?? $key !! '(unnamed)'
}' twice in signature {a.perl}: {$p.perl} vs {nqp::atkey($lookup,$key).perl}"
if nqp::existskey($lookup,$key);
nqp::bindkey($lookup,$key,$p);
}

# named variable mismatch
while nqp::islt_i($i = nqp::add_i($i,1),$elems) {
my $p := nqp::atpos($bp,$i);
my $nn := nqp::getattr($p,Parameter,'$!named_names');
my str $key = nqp::elems($nn) ?? nqp::atpos($nn,0) !! '';

# named param doesn't exist in other or is not equivalent
return False
unless nqp::existskey($lookup,$key)
&& $p eqv nqp::atkey($lookup,$key);
}

# it's a match
True
}

Perl6::Metamodel::Configuration.set_multi_sig_comparator(
-> \a, \b { my $sa = a.signature.^find_private_method('gistperl')(
a.signature, True, :where(-> $ { Nil }));
with $sa {
my $sb = b.signature.^find_private_method('gistperl')(
b.signature, True, :where(-> $ { Nil }));
$sa eqv $sb;
}
else {
False;
}
});
-> \a, \b { a.signature eqv b.signature }
);

# vim: ft=perl6 expandtab sw=4

0 comments on commit 2c552d9

Please sign in to comment.