# New Ticket Created by  Stuart Jansen 
# Please include the string:  [perl #50074]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=50074 >



This makes implementing lolcode ifthen support a tiny bit easier.
It looks like similiar support is already written for src/pmc/capture.pmc
---
 compilers/pct/src/PCT/Node.pir                |   20 ++++++++++++++++++++
 docs/pdds/pdd26_ast.pod                       |   10 ++++++++++
 languages/lolcode/src/parser/actions.pm       |   11 ++++-------
 runtime/parrot/library/Parrot/Capture_PIR.pir |   14 ++++++++++++++
 4 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/compilers/pct/src/PCT/Node.pir b/compilers/pct/src/PCT/Node.pir
index 1830868..43d7c10 100644
--- a/compilers/pct/src/PCT/Node.pir
+++ b/compilers/pct/src/PCT/Node.pir
@@ -106,10 +106,20 @@ children and attributes.  Returns the newly created node.
 
 Add C<child> to the beginning of the invocant's list of children.
 
+=item shift()
+
+Remove the first child from the invocant's list of children.
+Returns the child.
+
 =item push(child)
 
 Add C<child> to the end of the invocant's list of children.
 
+=item pop()
+
+Remove the last child from the invocant's list of children.
+Returns the child.
+
 =cut
 
 .sub 'unshift' :method
@@ -117,11 +127,21 @@ Add C<child> to the end of the invocant's list of children.
     unshift self, value
 .end
 
+.sub 'shift' :method
+    $P0 = shift self
+    .return ($P0)
+.end
+
 .sub 'push' :method
     .param pmc value
     push self, value
 .end
 
+.sub 'pop' :method
+    $P0 = pop self
+    .return ($P0)
+.end
+
 
 =item push_new(class, [child1, child2, ..., ] [attr1=>val1, attr2=>val2, ...])
 
diff --git a/docs/pdds/pdd26_ast.pod b/docs/pdds/pdd26_ast.pod
index 64ba0ac..738628d 100644
--- a/docs/pdds/pdd26_ast.pod
+++ b/docs/pdds/pdd26_ast.pod
@@ -61,10 +61,20 @@ Returns the newly created node.
 
 Add C<child> to the end of the node's array of children.
 
+=item pop()
+
+Remove the last child from the node's array of children.
+Returns the child.
+
 =item unshift(child)
 
 Add C<child> to the beginning of the node's array of children.
 
+=item shift()
+
+Remove the first child from the node's array of children.
+Returns the child.
+
 =item iterator( )
 
 Return a newly initialized C<Iterator> for the node's list
diff --git a/languages/lolcode/src/parser/actions.pm b/languages/lolcode/src/parser/actions.pm
index 6c9b06c..3c14cc9 100644
--- a/languages/lolcode/src/parser/actions.pm
+++ b/languages/lolcode/src/parser/actions.pm
@@ -97,15 +97,12 @@ method function($/) {
     make $past;
 }
 
-# Because we must bind the first <expression> to IT, we can't immediately
-# add $expr to $past. The code would probably be more clear if PAST::Node
-# supported shift() in addition to unshift().
 method ifthen($/) {
     my $count := +$<expression> - 1;
     my $expr  := $( $<expression>[$count] );
     my $then  := $( $<block>[$count] );
     $then.blocktype('immediate');
-    my $past := PAST::Op.new( $then,
+    my $past := PAST::Op.new( $expr, $then,
                               :pasttype('if'),
                               :node( $/ )
                             );
@@ -115,21 +112,21 @@ method ifthen($/) {
         $past.push( $else );
     }
     while ($count != 0) {
-        $past.unshift( $expr );
         $count := $count - 1;
         $expr  := $( $<expression>[$count] );
         $then  := $( $<block>[$count] );
         $then.blocktype('immediate');
-        $past  := PAST::Op.new( $then, $past,
+        $past  := PAST::Op.new( $expr, $then, $past,
                                :pasttype('if'),
                                :node( $/ )
                              );
     }
+    $expr := $past.shift();
     my $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'));
-    $past.unshift( $it );
     my $bind := PAST::Op.new( :pasttype('bind'), :node( $/ ) );
     $bind.push( $it );
     $bind.push( $expr );
+    $past.unshift( $it );
     my $past := PAST::Stmts.new( $bind, $past, :node( $/ ) );
     make $past;
 }
diff --git a/runtime/parrot/library/Parrot/Capture_PIR.pir b/runtime/parrot/library/Parrot/Capture_PIR.pir
index 0c89adb..8647f53 100644
--- a/runtime/parrot/library/Parrot/Capture_PIR.pir
+++ b/runtime/parrot/library/Parrot/Capture_PIR.pir
@@ -44,6 +44,13 @@ version until the Capture PMC is working properly.
 .end
 
 
+.sub 'shift_pmc' :vtable :method
+    $P0 = self.'get_array'()
+    $P0 = shift $P0
+    .return ($P0)
+.end
+
+
 .sub 'push_pmc' :vtable :method
     .param pmc val
     $P0 = self.'get_array'()
@@ -52,6 +59,13 @@ version until the Capture PMC is working properly.
 .end
 
 
+.sub 'pop_pmc' :vtable :method
+    $P0 = self.'get_array'()
+    $P0 = pop $P0
+    .return ($P0)
+.end
+
+
 .sub 'get_string_keyed_int' :vtable :method
     .param int key
     $S0 = ''

Reply via email to