Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"require" : {
"xp-framework/core": "^12.0 | ^11.6 | ^10.16",
"xp-framework/reflection": "^3.2 | ^2.15",
"xp-framework/ast": "^12.1",
"xp-framework/ast": "^12.2",
"php" : ">=7.4.0"
},
"require-dev" : {
Expand Down
37 changes: 28 additions & 9 deletions src/main/php/lang/ast/emit/PHP.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,15 @@ protected function emitFunction($result, $function) {
$result->out->write('function '.($function->signature->byref ? '&' : '').$function->name);
$this->emitSignature($result, $function->signature);

$result->out->write('{');
$this->emitAll($result, $function->body);
$result->out->write('}');
if ($function->body instanceof Block) {
$result->out->write('{');
$this->emitAll($result, $function->body->statements);
$result->out->write('}');
} else {
$result->out->write('{ return ');
$this->emitOne($result, $function->body);
$result->out->write('; }');
}

$result->locals= $locals;
}
Expand All @@ -371,9 +377,15 @@ protected function emitClosure($result, $closure) {
$closure->static ? $result->out->write('static function') : $result->out->write('function');
$this->emitSignature($result, $closure->signature, $closure->use);

$result->out->write('{');
$this->emitAll($result, $closure->body);
$result->out->write('}');
if ($closure->body instanceof Block) {
$result->out->write('{');
$this->emitAll($result, $closure->body->statements);
$result->out->write('}');
} else {
$result->out->write('{ return ');
$this->emitOne($result, $closure->body);
$result->out->write('; }');
}

$result->locals= $locals;
}
Expand All @@ -384,6 +396,7 @@ protected function emitLambda($result, $lambda) {
$lambda->static ? $result->out->write('static fn') : $result->out->write('fn');
$this->emitSignature($result, $lambda->signature);
$result->out->write('=>');

$this->emitOne($result, $lambda->body);

$result->locals= $locals;
Expand Down Expand Up @@ -719,7 +732,7 @@ protected function emitMethod($result, $method) {
if (null === $method->body) {
$result->out->write(';');
} else {
$result->out->write(' {');
$result->out->write('{');

// Emit non-constant parameter defaults
foreach ($init as $param) {
Expand All @@ -739,8 +752,14 @@ protected function emitMethod($result, $method) {
$result->codegen->scope[0]->init= [];
}

$this->emitAll($result, $method->body);
$result->out->write('}');
if ($method->body instanceof Block) {
$this->emitAll($result, $method->body->statements);
$result->out->write('}');
} else {
$result->out->write('return ');
$this->emitOne($result, $method->body);
$result->out->write('; }');
}
}

foreach ($promoted as $param) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ public function run($type) {
$value= "Test";
return match ($type) {
"PING" => "+PONG",
"MSG" => {
"MSG" {
$reply= "Re: ".$value;
return "+OK $reply";
},
default => {
default {
return "-ERR Unknown ".$type;
}
};
Expand Down Expand Up @@ -243,7 +243,7 @@ public function run() {
$test= "Original";
(function() use(&$test) {
match (true) {
true => {
true {
$test= "Changed";
return true;
}
Expand Down
31 changes: 22 additions & 9 deletions src/test/php/lang/ast/unittest/emit/InvocationTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,32 +78,45 @@ public function run() {
));
}

#[Test]
public function closure() {
#[Test, Values(['function() { return "closure"; }', 'function() => "closure"'])]
public function closure($expr) {
Assert::equals('closure', $this->run(
'class %T {

public function run() {
$f= function() { return "closure"; };
$f= '.$expr.';
return $f();
}
}'
));
}

#[Test]
public function global_function() {
Assert::equals('function', $this->run(
'function fixture() { return "function"; }
class %T {
#[Test, Values(['fn() { return "lambda"; }', 'fn() => "lambda"'])]
public function lambda($expr) {
Assert::equals('lambda', $this->run(
'class %T {

public function run() {
return fixture();
$f= '.$expr.';
return $f();
}
}'
));
}

#[Test, Values(['function t%1$s() { return "function"; }', 'function t%1$s() => "function";'])]
public function global_function($decl) {
Assert::equals('function', $this->run(sprintf(
$decl.' class %%T {

public function run() {
return t%1$s();
}
}',
uniqid()
)));
}

#[Test]
public function function_self_reference() {
Assert::equals(13, $this->run(
Expand Down
6 changes: 3 additions & 3 deletions src/test/php/lang/ast/unittest/emit/LambdasTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public function run() {
public function with_block() {
$r= $this->run('class %T {
public function run() {
return fn() => {
return fn() {
$a= 1;
return $a + 1;
};
Expand All @@ -208,7 +208,7 @@ public function capturing_with_block() {
$r= $this->run('class %T {
public function run() {
$a= 1;
return fn() => {
return fn() {
return $a + 1;
};
}
Expand All @@ -231,7 +231,7 @@ public function issue_176() {
$r= $this->run('class %T {
public function run(iterable $records) {
$nonNull= fn($record) => null !== $record;
$process= fn($records, $filter) => {
$process= fn($records, $filter) {
foreach ($records as $record) {
if ($filter($record)) yield $record;
}
Expand Down
Loading