Skip to content
This repository was archived by the owner on Oct 19, 2020. It is now read-only.

Commit 1a94bc6

Browse files
committed
Use specialized Node subclasses instead of misusing the CaseLabel
1 parent f00295d commit 1a94bc6

File tree

4 files changed

+77
-19
lines changed

4 files changed

+77
-19
lines changed

ChangeLog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ Switch expression for PHP - ChangeLog
33

44
## ?.?.? / ????-??-??
55

6+
## 0.3.0 / 2019-09-22
7+
8+
* Refactored code to use specialized `lang.ast.Node` subclasses instead of
9+
misusing the `CaseLabel` class from the `lang.ast` package.
10+
(@thekid)
11+
612
## 0.2.0 / 2019-09-09
713

814
* Updated dependency to newest version of `xp-framework/compiler`, see
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php namespace lang\ast\syntax\php;
2+
3+
use lang\ast\Node;
4+
use lang\ast\nodes\Braced;
5+
use lang\ast\nodes\InvokeExpression;
6+
use lang\ast\nodes\LambdaExpression;
7+
use lang\ast\nodes\Signature;
8+
9+
class CaseBlock extends Node {
10+
public $kind= 'caseblock';
11+
public $conditions, $statements;
12+
13+
public function __construct($conditions, $statements) {
14+
$this->conditions= $conditions;
15+
$this->statements= $statements;
16+
}
17+
18+
/**
19+
* Transforms case body into an expression by turning statement lists into an IIFE.
20+
*
21+
* @return lang.ast.Node
22+
*/
23+
public function expression() {
24+
return new InvokeExpression(new Braced(new LambdaExpression(new Signature([], null), $this->statements)), []);
25+
}
26+
27+
/** @return iterable */
28+
public function children() {
29+
foreach ((array)$this->conditions as $node) {
30+
yield $node;
31+
}
32+
foreach ($this->statements as $node) {
33+
yield $node;
34+
}
35+
}
36+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php namespace lang\ast\syntax\php;
2+
3+
use lang\ast\Node;
4+
5+
class CaseExpression extends Node {
6+
public $kind= 'caseexpr';
7+
public $conditions, $expression;
8+
9+
public function __construct($conditions, $expression) {
10+
$this->conditions= $conditions;
11+
$this->expression= $expression;
12+
}
13+
14+
/** @return lang.ast.Node */
15+
public function expression() {
16+
return $this->expression;
17+
}
18+
19+
/** @return iterable */
20+
public function children() {
21+
foreach ((array)$this->conditions as $node) {
22+
yield $node;
23+
}
24+
if (null !== $this->expression) {
25+
yield $this->expression;
26+
}
27+
}
28+
}

src/main/php/lang/ast/syntax/php/SwitchExpression.class.php

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,12 @@ public function setup($language, $emitter) {
5757
$parse->expecting('=>', 'switch');
5858
if ('{' === $parse->token->value) {
5959
$parse->forward();
60-
$return= $this->statements($parse);
60+
$cases[]= new CaseBlock($expr, $this->statements($parse));
6161
$parse->expecting('}', 'switch');
6262
} else {
63-
$return= $this->expression($parse, 0);
63+
$cases[]= new CaseExpression($expr, $this->expression($parse, 0));
6464
$parse->expecting(';', 'switch');
6565
}
66-
67-
$cases[]= new CaseLabel($expr, $return);
6866
}
6967
$parse->forward();
7068

@@ -77,17 +75,7 @@ public function setup($language, $emitter) {
7775
return $stmt;
7876
});
7977

80-
// Transforms case body into an expression by turning statement lists into an IIFE,
81-
// should that be necessary.
82-
$asExpr= function($body) {
83-
if ($body instanceof Node) {
84-
return $body;
85-
} else {
86-
return new InvokeExpression(new Braced(new LambdaExpression(new Signature([], null), $body)), []);
87-
}
88-
};
89-
90-
$emitter->transform('switchexpr', function($codegen, $node) use($asExpr) {
78+
$emitter->transform('switchexpr', function($codegen, $node) {
9179
static $is= [
9280
'string' => true,
9381
'int' => true,
@@ -104,9 +92,9 @@ public function setup($language, $emitter) {
10492
$ternary= new TernaryExpression(null, null, null);
10593
$ptr= &$ternary;
10694
foreach ($node->cases as $case) {
107-
if (null === $case->expression) {
108-
$ptr->otherwise= $asExpr($case->body);
109-
} else foreach ($case->expression as $i => $expr) {
95+
if (null === $case->conditions) {
96+
$ptr->otherwise= $case->expression();
97+
} else foreach ($case->conditions as $i => $expr) {
11098
if ($expr instanceof FunctionType || $expr instanceof ArrayType || $expr instanceof MapType) {
11199
$cond= new InvokeExpression(new Literal('is'), [new Literal('"'.$expr->name().'"'), $t]);
112100
} else if ($expr instanceof Type) {
@@ -120,7 +108,7 @@ public function setup($language, $emitter) {
120108
$cond= new BinaryExpression($t, '===', $expr);
121109
}
122110

123-
$ptr->otherwise= new Braced(new TernaryExpression($cond, $asExpr($case->body), null));
111+
$ptr->otherwise= new Braced(new TernaryExpression($cond, $case->expression(), null));
124112
$ptr= &$ptr->otherwise->expression;
125113
}
126114
}

0 commit comments

Comments
 (0)