Skip to content

Commit

Permalink
Implement method declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan O'Rear committed Jul 12, 2010
1 parent 2917971 commit 5cd98c5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CodeGen.pm
Expand Up @@ -30,6 +30,8 @@ use 5.010;
{ Add => 'Void' },
'List<DynProtoMetaObject>' =>
{ Add => 'Void' },
'Double' =>
{ ToString => 'String' },

'Kernel.NewROVar' => 'Variable',
'Kernel.NewRWVar' => 'Variable',
Expand Down
28 changes: 28 additions & 0 deletions Decl.pm
Expand Up @@ -190,6 +190,34 @@ use 5.010;
no Moose;
}

{
package Decl::HasMethod;
use Moose;
extends 'Decl';

has name => (is => 'ro', isa => 'Str', required => 1);
has var => (is => 'ro', isa => 'Str', required => 1);

sub do_preinit {
my ($self, $cg, $body) = @_;
if (!$body->isa('Body::Class')) {
#TODO: Make this a sorry.
die "Tried to set a method outside a class!";
}
$cg->peek_aux('how');
$cg->dup_fetch;
$cg->clr_string($self->name);
$cg->clr_wrap;
$cg->clr_int(0);
$cg->clr_wrap;
$cg->scopelexget($self->var);
$cg->call_method(0, "add-scoped-method", 3);
}

__PACKAGE__->meta->make_immutable;
no Moose;
}

{
package Decl::Super;
use Moose;
Expand Down
35 changes: 35 additions & 0 deletions Niecza/Actions.pm
Expand Up @@ -699,6 +699,9 @@ sub routine_declarator {}
sub routine_declarator__S_sub { my ($cl, $M) = @_;
$M->{_ast} = $M->{routine_def}{_ast};
}
sub routine_declarator__S_method { my ($cl, $M) = @_;
$M->{_ast} = $M->{method_def}{_ast};
}

my $next_anon_id = 0;
sub gensym { 'anon_' . ($next_anon_id++) }
Expand Down Expand Up @@ -765,6 +768,38 @@ sub routine_def { my ($cl, $M) = @_;
outer_key => (($scope eq 'my') ? "&$m" : undef));
}

sub method_def { my ($cl, $M) = @_;
my $scope = $::SCOPE // 'has';
$scope = 'anon' if !$M->{longname};
my $name = $M->{longname} ? $cl->mangle_longname($M->{longname}) : undef;

if ($M->{trait}[0] || $M->{multisig}[0] || $M->{sigil}) {
$M->sorry("Method traits NYI");
return;
}

my $sym = ($scope eq 'my') ? ('&' . $name) : $cl->gensym;

if ($scope eq 'augment' || $scope eq 'supercede' || $scope eq 'state') {
$M->sorry("Illogical scope $scope for method");
return;
}

if ($scope eq 'our') {
$M->sorry("Packages NYI");
return;
}

my $bl = $cl->sl_to_block($M->{blockoid}{_ast}, subname => $name);
$cl->block_to_closure($bl, outer_key => $sym);

push @{ $cl->get_outer($::CURLEX)->{'!decls'} },
Decl::HasMethod->new(name => $name, var => $sym)
unless $scope eq 'anon';

$M->{_ast} = Op::Lexical->new(name => $sym);
}

sub block { my ($cl, $M) = @_;
$M->{_ast} = $cl->sl_to_block($M->{blockoid}{_ast});
}
Expand Down

0 comments on commit 5cd98c5

Please sign in to comment.