Author: bernhard
Date: Mon Aug 18 05:37:27 2008
New Revision: 30299
Modified:
trunk/languages/pipp/TODO
trunk/languages/pipp/docs/overview.pod
trunk/languages/pipp/src/pct/actions.pm
trunk/languages/pipp/src/pct/grammar.pg
trunk/languages/pipp/t/php/control_flow.t
Log:
[Pipp] Start with support for while- and for-loop
Modified: trunk/languages/pipp/TODO
==============================================================================
--- trunk/languages/pipp/TODO (original)
+++ trunk/languages/pipp/TODO Mon Aug 18 05:37:27 2008
@@ -1,14 +1,13 @@
# $Id$
# Just some notes, on what might be next:
---
-- Support for e.g. "{$a}"
+- Support for multiple "{$a}"
- Support for $php_errormessage
- Support for ini setting 'display_errors'
- Support for $argc and $argv
- Support for static variables
- Support for '==='
-- Support for 'for' loops
-- Support for 'while' loops
- Support for 'switch'
- Support for 'elsif'
+- Support for 'foreach'
Modified: trunk/languages/pipp/docs/overview.pod
==============================================================================
--- trunk/languages/pipp/docs/overview.pod (original)
+++ trunk/languages/pipp/docs/overview.pod Mon Aug 18 05:37:27 2008
@@ -6,7 +6,7 @@
=head1 What is Pipp?
-Pipp is an incomplete implementation of PHP on Parrot.
+Pipp aims to be a complete implementation of PHP on Parrot.
=head1 Goals
@@ -15,7 +15,7 @@
Provide a side by side comparison of different parsing and tree transformation
techniques.
-Currently there are three variants:
+Currently there are three variants of Pipp:
=over
@@ -29,7 +29,7 @@
=head1 Status
-20 out of 1322 tests in the PHP 5.3.0 test suite pass for the PCT variant.
+21 out of 1322 tests in the PHP 5.3.0 test suite pass for the PCT variant.
=head1 Dependencies
Modified: trunk/languages/pipp/src/pct/actions.pm
==============================================================================
--- trunk/languages/pipp/src/pct/actions.pm (original)
+++ trunk/languages/pipp/src/pct/actions.pm Mon Aug 18 05:37:27 2008
@@ -207,6 +207,31 @@
make $( $<block> );
}
+method while_statement($/) {
+ my $cond := $( $<expression> );
+ my $block := $( $<block> );
+
+ make PAST::Op.new( $cond,
+ $block,
+ :pasttype('while'),
+ :node($/) );
+}
+
+method for_statement($/) {
+ my $init := $( $<var_assign> );
+ my $cond := $( $<expression>[0] );
+ my $work := PAST::Stmts.new( $( $<block> ), $( $<expression>[1] ) );
+
+ my $while := PAST::Op.new(
+ $cond,
+ $work,
+ :pasttype('while'),
+ );
+
+ make PAST::Stmts.new( $init, $while );
+}
+
+
# Handle the operator precedence table.
method expression($/, $key) {
if ($key eq 'end') {
Modified: trunk/languages/pipp/src/pct/grammar.pg
==============================================================================
--- trunk/languages/pipp/src/pct/grammar.pg (original)
+++ trunk/languages/pipp/src/pct/grammar.pg Mon Aug 18 05:37:27 2008
@@ -38,6 +38,8 @@
rule statement { <echo_statement> {*} #= echo_statement
| <expression_statement> {*} #=
expression_statement
| <if_statement> {*} #= if_statement
+ | <while_statement> {*} #= while_statement
+ | <for_statement> {*} #= for_statement
| <inline_sea_tp1> {*} #= inline_sea_tp1
| <inline_sea_tp2> {*} #= inline_sea_tp2
| <var_assign> {*} #= var_assign
@@ -53,6 +55,15 @@
rule arguments { [ <expression> [',' <expression>]* ]?
{*} }
rule if_statement { 'if' '(' <expression> ')' <block> <else_clause>?
{*} }
rule else_clause { 'else' <block>
{*} }
+rule elsif_clause { 'elsif' '(' <expression> ')' <block>
{*} }
+rule while_statement { 'while' '(' <expression> ')' <block>
{*} }
+rule for_statement { 'for'
+ '('
+ <var_assign>
+ <expression> ';'
+ <expression>
+ ')' <block>
{*}
+ }
token inline_sea_tp1 { <.CODE_END_TP1> <SEA_empty_allowed>
<.CODE_START_TP1> {*} }
token inline_sea_tp2 { <.CODE_END_TP2> <SEA_empty_allowed>
<.CODE_START_TP2> {*} }
regex SEA_empty_allowed { <-[<]>*? <before '<'>
}
@@ -145,5 +156,6 @@
proto 'prefix:-' is tighter('infix:*') is pirop('n_neg') { ... }
proto 'prefix:+' is equiv('prefix:-') { ... }
+proto 'prefix:!' is equiv('prefix:-') { ... }
proto 'term:' is tighter('prefix:-') is parsed(&term) { ... }
Modified: trunk/languages/pipp/t/php/control_flow.t
==============================================================================
--- trunk/languages/pipp/t/php/control_flow.t (original)
+++ trunk/languages/pipp/t/php/control_flow.t Mon Aug 18 05:37:27 2008
@@ -19,31 +19,31 @@
use Parrot::Config ();
use Parrot::Test;
-use Test::More tests => 10;
+use Test::More tests => 13;
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'if, one statement
in block' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'if, one statement in block'
);
<?php
if (1)
{
echo "Hi\n";
}
?>
-END_CODE
+CODE
Hi
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'if, no statements
in block' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'if, no statements in block'
);
<?php
if (1)
{
}
echo "Hi\n";
?>
-END_CODE
+CODE
Hi
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'if, two
statements in block' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'if, two statements in
block' );
<?php
if (1)
{
@@ -51,11 +51,11 @@
echo "\n";
}
?>
-END_CODE
+CODE
Hi
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'if/else taking
if-branch' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'if/else taking if-branch' );
<?php
if (1)
{
@@ -66,11 +66,11 @@
echo "else block\n";
}
?>
-END_CODE
+CODE
if block
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'i/else taking
else-branchf' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'i/else taking else-branchf'
);
<?php
if (0)
{
@@ -81,11 +81,11 @@
echo "else block\n";
}
?>
-END_CODE
+CODE
else block
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED' . q{ }, 'positive
int' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT' . q{ }, 'positive int' );
<?php
if (1) {
?>
@@ -93,11 +93,11 @@
<?php
}
?>
-END_CODE
+CODE
Condition is true.
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'zero' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'zero' );
<?php
if (0) {
?>
@@ -106,11 +106,11 @@
}
?>
Condition is false.
-END_CODE
+CODE
Condition is false.
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'string' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'string' );
<?php
if ( 'false' ) {
?>
@@ -118,11 +118,11 @@
<?php
}
?>
-END_CODE
+CODE
The string 'false' is true.
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'string' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'string' );
<?php
if ( 'vrai' ) {
?>
@@ -136,12 +136,12 @@
<?php
}
?>
-END_CODE
+CODE
The string 'vrai' is true.
-END_EXPECTED
+OUTPUT
-language_output_is( 'Pipp', <<'END_CODE', <<'END_EXPECTED', 'string' );
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'string' );
<?php
if ( 0 ) {
?>
@@ -155,6 +155,60 @@
<?php
}
?>
-END_CODE
+CODE
The integer 0 is false.
-END_EXPECTED
+OUTPUT
+
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'while loop' );
+<?php
+
+$count = 0;
+while ( $count < 10 ) { $count++; echo "round $count\n"; }
+CODE
+round 1
+round 2
+round 3
+round 4
+round 5
+round 6
+round 7
+round 8
+round 9
+round 10
+OUTPUT
+
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'while with negated
expression' );
+<?php
+
+$count = 0;
+while ( ! ( $count >= 10 ) ) { $count++; echo "round $count\n"; }
+CODE
+round 1
+round 2
+round 3
+round 4
+round 5
+round 6
+round 7
+round 8
+round 9
+round 10
+OUTPUT
+
+language_output_is( 'Pipp', <<'CODE', <<'OUTPUT', 'classic for-loop' );
+<?php
+
+$count = 0;
+for ( $count = 0; $count < 10; $count++ ) { echo "round $count\n"; }
+CODE
+round 0
+round 1
+round 2
+round 3
+round 4
+round 5
+round 6
+round 7
+round 8
+round 9
+OUTPUT