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>

Reply via email to