From f11ad52fdacb47a529474807eb498cff5ee2ca55 Mon Sep 17 00:00:00 2001 From: jnthn Date: Wed, 25 Mar 2009 16:02:17 +0100 Subject: [PATCH] Implement START statements (not terms yet). Add S04-closure-traits/start.t to spectest.data. --- src/parser/actions.pm | 41 ++++++++++++++++++++++++++++++++++------- src/parser/grammar.pg | 7 +++++++ t/spectest.data | 1 + 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/parser/actions.pm b/src/parser/actions.pm index 102a9fe35bf..2915e0a8217 100644 --- a/src/parser/actions.pm +++ b/src/parser/actions.pm @@ -403,6 +403,26 @@ method begin_statement($/) { make PAST::Block.new(); } +method start_statement($/) { + # Create block. + my $past := $( $ ); + $past.blocktype('immediate'); + declare_implicit_routine_vars($past); + + # Mark block as needing to load state. + our @?BLOCK; + block_has_state(@?BLOCK[0]); + + # We now need to emit code to run the block only once, and store the + # result. We'll just piggy-back off state vars. + make PAST::Var.new( + :scope('state'), + :name($past.unique('start_block_')), + :viviself($past), + :isdecl(1) + ); +} + method end_statement($/) { my $past := $( $ ); $past.blocktype('declaration'); @@ -1888,13 +1908,7 @@ method scope_declarator($/) { else { $past.name('infix:,'); $past.pasttype('call'); } if $scope eq 'state' { $past := $scope; - unless $block { - $block[0].push(PAST::Op.new( - :pasttype('call'), - :name('!state_var_init') - )); - $block := 1; - } + block_has_state($block); } } make $past; @@ -3124,6 +3138,19 @@ sub prevent_null_return($block) { } } + +# This takes a block and ensures we emit code to load any associated state +# (START blocks, state variables) at block entry. +sub block_has_state($block) { + unless $block { + $block[0].push(PAST::Op.new( + :pasttype('call'), + :name('!state_var_init') + )); + $block := 1; + } +} + # Local Variables: # mode: cperl # cperl-indent-level: 4 diff --git a/src/parser/grammar.pg b/src/parser/grammar.pg index 64ad3d30070..777ecaa788e 100644 --- a/src/parser/grammar.pg +++ b/src/parser/grammar.pg @@ -262,6 +262,7 @@ rule statement_control { | {*} #= for_statement | {*} #= use_statement | {*} #= begin_statement + | {*} #= start_statement | {*} #= end_statement | {*} #= catch_statement | {*} #= control_statement @@ -345,6 +346,12 @@ rule begin_statement { {*} } +rule start_statement { + $=[START] + + {*} +} + rule end_statement { $=[END] diff --git a/t/spectest.data b/t/spectest.data index 5c318694583..1628a7007fc 100644 --- a/t/spectest.data +++ b/t/spectest.data @@ -121,6 +121,7 @@ S03-operators/value_equivalence.t S04-blocks-and-statements/pointy-rw.t S04-blocks-and-statements/pointy.t S04-closure-traits/end.t +S04-closure-traits/start.t S04-declarations/implicit-parameter.t S04-declarations/multiple.t S04-declarations/my.t