Skip to content

Commit

Permalink
Fix emitting captures and return types for closures
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Jan 6, 2024
1 parent 01d0743 commit 5111675
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ XP Compiler ChangeLog

## ?.?.? / ????-??-??

* Fixed emitting captures and return types for closures - @thekid

## 8.17.0 / 2023-10-03

* Merged PR #177: Remove Result::$stack. Use local variables for backing
Expand Down
17 changes: 9 additions & 8 deletions src/main/php/lang/ast/emit/PHP.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,21 @@ protected function emitParameter($result, $parameter) {
$result->locals[$parameter->name]= true;
}

protected function emitSignature($result, $signature) {
protected function emitSignature($result, $signature, $use= null) {
$result->out->write('(');
foreach ($signature->parameters as $i => $parameter) {
if ($i++) $result->out->write(',');
$this->emitParameter($result, $parameter);
}
$result->out->write(')');

if ($use) {
$result->out->write(' use('.implode(',', $use).') ');
foreach ($use as $variable) {
$result->locals[substr($variable, 1)]= true;
}
}

if ($signature->returns && $t= $this->literal($signature->returns)) {
$result->out->write(':'.$t);
}
Expand All @@ -349,14 +356,8 @@ protected function emitClosure($result, $closure) {
$result->locals= [];

$closure->static ? $result->out->write('static function') : $result->out->write('function');
$this->emitSignature($result, $closure->signature);
$this->emitSignature($result, $closure->signature, $closure->use);

if ($closure->use) {
$result->out->write(' use('.implode(',', $closure->use).') ');
foreach ($closure->use as $variable) {
$result->locals[substr($variable, 1)]= true;
}
}
$result->out->write('{');
$this->emitAll($result, $closure->body);
$result->out->write('}');
Expand Down
14 changes: 14 additions & 0 deletions src/test/php/lang/ast/unittest/emit/LambdasTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,18 @@ public function run(iterable $records) {

Assert::equals([1, 2], iterator_to_array($r));
}

#[Test]
public function use_with_return_type() {
$r= $this->run('class %T {
public function run() {
$local= 1;
return function() use($local): int {
return $local;
};
}
}');

Assert::equals(1, $r());
}
}

0 comments on commit 5111675

Please sign in to comment.