Skip to content

Commit

Permalink
Implement box/unbox primitives, improved scope handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan O'Rear committed Jul 12, 2010
1 parent 41563a4 commit c1c8f20
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Body.pm
Expand Up @@ -19,7 +19,7 @@ use CodeGen ();
sub code {
my ($self) = @_;
if ($self->codegen) { return $self->codegen }
$self->codegen(CodeGen->new(name => $self->name));
$self->codegen(CodeGen->new(name => $self->name, body => $self));
my $cg = $self->codegen;
$self->do_enter($cg);
$self->do->item_cg($cg, $self);
Expand Down
28 changes: 24 additions & 4 deletions CodeGen.pm
Expand Up @@ -43,6 +43,8 @@ use 5.010;
'Kernel.ScalarContainerMO' => 'DynMetaObject',
'Kernel.MainlineContinuation' => 'DynBlockDelegate',
'Kernel.MakeSub' => 'IP6',
'Kernel.BoxAny' => 'Variable',
'Kernel.UnboxAny' => 'object',
);

has name => (isa => 'Str', is => 'ro');
Expand All @@ -60,6 +62,8 @@ use 5.010;

has auxdepths => (isa => 'HashRef', is => 'ro', default => sub { +{} });
has auxtypes => (isa => 'HashRef', is => 'ro', default => sub { +{} });
has body => (isa => 'Body', is => 'ro');
has bodies => (isa => 'ArrayRef', is => 'ro', default => sub { [] });

sub qm { "\"" . $_[0] . "\"" }

Expand Down Expand Up @@ -200,15 +204,15 @@ use 5.010;
}

sub scopelexget {
my ($self, $name, $body) = @_;
my ($self, $name) = @_;
my $body = $self->body // $self->bodies->[-1];
my ($order, $scope) = (0, $body);
while ($scope && !$scope->lexical->{$name}) {
$scope = $scope->outer;
$order++;
}
if (!$scope) {
die "Failed to resolve lexical $name in " .
$body->name;
die "Failed to resolve lexical $name in " . $body->name;
}
$self->lexget($order, $name);
}
Expand Down Expand Up @@ -354,6 +358,20 @@ use 5.010;
$self->_push($ty, "((CLRImportObject)$v).val");
}

sub box {
my ($self, $ty) = @_;
$self->scopelexget($ty);
$self->fetch;
$self->clr_call_direct('Kernel.BoxAny', 2);
}

sub unbox {
my ($self, $ty) = @_;
$self->fetch;
$self->clr_call_direct('Kernel.UnboxAny', 1);
$self->cast($ty);
}

sub clr_new {
my ($self, $class, $nargs) = @_;
my @args = reverse map { $self->_pop } 1 .. $nargs;
Expand Down Expand Up @@ -480,15 +498,17 @@ use 5.010;
}

sub open_protopad {
my ($self) = @_;
my ($self, $body) = @_;
$self->peek_aux('protopad');
$self->clr_new('Frame', 1);
$self->push_aux('protopad');
push @{ $self->bodies }, $body;
}

sub close_sub {
my ($self, $bodycg) = @_;
$self->pop_aux('protopad');
pop @{ $self->bodies };
$self->peek_aux('protopad');
my $op = $self->_pop;
my $pp = $self->_pop;
Expand Down
6 changes: 3 additions & 3 deletions Decl.pm
Expand Up @@ -26,7 +26,7 @@ use 5.010;
sub do_preinit {
my ($self, $cg, $body) = @_;
$self->code->outer($body);
$cg->open_protopad;
$cg->open_protopad($self->code);
$self->code->do_preinit($cg);
$cg->close_sub($self->code->code);
$cg->call_sub($self->has_var, 0);
Expand Down Expand Up @@ -64,7 +64,7 @@ use 5.010;
sub do_preinit {
my ($self, $cg, $body) = @_;
$self->code->outer($body);
$cg->open_protopad;
$cg->open_protopad($self->code);
$self->code->do_preinit($cg);
$cg->close_sub($self->code->code);
$cg->clr_call_direct('Kernel.NewROVar', 1);
Expand Down Expand Up @@ -154,7 +154,7 @@ use 5.010;
$self->body->outer($body);
$self->body->var($self->var);

$cg->open_protopad;
$cg->open_protopad($self->body);

$cg->peek_aux('how');
$cg->dup_fetch;
Expand Down
12 changes: 12 additions & 0 deletions Kernel.cs
Expand Up @@ -448,6 +448,18 @@ public class Kernel {
return n;
}

public static Variable BoxAny(object v, IP6 proto) {
DynObject n = new DynObject();
n.klass = ((DynObject)proto).klass;
n.slots["value"] = v;
return NewROVar(n);
}

public static object UnboxAny(IP6 o) {
// TODO: Check for compatibility?
return ((DynObject)o).slots["value"];
}

public static IP6 MakeSC(IP6 inside) {
DynObject n = new DynObject();
n.klass = ScalarContainerMO;
Expand Down
2 changes: 1 addition & 1 deletion Unit.pm
Expand Up @@ -28,7 +28,7 @@ use 5.010;
$cg->fetch;
$cg->cast('Frame');
$cg->push_aux('protopad');
$cg->open_protopad;
$cg->open_protopad($self->mainline);
$self->mainline->outer($self->setting) if $self->setting;
$self->mainline->do_preinit($cg);
$cg->close_sub($self->mainline->code);
Expand Down

0 comments on commit c1c8f20

Please sign in to comment.