Author: coke
Date: Wed Jun 6 19:13:13 2007
New Revision: 18852
Modified:
trunk/ (props changed)
trunk/compilers/past-pm/PAST/Node.pir
trunk/compilers/past-pm/POST/Grammar.tg
trunk/languages/perl6/src/PAST/Grammar.tg
trunk/languages/perl6/src/parser/grammar_rules.pg
Log:
[perl6]
* pass the 'for' sanity tests: "for @array {}" and "for @array -> $iter {}"
[past-pm]
* add a for pasttype that corresponds to the perl6 for usage.
Modified: trunk/compilers/past-pm/PAST/Node.pir
==============================================================================
--- trunk/compilers/past-pm/PAST/Node.pir (original)
+++ trunk/compilers/past-pm/PAST/Node.pir Wed Jun 6 19:13:13 2007
@@ -482,6 +482,10 @@
until - Evaluate the first child, if the result is
false then evaluate the second child and repeat.
+for - Iterate over the first child. For each element,
+ invoke the sub in the second child, passing the
+ element as the only parameter.
+
call - Call a subroutine, passing the results of any
child nodes as arguments. The subroutine to be
called is given by the node's C<name> attribute,
Modified: trunk/compilers/past-pm/POST/Grammar.tg
==============================================================================
--- trunk/compilers/past-pm/POST/Grammar.tg (original)
+++ trunk/compilers/past-pm/POST/Grammar.tg Wed Jun 6 19:13:13 2007
@@ -292,11 +292,62 @@
.return (ops)
}
-
transform until (PAST::Op) :language('PIR') {
.return tree.'get'('while', node)
}
+transform for (PAST::Op) :language('PIR') {
+ .local pmc ops
+ ops = new 'POST::Ops'
+ ops.'init'('node'=>node)
+
+ .local pmc looplabel, endlabel
+ .local string pasttype, n
+ pasttype = node.'pasttype'()
+ n = node.'unique'('_')
+ $S0 = concat pasttype, n
+ looplabel = ops.'new'('POST::Label', 'result'=>$S0)
+ $S0 = concat $S0, '_end'
+ endlabel = ops.'new'('POST::Label', 'result'=>$S0)
+
+ .local pmc collpast, collpost
+ collpast = node[0]
+ collpost = tree.'get'('post', collpast)
+
+ .local pmc collvar
+ collvar=collpost['result']
+
+ # reference our collection ...
+ ops.'push'(collpost)
+ # Create a temporary iterator for our collection
+ # $P<unique> = new .Iterator, obj from collection.
+ .local pmc iter
+ iter = ops.'unique'('$P')
+ ops.'push_pirop'('new',iter,'.Iterator',collvar)
+
+ # loop
+ ops.'push'(looplabel)
+ ops.'push_pirop'('unless', iter, endlabel)
+ # end unless iterator
+
+ # assign nextval to loop variable
+ .local pmc nextval
+ nextval = ops.'unique'('$P')
+ ops.'push_pirop'('shift', nextval, iter)
+
+ # execute block
+ .local pmc subpast, subpost
+ subpast = node[1]
+ subpost = tree.'get'('post', subpast)
+ $P0 = subpost[0] # get to the sub so we can add the param..
+ ops.'push'(subpost)
+ ops.'push_pirop'('call',subpost,nextval)
+
+ # goto loop
+ ops.'push_pirop'('goto', looplabel)
+ ops.'push'(endlabel)
+ .return (ops)
+}
transform try (PAST::Op) :language('PIR') {
.local pmc trypast, trypost, post, traplabel, endlabel
Modified: trunk/languages/perl6/src/PAST/Grammar.tg
==============================================================================
--- trunk/languages/perl6/src/PAST/Grammar.tg (original)
+++ trunk/languages/perl6/src/PAST/Grammar.tg Wed Jun 6 19:13:13 2007
@@ -155,6 +155,34 @@
.return tree.'get'('if', node, 'Perl6::Grammar::statement_control')
}
+transform for (Perl6::Grammar::statement_control) :language('PIR') {
+ .local pmc collection, pointy_sub, signature
+ collection = node['expression']
+ pointy_sub = node['pblock']
+ signature = pointy_sub['signature']
+
+ unless null signature goto ok_variable
+
+ # Fake up a new signature to replace our missing one...
+ $P1 = find_global 'Perl6::Grammar', 'signature'
+ signature = new .ResizablePMCArray
+ $P2 = $P1('$_','grammar' => 'Perl6::Grammar')
+ push signature, $P2
+
+ pointy_sub['signature'] = signature
+ok_variable:
+
+ .local pmc collpast, subpast
+ collpast = tree.'get'('past', collection, 'Perl6::Grammar::expression')
+ subpast = tree.'get'('past', pointy_sub, 'Perl6::Grammar::subroutine')
+
+ .local pmc past
+ past = new 'PAST::Op'
+ past.'init'(collpast, subpast, 'node'=>node, 'pasttype'=>'for')
+
+ .return (past)
+}
+
transform past (Perl6::Grammar::expression) :language('PIR') {
$P0 = node['expr']
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 Wed Jun 6 19:13:13 2007
@@ -92,15 +92,17 @@
[ <?ws>: [while|until] <expression: ;> ]
| $<KEY>:=[loop] [ \( <expression> ; <expression> ; <expression> \) ]?
<block>
- | $<KEY>:=[for] <expression: {> <block>
+ | $<KEY>:=[for] <expression> <pblock>
]
}
-
token statement_modifier {
<?ws> $<KEY>:=[if|unless|for|while|until] <expression: ;>
}
+token pblock {
+ <?ws> [<'->'> <?ws> <signature> <?ws>]? <block>
+}
token block {
<?ws>