Author: coke
Date: Thu Jun 7 13:22:22 2007
New Revision: 18864
Modified:
trunk/ (props changed)
trunk/compilers/past-pm/POST/Node.pir
trunk/languages/perl6/perl6.pir
trunk/languages/perl6/src/PAST/Grammar.tg
trunk/languages/perl6/src/parser/grammar_rules.pg
Log:
[perl6] add support for END blocks. This is kind of a hack, working around the
lack of a parrot feature, but, it does reduce the number of failing perl six
sanity .t to one.
Modified: trunk/compilers/past-pm/POST/Node.pir
==============================================================================
--- trunk/compilers/past-pm/POST/Node.pir (original)
+++ trunk/compilers/past-pm/POST/Node.pir Thu Jun 7 13:22:22 2007
@@ -344,8 +344,15 @@
$S0 = self.'blocktype'()
if $S0 == 'declaration' goto skip_declaration
code.'emit'(" %0 = find_name %1", value, name)
+ if $S0 == 'END' goto add_end_block
skip_declaration:
.return (code)
+ add_end_block:
+ $S1 = code.'unique'('$P')
+ code.'emit'(" %0 = find_global '_perl6', '%BLOCKS'", $S1)
+ code.'emit'(" %0 = %0['END']", $S1)
+ code.'emit'(" push %0, %1", $S1, value)
+ .return (code)
.end
Modified: trunk/languages/perl6/perl6.pir
==============================================================================
--- trunk/languages/perl6/perl6.pir (original)
+++ trunk/languages/perl6/perl6.pir Thu Jun 7 13:22:22 2007
@@ -51,11 +51,51 @@
=cut
+.const int SEVERITY_SLOT = 2 # _severity
+
.sub 'main' :main
.param pmc args
- load_bytecode 'PGE/Dumper.pbc'
+
+ $P0 = new .ResizablePMCArray
+ $P1 = new .Hash
+ $P1['END'] = $P0
+ store_global '_perl6', '%BLOCKS', $P1
+
$P0 = compreg 'Perl6'
- .return $P0.'command_line'(args)
+
+ push_eh exit_handler
+ $P1 = $P0.'command_line'(args)
+ clear_eh
+
+ goto do_END_blocks
+
+# Run all the END blocks that have been registered.
+
+exit_handler:
+ .get_results($P0,$S0)
+ .include 'except_severity.pasm'
+ $I0 = $P0[SEVERITY_SLOT]
+ if $I0 != .EXCEPT_EXIT goto rethrow_error
+
+do_END_blocks:
+ .include 'iterator.pasm'
+
+ $P0 = find_global '_perl6', '%BLOCKS'
+ if null $P0 goto done
+ $P0 = $P0['END']
+ if null $P0 goto done
+ $P1 = new .Iterator, $P0
+ $P1 = .ITERATE_FROM_END
+loop_blocks:
+ unless $P1 goto done
+ $P2 = pop $P1
+ $P2()
+ goto loop_blocks
+done:
+ end
+
+rethrow_error:
+ rethrow $P0
.end
.include 'src/parser/expression.pir'
Modified: trunk/languages/perl6/src/PAST/Grammar.tg
==============================================================================
--- trunk/languages/perl6/src/PAST/Grammar.tg (original)
+++ trunk/languages/perl6/src/PAST/Grammar.tg Thu Jun 7 13:22:22 2007
@@ -65,6 +65,8 @@
unless null $P0 goto block
$P0 = node['statement_control']
unless null $P0 goto statement_control
+ $P0 = node['closure_trait']
+ unless null $P0 goto closure_trait
expression:
$P0 = node['expression']
@@ -79,6 +81,8 @@
.return ($P1)
statement_control:
.return tree.'get'('past', $P0, 'Perl6::Grammar::statement_control')
+ closure_trait:
+ .return tree.'get'('past', $P0, 'Perl6::Grammar::closure_trait')
}
@@ -650,6 +654,14 @@
.return (past)
}
+transform past (Perl6::Grammar::closure_trait) :language('PIR') {
+ $P0 = node['block']
+ $P1 = tree.'get'('past', $P0, 'Perl6::Grammar::block')
+ # obviously, this needs to be expanded to deal with other types.
+ $P1.'blocktype'('END')
+ .return ($P1)
+}
+
=back
=cut
Modified: trunk/languages/perl6/src/parser/grammar_rules.pg
==============================================================================
--- trunk/languages/perl6/src/parser/grammar_rules.pg (original)
+++ trunk/languages/perl6/src/parser/grammar_rules.pg Thu Jun 7 13:22:22 2007
@@ -113,6 +113,7 @@
token closure_trait {
+ <?ws>?
$<trait>:=[ BEGIN | CHECK | INIT | END | START
| ENTER | LEAVE | KEEP | UNDO
| FIRST | NEXT | LAST