Skip to content

Commit

Permalink
Implement while and until loops
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan O'Rear committed Jul 13, 2010
1 parent 7241a06 commit 7a830e4
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Niecza/Actions.pm
Expand Up @@ -888,6 +888,18 @@ sub statement_control__S_if { my ($cl, $M) = @_;
false => $else);
}

sub statement_control__S_while { my ($cl, $M) = @_;
$M->{_ast} = Op::WhileLoop->new(check => $M->{xblock}{_ast}[0],
body => $cl->block_to_immediate($M->{xblock}{_ast}[1]),
until => 0, once => 0);
}

sub statement_control__S_until { my ($cl, $M) = @_;
$M->{_ast} = Op::WhileLoop->new(check => $M->{xblock}{_ast}[0],
body => $cl->block_to_immediate($M->{xblock}{_ast}[1]),
until => 1, once => 0);
}

sub package_def { my ($cl, $M) = @_;
if ($::PKGDECL ne 'class') {
$M->sorry('Non-class package definitions are not yet supported');
Expand Down
37 changes: 37 additions & 0 deletions Op.pm
Expand Up @@ -177,6 +177,43 @@ use 5.010;
no Moose;
}

{
package Op::WhileLoop;
use Moose;
extends 'Op';

has check => (isa => 'Op', is => 'ro', required => 1);
has body => (isa => 'Op', is => 'ro', required => 1);
has once => (isa => 'Bool', is => 'ro', required => 1);
has until => (isa => 'Bool', is => 'ro', required => 1);

sub void_cg {
my ($self, $cg, $body) = @_;

my $l1 = $cg->label;
my $l2 = $self->once ? 0 : $cg->label;

$cg->goto($l2) unless $self->once;
$cg->labelhere($l1);
$self->body->void_cg($cg, $body);
$cg->labelhere($l2) unless $self->once;
$self->check->item_cg($cg, $body);
$cg->fetch;
$cg->unbox('Boolean');
my $m = $self->until ? 'ncgoto' : 'cgoto';
$cg->$m($l1);
}

sub item_cg {
my ($self, $cg, $body) = @_;
$self->void_cg($cg, $body);
$cg->push_null('Variable');
}

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

{
package Op::Num;
use Moose;
Expand Down

0 comments on commit 7a830e4

Please sign in to comment.