Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support for StatementBlock, IfStatement and ForeachStatement.

  • Loading branch information...
commit bdccb774e1df635f544a9cdf0fba5fb595f0b98e 1 parent 778cfac
@jmalloc jmalloc authored
View
4 composer.lock
@@ -8,8 +8,8 @@
{
"package": "icecave/pasta-ast",
"version": "dev-master",
- "source-reference": "5394e8f3c68414e6ed8a44d2f9931d028fe9bd76",
- "commit-date": "1344151690"
+ "source-reference": "905385f758726fdf2a6db8e894e9de4cfc0b0427",
+ "commit-date": "1344332929"
},
{
"package": "icecave/visita",
View
68 lib/Icecave/Rasta/Generator.php
@@ -5,12 +5,15 @@
use Icecave\Pasta\AST\ClassModifier;
use Icecave\Pasta\AST\ContentBlock;
use Icecave\Pasta\AST\ExpressionStatement;
+use Icecave\Pasta\AST\ForeachStatement;
use Icecave\Pasta\AST\FunctionCall;
use Icecave\Pasta\AST\FunctionDefinition;
use Icecave\Pasta\AST\FunctionInterface;
use Icecave\Pasta\AST\FunctionParameter;
use Icecave\Pasta\AST\IVisitor;
+use Icecave\Pasta\AST\IfStatement;
use Icecave\Pasta\AST\InterfaceDefinition;
+use Icecave\Pasta\AST\IStatement;
use Icecave\Pasta\AST\Literal;
use Icecave\Pasta\AST\Node;
use Icecave\Pasta\AST\Operator\BinaryOperator;
@@ -26,11 +29,13 @@
use Icecave\Pasta\AST\PhpBlock;
use Icecave\Pasta\AST\QualifiedName;
use Icecave\Pasta\AST\ReturnStatement;
+use Icecave\Pasta\AST\StatementBlock;
use Icecave\Pasta\AST\Root;
class Generator implements IVisitor
{
- public function __construct($indentString = ' ') {
+ public function __construct($indentString = ' ')
+ {
$this->indentString = $indentString;
$this->indentLevel = 0;
$this->inlineExpressions = 0;
@@ -117,11 +122,7 @@ public function visitFunctionDefinition(FunctionDefinition $node)
$parameters[] = $parameter->accept($this);
}
$code = $this->indent($node->accessModifier()->value() . ' function ' . $node->name() . '(' . implode(', ', $parameters) . ')' . PHP_EOL);
- $code .= $this->indent('{' . PHP_EOL);
- $this->startIndent();
- $code .= $this->visitChildren($node);
- $this->endIndent();
- $code .= $this->indent('}' . PHP_EOL);
+ $code .= $node->statementBlock()->accept($this);
return $code;
}
@@ -134,6 +135,35 @@ public function visitReturnStatement(ReturnStatement $node)
return $this->indent('return' . $expression . ';' . PHP_EOL);
}
+ public function visitForeachStatement(ForeachStatement $node)
+ {
+ if ($keyName = $node->keyName()) {
+ $unpack = '$' . $keyName . ' => $' . $node->valueName();
+ } else {
+ $unpack = '$' . $node->valueName();
+ }
+ $code = $this->indent('foreach (' . $node->sequence()->accept($this) . ' as ' . $unpack . ')' . PHP_EOL);
+ $code .= $this->generateStatementCode($node->statement());
+ return $code;
+ }
+
+ public function visitIfStatement(IfStatement $node)
+ {
+ $code = $this->indent('if (' . $node->condition()->accept($this) . ')' . PHP_EOL);
+ $code .= $this->generateStatementCode($node->trueBranch());
+
+ $statement = $node->falseBranch();
+ if ($statement instanceof IfStatement) {
+ $code .= $this->indent('else');
+ $code .= ltrim($statement->accept($this));
+ } elseif ($statement) {
+ $code .= $this->indent('else' . PHP_EOL);
+ $code .= $this->generateStatementCode($statement);
+ }
+
+ return $code;
+ }
+
public function visitExpressionStatement(ExpressionStatement $node)
{
return $this->indent($node->expression()->accept($this) . ';' . PHP_EOL);
@@ -194,6 +224,18 @@ public function visitQualifiedName(QualifiedName $node)
return $node->string();
}
+ public function visitStatementBlock(StatementBlock $node)
+ {
+ $code = $this->indent('{' . PHP_EOL);
+ $this->startIndent();
+ $code .= $this->visitChildren($node);
+ $this->endIndent();
+ $code .= $this->indent('}' . PHP_EOL);
+ return $code;
+ }
+
+ // Operators ...
+
public function visitEquals(Equals $node)
{
return $this->generateBinaryOperatorCode('==', $node);
@@ -229,6 +271,8 @@ public function visitLogicalNot(LogicalNot $node)
return $this->generateUnaryOperatorCode('!', $node);
}
+ // Support ...
+
protected function indent($code, $level = null)
{
$indent = str_repeat($this->indentString, $level ?: $this->indentLevel);
@@ -276,6 +320,18 @@ protected function generatePolyadicOperatorCode($operator, PolyadicOperator $nod
return '(' . implode(' ' . $operator . ' ', $expressions) . ')';
}
+ protected function generateStatementCode(IStatement $node)
+ {
+ if ($node instanceof StatementBlock) {
+ return $node->accept($this);
+ }
+
+ $this->startIndent();
+ $code = $node->accept($this);
+ $this->endIndent();
+ return $code;
+ }
+
private $indentString;
private $indentLevel;
}
View
153 test/suite/Icecave/Rasta/GeneratorTest.php
@@ -5,10 +5,12 @@
use Icecave\Pasta\AST\ClassModifier;
use Icecave\Pasta\AST\ContentBlock;
use Icecave\Pasta\AST\ExpressionStatement;
+use Icecave\Pasta\AST\ForeachStatement;
use Icecave\Pasta\AST\FunctionCall;
use Icecave\Pasta\AST\FunctionDefinition;
use Icecave\Pasta\AST\FunctionInterface;
use Icecave\Pasta\AST\FunctionParameter;
+use Icecave\Pasta\AST\IfStatement;
use Icecave\Pasta\AST\InterfaceDefinition;
use Icecave\Pasta\AST\Literal;
use Icecave\Pasta\AST\Operator\Equals;
@@ -21,6 +23,7 @@
use Icecave\Pasta\AST\PhpBlock;
use Icecave\Pasta\AST\QualifiedName;
use Icecave\Pasta\AST\ReturnStatement;
+use Icecave\Pasta\AST\StatementBlock;
use Icecave\Pasta\AST\Root;
use PHPUnit_Framework_TestCase;
@@ -214,6 +217,114 @@ public function testVisitFunctionParameterWithDefaultValue()
$this->assertSame($expected, $code);
}
+ public function testForeachStatement()
+ {
+ $node = new ForeachStatement(
+ new Literal(123),
+ 'theKey',
+ 'theValue',
+ new StatementBlock
+ );
+ $code = $this->_generator->visitForeachStatement($node);
+
+ $expected = 'foreach (123 as $theKey => $theValue)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testForeachStatementWithoutKey()
+ {
+ $node = new ForeachStatement(
+ new Literal(123),
+ null,
+ 'theValue',
+ new StatementBlock
+ );
+ $code = $this->_generator->visitForeachStatement($node);
+
+ $expected = 'foreach (123 as $theValue)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testIfStatement()
+ {
+ $node = new IfStatement(new Literal(true));
+ $code = $this->_generator->visitIfStatement($node);
+
+ $expected = 'if (true)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testIfStatementElse()
+ {
+ $node = new IfStatement(
+ new Literal(true),
+ null,
+ new StatementBlock
+ );
+ $code = $this->_generator->visitIfStatement($node);
+
+ $expected = 'if (true)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $expected .= 'else' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testIfStatementElseIf()
+ {
+ $node = new IfStatement(
+ new Literal(true),
+ null,
+ new IfStatement(new Literal(false))
+ );
+ $code = $this->_generator->visitIfStatement($node);
+
+ $expected = 'if (true)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $expected .= 'elseif (false)' . PHP_EOL;
+ $expected .= '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testIfStatementSingleStatement()
+ {
+ $node = new IfStatement(
+ new Literal(true),
+ new ExpressionStatement(new FunctionCall(QualifiedName::fromString('foo')))
+ );
+ $code = $this->_generator->visitIfStatement($node);
+
+ $expected = 'if (true)' . PHP_EOL;
+ $expected .= ' foo();' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testIfStatementElseSingleStatement()
+ {
+ $node = new IfStatement(
+ new Literal(true),
+ new ExpressionStatement(new FunctionCall(QualifiedName::fromString('foo'))),
+ new ExpressionStatement(new FunctionCall(QualifiedName::fromString('bar')))
+ );
+ $code = $this->_generator->visitIfStatement($node);
+
+ $expected = 'if (true)' . PHP_EOL;
+ $expected .= ' foo();' . PHP_EOL;
+ $expected .= 'else' . PHP_EOL;
+ $expected .= ' bar();' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
public function testReturnStatement()
{
$node = new ReturnStatement;
@@ -223,6 +334,30 @@ public function testReturnStatement()
$this->assertSame($expected, $code);
}
+ public function testVisitStatementBlockEmpty()
+ {
+ $node = new StatementBlock;
+ $code = $this->_generator->visitStatementBlock($node);
+
+ $expected = '{' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
+ public function testVisitStatementBlock()
+ {
+ $node = new StatementBlock;
+ $node->add(
+ new ExpressionStatement(new FunctionCall(QualifiedName::fromString('foo')))
+ );
+ $code = $this->_generator->visitStatementBlock($node);
+
+ $expected = '{' . PHP_EOL;
+ $expected .= ' foo();' . PHP_EOL;
+ $expected .= '}' . PHP_EOL;
+ $this->assertSame($expected, $code);
+ }
+
public function testReturnStatementWithExpression()
{
$node = new ReturnStatement(new Literal(123));
@@ -316,7 +451,7 @@ public function testVisitFunctionCallNestedCallInReturnStatement()
$nestedNode0->add(new Literal('before'));
$nestedNode0->add($nestedNode1);
$nestedNode0->add(new Literal('after'));
-
+
$node = new ReturnStatement($nestedNode0);
$code = $this->_generator->visitReturnStatement($node);
@@ -344,12 +479,12 @@ public function testVisitLiteral()
$expected = "'<literal>'";
$this->assertSame($expected, $code);
}
-
+
public function testVisitEquals()
{
$node = new Equals(new Literal(123), new Literal(456));
$code = $this->_generator->visitEquals($node);
-
+
$expected = "(123 == 456)";
$this->assertSame($expected, $code);
}
@@ -358,7 +493,7 @@ public function testVisitStrictEquals()
{
$node = new StrictEquals(new Literal(123), new Literal(456));
$code = $this->_generator->visitStrictEquals($node);
-
+
$expected = "(123 === 456)";
$this->assertSame($expected, $code);
}
@@ -367,7 +502,7 @@ public function testVisitNotEquals()
{
$node = new NotEquals(new Literal(123), new Literal(456));
$code = $this->_generator->visitNotEquals($node);
-
+
$expected = "(123 != 456)";
$this->assertSame($expected, $code);
}
@@ -376,7 +511,7 @@ public function testVisitStrictNotEquals()
{
$node = new StrictNotEquals(new Literal(123), new Literal(456));
$code = $this->_generator->visitStrictNotEquals($node);
-
+
$expected = "(123 !== 456)";
$this->assertSame($expected, $code);
}
@@ -386,7 +521,7 @@ public function testVisitLogicalAnd()
$node = new LogicalAnd(new Literal(123), new Literal(456));
$node->add(new Literal(789));
$code = $this->_generator->visitLogicalAnd($node);
-
+
$expected = "(123 && 456 && 789)";
$this->assertSame($expected, $code);
}
@@ -396,7 +531,7 @@ public function testVisitLogicalOr()
$node = new LogicalOr(new Literal(123), new Literal(456));
$node->add(new Literal(789));
$code = $this->_generator->visitLogicalOr($node);
-
+
$expected = "(123 || 456 || 789)";
$this->assertSame($expected, $code);
}
@@ -405,7 +540,7 @@ public function testVisitLogicalNot()
{
$node = new LogicalNot(new Literal(123));
$code = $this->_generator->visitLogicalNot($node);
-
+
$expected = "(!123)";
$this->assertSame($expected, $code);
}
Please sign in to comment.
Something went wrong with that request. Please try again.