Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Remove special handling of BEGIN and make add_phaser a littler smarte…
…r about BEGIN (ends up much less code duplication than what we had before.)
  • Loading branch information
jnthn committed Jul 15, 2010
1 parent c9b7229 commit 8ce9aff
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 51 deletions.
52 changes: 21 additions & 31 deletions src/Perl6/Actions.pm
Expand Up @@ -530,34 +530,7 @@ method statement_control:sym<CONTROL>($/) {
make PAST::Stmts.new(:node($/));
}

method statement_prefix:sym<BEGIN>($/) {
# BEGIN is kinda tricky. We actually need to run the code in it with
# immediate effect, and then have the BEGIN block evaluate to what
# was produced at runtime. But if we're in a pre-compiled module, we
# need to run the lot. Thus we keep a "already computed BEGIN values"
# hash and don't re-run if the value is in that. Of course, we still
# don't handle looking at things in outer lexical scopes here.
our %BEGINDONE;
our $?RAKUDO_HLL;
my $past := $<blorst>.ast;
$past.blocktype('declaration');
$past := PAST::Block.new(
:hll($?RAKUDO_HLL),
PAST::Op.new( :pasttype('call'), :name('!YOU_ARE_HERE'), $past )
);
my $compiled := PAST::Compiler.compile($past);
my $begin_id := $past.unique('BEGINDONE_');
%BEGINDONE{$begin_id} := $compiled();
@BLOCK[0].loadinit.push(PAST::Op.new(
:pasttype('call'), :name('!begin_unless_begun'),
$begin_id, $past
));
make PAST::Var.new( :scope('keyed'),
PAST::Var.new( :name('%BEGINDONE'), :namespace(pir::split('::', 'Perl6::Actions')), :scope('package') ),
PAST::Val.new( :value($begin_id) )
);
}

method statement_prefix:sym<BEGIN>($/) { add_phaser($/, 'BEGIN'); }
method statement_prefix:sym<CHECK>($/) { add_phaser($/, 'CHECK'); }
method statement_prefix:sym<INIT>($/) { add_phaser($/, 'INIT'); }
method statement_prefix:sym<END>($/) { add_phaser($/, 'END'); }
Expand Down Expand Up @@ -617,10 +590,27 @@ method blorst($/) {
sub add_phaser($/, $bank) {
my $block := $<blorst>.ast;
my $subid := $block.subid();
@BLOCK[0].loadinit.push(
PAST::Op.new( :pasttype('call'), :name('!add_phaser'),
$bank, $block, :node($/))

# We always emit code to add the phaser.
my $add_phaser := PAST::Op.new(
:pasttype('call'), :name('!add_phaser'),
$bank, $block, :node($/)
);
@BLOCK[0].loadinit.push($add_phaser);

# If it's a BEGIN phaser, also need to add and run it immediately.
if $bank eq 'BEGIN' {
our $?RAKUDO_HLL;
my $fire := PAST::Op.new( :pasttype('call'), :name('!fire_phasers'), 'BEGIN' );
@BLOCK[0].loadinit.push($fire);
my $compiled := PAST::Compiler.compile(PAST::Block.new(
:hll($?RAKUDO_HLL),
$add_phaser, $fire
));
$compiled();
}

# Need to get return value of phaser at "runtime".
make PAST::Op.new( :pasttype('call'), :name('!get_phaser_result'), $subid );
}

Expand Down
20 changes: 0 additions & 20 deletions src/glue/phasers.pir
Expand Up @@ -95,26 +95,6 @@ Gets the result value that a phaser produced.
.return (result)
.end
=item !begin_unless_begun(id, block)
Runs a BEGIN block, unless it was already run during the parse, in which case
we don't bother. If we do have to run it, we put in place the computed value.

=cut

.sub '!begin_unless_begun'
.param string id
.param pmc block
$P0 = get_hll_global ['Perl6';'Actions'], '%BEGINDONE'
$P1 = $P0[id]
unless null $P1 goto begun
$P1 = block()
$P0[id] = $P1
begun:
.return ($P1)
.end

=back
=cut
Expand Down

0 comments on commit 8ce9aff

Please sign in to comment.