diff --git a/README.md b/README.md index 12b54880..83cd907f 100755 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ class HelloWorld { $author= Reflection::type(self::class)->annotation(Author::class)->argument(0); Console::writeLine(new Date()->toString(), ': '); - $greet($args[0] ?? 'World', from: $author) |> Console::writeLine(?); + $hello= $greet(?, from: $author); + $hello($args[0] ?? 'World') |> Console::writeLine(?); } } ``` @@ -93,9 +94,10 @@ lang.ast.emit.PHP74 lang.ast.emit.PHP80 lang.ast.emit.PHP81 lang.ast.emit.PHP82 -lang.ast.emit.PHP83 [*] -lang.ast.emit.PHP84 +lang.ast.emit.PHP83 +lang.ast.emit.PHP84 [*] lang.ast.emit.PHP85 +lang.ast.emit.PHP86 lang.ast.syntax.php.Using [*] @FileSystemCL<./vendor/xp-lang/php-is-operator/src/main/php> diff --git a/src/main/php/lang/ast/emit/PHP.class.php b/src/main/php/lang/ast/emit/PHP.class.php index 742f531d..4e3ae58e 100755 --- a/src/main/php/lang/ast/emit/PHP.class.php +++ b/src/main/php/lang/ast/emit/PHP.class.php @@ -13,6 +13,7 @@ InstanceExpression, Literal, NewExpression, + Placeholder, Property, ScopeExpression, UnpackExpression, @@ -1123,6 +1124,16 @@ protected function emitClone($result, $clone) { $result->out->write(')'); } + protected function emitPlaceholder($result, $placeholder) { + if (Placeholder::$VARIADIC === $placeholder) { + $result->out->write('...'); + } else if (Placeholder::$ARGUMENT === $placeholder) { + $result->out->write('?'); + } else { + $this->raise('Unsupportet placeholder '.$placeholder->kind()); + } + } + protected function emitCallable($result, $callable) { // Disambiguate the following: @@ -1132,7 +1143,9 @@ protected function emitCallable($result, $callable) { $callable->expression->line= -1; $this->emitOne($result, $callable->expression); - $result->out->write('(...)'); + $result->out->write('('); + $this->emitArguments($result, $callable->arguments); + $result->out->write(')'); } protected function emitCallableNew($result, $callable) { diff --git a/src/main/php/lang/ast/emit/PHP86.class.php b/src/main/php/lang/ast/emit/PHP86.class.php new file mode 100755 index 00000000..4b9528a3 --- /dev/null +++ b/src/main/php/lang/ast/emit/PHP86.class.php @@ -0,0 +1,57 @@ + literal mappings */ + public function __construct() { + $this->literals= [ + IsArray::class => function($t) { return 'array'; }, + IsMap::class => function($t) { return 'array'; }, + IsFunction::class => function($t) { return 'callable'; }, + IsValue::class => function($t) { return $t->literal(); }, + IsNullable::class => function($t) { + if (null === ($l= $this->literal($t->element))) return null; + return $t->element instanceof IsUnion ? $l.'|null' : '?'.$l; + }, + IsIntersection::class => function($t) { + $i= ''; + foreach ($t->components as $component) { + if (null === ($l= $this->literal($component))) return null; + $i.= '&'.$l; + } + return substr($i, 1); + }, + IsUnion::class => function($t) { + $u= ''; + foreach ($t->components as $component) { + if (null === ($l= $this->literal($component))) return null; + $u.= '|'.$l; + } + return substr($u, 1); + }, + IsLiteral::class => function($t) { return $t->literal(); }, + IsGeneric::class => function($t) { return null; } + ]; + } +} \ No newline at end of file diff --git a/src/test/php/lang/ast/unittest/emit/CallableSyntaxTest.class.php b/src/test/php/lang/ast/unittest/emit/CallableSyntaxTest.class.php index 070970d0..f0b43f43 100755 --- a/src/test/php/lang/ast/unittest/emit/CallableSyntaxTest.class.php +++ b/src/test/php/lang/ast/unittest/emit/CallableSyntaxTest.class.php @@ -423,7 +423,7 @@ public function run() { Assert::equals(1, $count); } - #[Test, Runtime(php: '>=8.6.0')] + #[Test, Runtime(php: '>=8.6.0-dev')] public function partial_function_application_with_named() { $r= $this->run('class %T { @@ -435,18 +435,6 @@ public function run() { Assert::equals('ok.', $r); } - #[Test, Runtime(php: '>=8.6.0')] - public function partial_function_application_variadic_before_named() { - $r= $this->run('class %T { - - public function run() { - $f= str_replace("test", ..., subject: ?); - return $f("ok", "test."); - } - }'); - Assert::equals('ok.', $r); - } - #[Test] public function partial_function_application_omit_optional() { $f= $this->run('class %T { diff --git a/src/test/php/lang/ast/unittest/emit/PHP86Test.class.php b/src/test/php/lang/ast/unittest/emit/PHP86Test.class.php new file mode 100755 index 00000000..7ee1ea75 --- /dev/null +++ b/src/test/php/lang/ast/unittest/emit/PHP86Test.class.php @@ -0,0 +1,26 @@ +emit('str_replace("test", "ok", ?)') + ); + } + + #[Test] + public function partial_function_application_variadic() { + Assert::equals( + 'str_replace("test","ok",...);', + $this->emit('str_replace("test", "ok", ...)') + ); + } +} \ No newline at end of file