Author: bernhard
Date: Sun Dec 28 05:12:54 2008
New Revision: 34486
Modified:
trunk/languages/pipp/src/pct/actions.pm
trunk/languages/pipp/src/pct/grammar.pg
trunk/languages/pipp/t/php/closures.t
Log:
[Pipp] Start with support for closures.
Passing an argument to a closure is still broken.
Modified: trunk/languages/pipp/src/pct/actions.pm
==============================================================================
--- trunk/languages/pipp/src/pct/actions.pm (original)
+++ trunk/languages/pipp/src/pct/actions.pm Sun Dec 28 05:12:54 2008
@@ -161,6 +161,13 @@
make $( $<expression> );
}
+method closure_call($/) {
+ my $past := $( $<arguments> );
+ $past.push( $( $<var> ) );
+
+ make $past;
+}
+
method function_call($/) {
my $past := $( $<arguments> );
$past.name( ~$<FUNCTION_NAME> );
@@ -505,6 +512,23 @@
);
}
+method closure($/, $key) {
+ our @?BLOCK; # A stack of PAST::Block
+
+ if $key eq 'open' {
+ # note that $<param_list> creates a new PAST::Block.
+ @?BLOCK.unshift( $( $<param_list> ) );
+ }
+ else {
+ my $block := @?BLOCK.shift();
+
+ $block.control('return_pir');
+ $block.push( $( $<statement_list> ) );
+
+ make $block;
+ }
+}
+
method function_definition($/, $key) {
our @?BLOCK; # A stack of PAST::Block
Modified: trunk/languages/pipp/src/pct/grammar.pg
==============================================================================
--- trunk/languages/pipp/src/pct/grammar.pg (original)
+++ trunk/languages/pipp/src/pct/grammar.pg Sun Dec 28 05:12:54 2008
@@ -268,6 +268,11 @@
{*}
}
+rule closure_call {
+ <var> '(' <arguments> ')'
+ {*}
+}
+
rule function_call {
<FUNCTION_NAME> '(' <arguments> ')'
{*}
@@ -372,11 +377,13 @@
}
rule term {
- <method_call> {*} #= method_call
+ | <method_call> {*} #= method_call
+ | <closure> {*} #= closure
+ | <closure_call> {*} #= closure_call
| <function_call> {*} #= function_call
| <instantiate_array> {*} #= instantiate_array
| <constructor_call> {*} #= constructor_call
- | '(' <expression> {*} ')' #= expression
+ | '(' <expression> ')' {*} #= expression
| <literal> {*} #= literal
| <class_constant> {*} #= class_constant
| <constant> {*} #= constant
@@ -386,6 +393,13 @@
# declarations
+rule closure {
+ 'function' <param_list>
+ {*} #= open
+ '{' <statement_list> '}'
+ {*} #= close
+}
+
rule function_definition {
'function' <FUNCTION_NAME> <param_list>
{*} #= open
Modified: trunk/languages/pipp/t/php/closures.t
==============================================================================
--- trunk/languages/pipp/t/php/closures.t (original)
+++ trunk/languages/pipp/t/php/closures.t Sun Dec 28 05:12:54 2008
@@ -20,18 +20,42 @@
use FindBin;
use lib "$FindBin::Bin/../../../../lib", "$FindBin::Bin/../../lib";
-use Parrot::Test tests => 1;
+use Parrot::Test tests => 2;
-language_output_is( 'Pipp', <<'CODE', <<'OUT', 'function with no args', todo
=> 'not implemented yet' );
+=for perl6
+
+my $anon_no_args = sub () {
+ print "The function anon_no_args() has been called.\n";
+};
+
+$anon_no_args();
+
+=cut
+
+language_output_is( 'Pipp', <<'CODE', <<'OUT', 'anonymous function with no
args' );
+<?php
+
+$anon_no_args = function () {
+ echo "The function anon_no_args() has been called.\n";
+};
+
+$anon_no_args();
+
+?>
+CODE
+The function anon_no_args() has been called.
+OUT
+
+language_output_is( 'Pipp', <<'CODE', <<'OUT', 'anonymous function with one
arg', todo => 'broken' );
<?php
-$dummy_no_args = function () {
- echo "The function dummy_no_args() has been called.\n";
+$anon_one_arg = function ($arg_1) {
+ echo "'$arg_1' was passed to anon_one_arg().\n";
};
-$dummy_no_args();
+$anon_one_arg('one');
?>
CODE
-The function dummy_no_args() has been called.
+'one' was passed to anon_one_arg().
OUT