Skip to content

Commit

Permalink
Merge branch 'master' of git@github.com:rakudo/rakudo
Browse files Browse the repository at this point in the history
  • Loading branch information
pmichaud committed Apr 20, 2009
2 parents 61c827b + cb2b28b commit 07bfffc
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 14 deletions.
83 changes: 83 additions & 0 deletions src/builtins/guts.pir
Expand Up @@ -825,6 +825,89 @@ and C<type>.
.end


=item !var_trait(var, type, trait, arg?)

=cut

.sub '!var_trait'
.param pmc var
.param string type
.param string trait
.param pmc arg :optional
.param int has_arg :opt_flag

if has_arg goto have_arg
null arg
have_arg:

$S0 = concat '!var_trait_', trait
$P0 = find_name $S0
if null $P0 goto done
.tailcall $P0(trait, var, arg)
done:
.return (var)
.end


=item !var_trait_verb(var, trait, arg?)

=cut

.sub '!var_trait_verb'
.param pmc var
.param string trait
.param pmc arg :optional
.param int has_arg :opt_flag

if has_arg goto have_arg
null arg
have_arg:

$S0 = substr trait, 11
$S0 = concat '!var_trait_verb_', $S0
$P0 = find_name $S0
if null $P0 goto done
.tailcall $P0(var, arg)
done:
.return (var)
.end


=item !var_trait_verb_of(var, arg?)

Sets the type constraint on the container.

=cut

.sub '!var_trait_verb_of'
.param pmc var
.param pmc arg
$I0 = isa var, 'Perl6Scalar'
unless $I0 goto non_scalar
setprop var, 'type', arg
.return (var)
non_scalar:
$I0 = isa var, 'Perl6Array'
if $I0 goto array
$I0 = isa var, 'Perl6Hash'
if $I0 goto hash
$I0 = isa var, 'Sub'
if $I0 goto code
array:
$P0 = get_hll_global 'Positional'
goto mixin
hash:
$P0 = get_hll_global 'Associative'
goto mixin
code:
$P0 = get_hll_global 'Callable'
goto mixin
mixin:
$P0 = $P0.'!select'(arg)
.tailcall 'infix:does'(var, $P0)
.end


=item !sub_trait(sub, type, trait, arg?)

=cut
Expand Down
37 changes: 23 additions & 14 deletions src/parser/actions.pm
Expand Up @@ -1904,30 +1904,39 @@ method scope_declarator($/) {
$block[0].push( $has );
}
else {
# $scope eq 'package' | 'lexical'
# $scope eq 'package' | 'lexical' | 'state'
my $viviself := PAST::Op.new( :pirop('new PsP'), $var<itype> );
if $init_value { $viviself.push( $init_value ); }
$var.viviself( $viviself );
if $var<traitlist> {
for @($var<traitlist>) {
if substr($_[0], 0, 11) eq 'trait_verb:' {
$_.name('!var_trait_verb');
}
else {
$_.name('!var_trait');
}
$_.unshift($var);
$var := $_;
}
}
if $type {
if $var<sigil> eq '$' {
$var := PAST::Op.new( :pirop('setprop'), $var, 'type', $type );
$var := PAST::Op.new(
:pasttype('call'),
:name('!var_trait_verb_of'),
$var, $type
);
}
else {
my $role_type;
if $var<sigil> eq '@' { $role_type := 'Positional' }
elsif $var<sigil> eq '%' { $role_type := 'Associative' }
elsif $var<sigil> eq '' { $role_type := 'Callable' } # & becomes null sigil
else { $/.panic("Cannot handle typed variables with sigil " ~ $var<sigil>); }
if $var<sigil> ne '@' && $var<sigil> ne '%' && $var<sigil> ne '' {
$/.panic("Cannot handle typed variables with sigil " ~ $var<sigil>);
}
$var := PAST::Op.new(
:pasttype('call'),
:name('infix:does'),
:name('!var_trait_verb_of'),
$var,
PAST::Op.new(
:pasttype('callmethod'),
:name('!select'),
PAST::Var.new( :name($role_type), :scope('package') ),
$type
)
$type
);
}
}
Expand Down

0 comments on commit 07bfffc

Please sign in to comment.