Skip to content
This repository was archived by the owner on Jun 2, 2021. It is now read-only.

Commit d863efa

Browse files
committed
#13 : Fix for loop + add test case
1 parent be4c73c commit d863efa

File tree

8 files changed

+318
-13
lines changed

8 files changed

+318
-13
lines changed

src/PhpToZephir/Converter/Printer/Stmt/ClassMethodPrinter.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ private function collectVars($node, array $vars = array())
233233
$vars[] = $stmt->keyVar->name;
234234
}
235235
$vars[] = $stmt->valueVar->name;
236+
} elseif ($stmt instanceof Stmt\For_) {
237+
foreach ($stmt->init as $init) {
238+
if ($init instanceof Expr\Assign) {
239+
$vars[] = $init->var->name;
240+
}
241+
}
236242
} elseif ($stmt instanceof Stmt\If_) {
237243
foreach ($this->nodeFetcher->foreachNodes($stmt) as $nodeData) {
238244
$node = $nodeData['node'];

src/PhpToZephir/Converter/Printer/Stmt/ForPrinter.php

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use PhpParser\Node\Stmt;
66
use PhpToZephir\Converter\SimplePrinter;
7+
use PhpParser\Node\Expr\BinaryOp;
8+
use PhpParser\Node\Expr\Variable;
79

810
class ForPrinter extends SimplePrinter
911
{
@@ -22,10 +24,50 @@ public static function getType()
2224
*/
2325
public function convert(Stmt\For_ $node)
2426
{
25-
return 'for '
26-
.$this->dispatcher->pCommaSeparated($node->init).';'.(!empty($node->cond) ? ' ' : '')
27-
.$this->dispatcher->pCommaSeparated($node->cond).';'.(!empty($node->loop) ? ' ' : '')
28-
.$this->dispatcher->pCommaSeparated($node->loop)
29-
.' {'.$this->dispatcher->pStmts($node->stmts)."\n".'}';
27+
$transformAsLoop = false;
28+
29+
if (is_array($node->init) && count($node->init) > 1) {
30+
throw new \Exception(sprintf('Cannot convert %s ', $this->dispatcher->pCommaSeparated($node->init)));
31+
}
32+
33+
if (is_array($node->cond) && count($node->cond) > 1) {
34+
throw new \Exception(sprintf('Cannot convert %s ', $this->dispatcher->pCommaSeparated($node->cond)));
35+
}
36+
37+
if (count($node->cond) === 0) {
38+
return (!empty($node->init) ? $this->dispatcher->pStmts($node->init) . "\n" : '')
39+
. 'loop'
40+
.' {'.$this->dispatcher->pStmts($node->stmts)."\n".$this->dispatcher->pStmts($node->loop)."\n".'}';
41+
} else {
42+
43+
$node = $this->findIteratorVar($node);
44+
45+
return 'for '
46+
.$this->dispatcher->p($node->init[0]->var).' in '.(!empty($node->cond) ? '' : '')
47+
.'range(' . $this->dispatcher->p($node->cond[0]->left).', '. $this->dispatcher->p($node->cond[0]->right) . ')'
48+
.' {'.$this->dispatcher->pStmts($node->stmts)."\n".'}';
49+
}
50+
}
51+
52+
/**
53+
* @param Stmt\For_ $node
54+
* @return \Stmt\For_
55+
*/
56+
private function findIteratorVar(Stmt\For_ $node)
57+
{
58+
$varName = $node->init[0]->var;
59+
$varValue = $node->init[0]->expr;
60+
61+
if ($node->cond[0]->left instanceof Variable && $node->cond[0]->left->name === $varName->name) {
62+
$node->cond[0]->left = $varValue;
63+
} elseif ($node->cond[0]->right instanceof Variable && $node->cond[0]->right->name === $varName->name) {
64+
$node->cond[0]->right = $varValue;
65+
}
66+
67+
if ($node->cond[0] instanceof BinaryOp\Smaller) {
68+
$node->cond[0]->right->value--;
69+
}
70+
71+
return $node;
3072
}
3173
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Test continue stmt
3+
--DESCRIPTION--
4+
Lowlevel basic test
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../../../../Bootstrap.php';
9+
10+
use PhpToZephir\EngineFactory;
11+
use PhpToZephir\Logger;
12+
use Symfony\Component\Console\Output\NullOutput;
13+
14+
$engine = EngineFactory::getInstance(new Logger(new NullOutput(), false));
15+
$code = <<<'EOT'
16+
<?php
17+
namespace Code\Loops\ForStmt;
18+
19+
class ForEquals
20+
{
21+
public function testSampleFromPhpDoc1()
22+
{
23+
for ($i = 1; $i <= 10; $i++) {
24+
echo $i;
25+
}
26+
}
27+
}
28+
EOT;
29+
echo $engine->convertString($code, true);
30+
31+
?>
32+
--EXPECT--
33+
namespace Code\Loops\ForStmt;
34+
35+
class ForEquals
36+
{
37+
public function testSampleFromPhpDoc1() -> void
38+
{
39+
var i;
40+
41+
for i in range(1, 10) {
42+
echo i;
43+
}
44+
}
45+
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Test continue stmt
3+
--DESCRIPTION--
4+
Lowlevel basic test
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../../../../Bootstrap.php';
9+
10+
use PhpToZephir\EngineFactory;
11+
use PhpToZephir\Logger;
12+
use Symfony\Component\Console\Output\NullOutput;
13+
14+
$engine = EngineFactory::getInstance(new Logger(new NullOutput(), false));
15+
$code = <<<'EOT'
16+
<?php
17+
namespace Code\Loops\ForStmt;
18+
19+
class ForMinus
20+
{
21+
public function testSimple()
22+
{
23+
for ($i = 0; $i < 10; $i++) {
24+
echo $i;
25+
}
26+
}
27+
}
28+
EOT;
29+
echo $engine->convertString($code, true);
30+
31+
?>
32+
--EXPECT--
33+
namespace Code\Loops\ForStmt;
34+
35+
class ForMinus
36+
{
37+
public function testSimple() -> void
38+
{
39+
var i;
40+
41+
for i in range(0, 9) {
42+
echo i;
43+
}
44+
}
45+
46+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--TEST--
2+
Test continue stmt
3+
--DESCRIPTION--
4+
Lowlevel basic test
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../../../../Bootstrap.php';
9+
10+
use PhpToZephir\EngineFactory;
11+
use PhpToZephir\Logger;
12+
use Symfony\Component\Console\Output\NullOutput;
13+
14+
$engine = EngineFactory::getInstance(new Logger(new NullOutput(), false));
15+
$code = <<<'EOT'
16+
<?php
17+
namespace Code\Loops\ForStmt;
18+
19+
class ForWithBreakOutside
20+
{
21+
public function testSampleFromPhpDoc2()
22+
{
23+
for ($i = 1; ; $i++) {
24+
if ($i > 10) {
25+
break;
26+
}
27+
echo $i;
28+
}
29+
}
30+
}
31+
EOT;
32+
echo $engine->convertString($code, true);
33+
34+
?>
35+
--EXPECT--
36+
namespace Code\Loops\ForStmt;
37+
38+
class ForWithBreakOutside
39+
{
40+
public function testSampleFromPhpDoc2() -> void
41+
{
42+
var i;
43+
44+
45+
let i = 1;
46+
loop {
47+
48+
if i > 10 {
49+
break;
50+
}
51+
echo i;
52+
53+
let i++;
54+
}
55+
}
56+
57+
}

tests/Converter/Code/Loops/ForStmt/SimpleFor.phpt renamed to tests/Converter/Code/Loops/ForStmt/ForWithCount.phpt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ $code = <<<'EOT'
1616
<?php
1717
namespace Code\Loops\ForStmt;
1818
19-
class SimpleFor
19+
class ForWithCount
2020
{
21-
public function test()
21+
public function testWithCall()
2222
{
2323
$myArray = array('test', '2');
2424
25-
/*for ($i = 0; count($myArray) < $i; $i++) {
26-
27-
}*/
25+
for ($i = 0; $i < count($myArray); $i++) {
26+
echo $i;
27+
}
2828
}
2929
}
3030
EOT;
@@ -34,14 +34,17 @@ echo $engine->convertString($code, true);
3434
--EXPECT--
3535
namespace Code\Loops\ForStmt;
3636

37-
class SimpleFor
37+
class ForWithCount
3838
{
39-
public function test() -> void
39+
public function testWithCall() -> void
4040
{
41-
var myArray;
41+
var myArray, i;
4242

4343

4444
let myArray = ["test", "2"];
45+
for i in range(0, count(myArray)) {
46+
echo i;
47+
}
4548
}
4649

4750
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
Test continue stmt
3+
--DESCRIPTION--
4+
Lowlevel basic test
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../../../../Bootstrap.php';
9+
10+
use PhpToZephir\EngineFactory;
11+
use PhpToZephir\Logger;
12+
use Symfony\Component\Console\Output\NullOutput;
13+
14+
$engine = EngineFactory::getInstance(new Logger(new NullOutput(), false));
15+
$code = <<<'EOT'
16+
<?php
17+
namespace Code\Loops\ForStmt;
18+
19+
class ForWithoutStmt
20+
{
21+
public function testSampleFromPhpDoc3()
22+
{
23+
$i = 1;
24+
for (; ; ) {
25+
if ($i > 10) {
26+
break;
27+
}
28+
echo $i;
29+
$i++;
30+
}
31+
}
32+
}
33+
EOT;
34+
echo $engine->convertString($code, true);
35+
36+
?>
37+
--EXPECT--
38+
namespace Code\Loops\ForStmt;
39+
40+
class ForWithoutStmt
41+
{
42+
public function testSampleFromPhpDoc3() -> void
43+
{
44+
var i;
45+
46+
let i = 1;
47+
loop {
48+
49+
if i > 10 {
50+
break;
51+
}
52+
echo i;
53+
let i++;
54+
55+
}
56+
}
57+
58+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
Test continue stmt
3+
--DESCRIPTION--
4+
Lowlevel basic test
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../../../Bootstrap.php';
9+
10+
use PhpToZephir\EngineFactory;
11+
use PhpToZephir\Logger;
12+
use Symfony\Component\Console\Output\NullOutput;
13+
14+
$engine = EngineFactory::getInstance(new Logger(new NullOutput(), false));
15+
$code = <<<'EOT'
16+
<?php
17+
18+
namespace Code\Method;
19+
20+
class TestUnset
21+
{
22+
public function simpleTest()
23+
{
24+
$foo = 'simpleTest';
25+
26+
unset($foo);
27+
}
28+
}
29+
EOT;
30+
echo $engine->convertString($code, true);
31+
32+
?>
33+
--EXPECT--
34+
namespace Code\Method;
35+
36+
class TestUnset
37+
{
38+
public function simpleTest() -> void
39+
{
40+
var foo;
41+
42+
let foo = "simpleTest";
43+
unset(foo);
44+
45+
}
46+
47+
}

0 commit comments

Comments
 (0)