Skip to content

Commit 8c7d897

Browse files
authored
Merge pull request #3 from pug-php/ternary
Handle ternary expressions
2 parents 1e8fead + ed36218 commit 8c7d897

File tree

9 files changed

+84
-24
lines changed

9 files changed

+84
-24
lines changed

examples/ternary.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
a = {
2+
b: function () {
3+
return 42;
4+
}
5+
};
6+
foo = 9;
7+
bar = "9";
8+
result = foo == bar ? a.b() : null;
9+
10+
return result

examples/ternary.return

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
42

src/JsPhpize/Compiler/Compiler.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use JsPhpize\Nodes\Instruction;
1414
use JsPhpize\Nodes\Node;
1515
use JsPhpize\Nodes\Parenthesis;
16+
use JsPhpize\Nodes\Ternary;
1617
use JsPhpize\Nodes\Value;
1718
use JsPhpize\Nodes\Variable;
1819

@@ -218,10 +219,6 @@ public function visitNode(Node $node, $indent)
218219
if ($node instanceof Value) {
219220
$php = $node->getBefore() . $php . $node->getAfter();
220221
}
221-
if (!method_exists($this, $method)) {
222-
var_dump($method);
223-
exit;
224-
}
225222

226223
return $indent . $php;
227224
}
@@ -231,6 +228,13 @@ protected function visitParenthesis(Parenthesis $parenthesis, $indent)
231228
return '(' . $this->visitNodesArray($parenthesis->nodes, $indent, $parenthesis->separator) . ')';
232229
}
233230

231+
protected function visitTernary(Ternary $ternary, $indent)
232+
{
233+
return $this->visitNode($ternary->condition, $indent) .
234+
' ? ' . $this->visitNode($ternary->trueValue, $indent) .
235+
' : ' . $this->visitNode($ternary->falseValue, $indent);
236+
}
237+
234238
protected function visitVariable(Variable $variable, $indent)
235239
{
236240
$name = $variable->name;

src/JsPhpize/Nodes/Assignation.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ public function __construct($operator, Assignable $leftHand, Node $rightHand)
2727
throw new Exception($leftHand->getNonAssignableReason(), 9);
2828
}
2929

30-
if (!($rightHand instanceof Value) && (!($rightHand instanceof Block) || $rightHand->type !== 'function')) {
31-
throw new Exception('Only Value instance or Function block could be assigned.', 19);
32-
}
30+
$rightHand->mustBeAssignable();
3331

3432
$this->operator = $operator;
3533
$this->leftHand = $leftHand;

src/JsPhpize/Nodes/BracketsArray.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
class BracketsArray extends ArrayBase
66
{
7-
public function addItem(Constant $key, Value $value)
7+
public function addItem(Constant $key, Node $value)
88
{
9+
$value->mustBeAssignable();
10+
911
$this->data[] = array($key, $value);
1012
}
1113
}

src/JsPhpize/Nodes/Node.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@
22

33
namespace JsPhpize\Nodes;
44

5+
use JsPhpize\Parse\Exception;
6+
57
abstract class Node
68
{
79
public function __get($name)
810
{
911
return $this->$name;
1012
}
13+
14+
public function mustBeAssignable()
15+
{
16+
if (!($this instanceof Value) && (!($this instanceof Block) || $this->type !== 'function')) {
17+
throw new Exception('Only Value instance or Function block could be assigned.', 19);
18+
}
19+
}
1120
}

src/JsPhpize/Nodes/Ternary.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Ternary extends Value
2222
public function __construct(Value $condition, Value $trueValue, Value $falseValue)
2323
{
2424
$this->condition = $condition;
25-
$this->rueValue = $trueValue;
25+
$this->trueValue = $trueValue;
2626
$this->falseValue = $falseValue;
2727
}
2828
}

src/JsPhpize/Parser/Parser.php

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
use JsPhpize\Nodes\FunctionCall;
1414
use JsPhpize\Nodes\HooksArray;
1515
use JsPhpize\Nodes\Main;
16+
use JsPhpize\Nodes\Node;
1617
use JsPhpize\Nodes\Parenthesis;
18+
use JsPhpize\Nodes\Ternary;
1719
use JsPhpize\Nodes\Value;
1820
use JsPhpize\Nodes\Variable;
1921

@@ -296,6 +298,28 @@ protected function expectValue($next, $exception = null)
296298
}
297299
throw new Exception('Value expected before ' . $this->exceptionInfos(), 13);
298300
}
301+
if ($next->is('function')) {
302+
$function = new Block('function');
303+
$next = $this->get(0);
304+
if ($next->is('variable')) {
305+
$this->skip();
306+
$next = $this->get(0);
307+
}
308+
if (!$next->is('(')) {
309+
$this->unexpected($next);
310+
}
311+
$this->skip();
312+
$function->setValue($this->parseParentheses());
313+
$next = $this->get(0);
314+
if (!$next->is('{')) {
315+
$this->unexpected($next);
316+
}
317+
$this->skip();
318+
$this->parseBlock($function);
319+
$this->skip();
320+
321+
return $function;
322+
}
299323
$value = $this->getValueFromToken($next);
300324
if (!$value) {
301325
$this->unexpected($next);
@@ -304,6 +328,26 @@ protected function expectValue($next, $exception = null)
304328
return $value;
305329
}
306330

331+
protected function parseTernary(Node $condition)
332+
{
333+
$trueValue = $this->expectValue($this->next());
334+
$next = $this->next();
335+
if (!$next) {
336+
throw new Exception("Ternary expression not properly closed after '?' " . $this->exceptionInfos(), 14);
337+
}
338+
if (!$next->is(':')) {
339+
throw new Exception("':' expected but $next given " . $this->exceptionInfos(), 15);
340+
}
341+
$next = $this->next();
342+
if (!$next) {
343+
throw new Exception("Ternary expression not properly closed after ':' " . $this->exceptionInfos(), 16);
344+
}
345+
$falseValue = $this->expectValue($next);
346+
$next = $this->get(0);
347+
348+
return new Ternary($condition, $trueValue, $falseValue);
349+
}
350+
307351
protected function parseValue($token)
308352
{
309353
$debug = ($token->value === 'array_slice');
@@ -341,27 +385,19 @@ protected function parseValue($token)
341385
}
342386
if ($token->is('?')) {
343387
$this->skip();
344-
$trueValue = $this->expectValue($this->next());
345-
$next = $this->next();
346-
if (!$next) {
347-
throw new Exception("Ternary expression not properly closed after '?' " . $this->exceptionInfos(), 14);
348-
}
349-
if (!$next->is(':')) {
350-
throw new Exception("':' expected but $next given " . $this->exceptionInfos(), 15);
351-
}
352-
$next = $this->next();
353-
if (!$next) {
354-
throw new Exception("Ternary expression not properly closed after ':' " . $this->exceptionInfos(), 16);
355-
}
356-
$falseValue = $this->expectValue($this->next());
357-
$value = new Ternary($value, $trueValue, $falseValue);
388+
$value = $this->parseTernary($value);
358389

359390
continue;
360391
}
361392

362393
$this->skip();
363394
$nextValue = $this->expectValue($this->next());
364395
$value = new Dyiade($token->type, $value, $nextValue);
396+
$token = $this->get(0);
397+
if ($token && $token->is('?')) {
398+
$this->skip();
399+
$value = $this->parseTernary($value);
400+
}
365401

366402
continue;
367403
}

tests/render.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public function caseProvider()
1010

1111
$examples = __DIR__ . '/../examples';
1212
foreach (scandir($examples) as $file) {
13-
if (substr($file, -7) === '.return' && strpos($file, 'lambda') !== false) {
13+
if (substr($file, -7) === '.return') {
1414
$cases[] = array($file, substr($file, 0, -7) . '.js');
1515
}
1616
}

0 commit comments

Comments
 (0)