# 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 = ''