diff --git a/cli.php b/cli.php new file mode 100755 index 00000000..06ec5c2e --- /dev/null +++ b/cli.php @@ -0,0 +1,4 @@ +#!/usr/bin/env php +=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/b8dfcf02094b8c03b40322c229493bb2884423c5", + "reference": "b8dfcf02094b8c03b40322c229493bb2884423c5", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.63" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "support": { + "issues": "https://github.com/Seldaek/cli-prompt/issues", + "source": "https://github.com/Seldaek/cli-prompt/tree/1.0.4" + }, + "time": "2020-12-15T21:32:01+00:00" } ], "packages-dev": [ @@ -1270,56 +1441,6 @@ }, "time": "2019-01-08T18:20:26+00:00" }, - { - "name": "psr/log", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "time": "2024-09-11T13:17:53+00:00" - }, { "name": "react/cache", "version": "v1.2.0", @@ -4100,5 +4221,5 @@ "prefer-lowest": false, "platform": {}, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/examples/fannkuchredux.php b/examples/fannkuchredux.php index a4ed263f..91950d1e 100644 --- a/examples/fannkuchredux.php +++ b/examples/fannkuchredux.php @@ -25,15 +25,15 @@ function fannkuch($n) while ($i < $n) { $perm[$i] = $perm1[$i]; $i += 1; - - var_dump($perm, $perm1); - var_dump('[i] i=' . $i); +// +// var_dump($perm, $perm1); +// var_dump('[i] i=' . $i); } // Count flips and update max and checksum $f = 0; $k = $perm[0]; - var_dump('[xxx] k=' . $k); +// var_dump('[xxx] k=' . $k); while ($k != 0) { $i = 0; @@ -46,7 +46,7 @@ function fannkuch($n) $k = $perm[0]; $f += 1; - var_dump('[--] r=' . $r . ', checksum=' . $checksum . ', i=' . $i . ', k=' . $k . ', f=' . $f . ', r=' . $r); +// var_dump('[--] r=' . $r . ', checksum=' . $checksum . ', i=' . $i . ', k=' . $k . ', f=' . $f . ', r=' . $r); } var_dump('[2] r=' . $r . ', nperm=' . $nperm . ', checksum=' . $checksum . ', i=' . $i . ', k=' . $k . ', f=' . $f . ', r=' . $r); @@ -74,8 +74,6 @@ function fannkuch($n) if ($count[$r] > 0) $more = false; else $r += 1; } $nperm += 1; - - sleep(1); } return $flips; } diff --git a/main.cc b/main.cc index 04fdc7ad..734f55c5 100644 --- a/main.cc +++ b/main.cc @@ -3,10 +3,15 @@ void php_main(); -int main(int argc, char **argv) { - php_embed_init(argc, argv); +extern php::Var argc; +extern php::Var argv; + +int main(int cpp_argc, char **cpp_argv) { + php_embed_init(cpp_argc, cpp_argv); int rc = 0; zend_first_try { + argc = php::global("argc"); + argv = php::global("argv"); php_main(); } zend_catch { @@ -14,6 +19,8 @@ int main(int argc, char **argv) { } zend_end_try(); + argc.unset(); + argv.unset(); php_embed_shutdown(); return rc; } diff --git a/main.php b/main.php deleted file mode 100755 index 45d24a50..00000000 --- a/main.php +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env php - self::TYPE_ARRAY, '_REQUEST' => self::TYPE_ARRAY, 'GLOBALS' => self::TYPE_ARRAY, + 'argc' => self::TYPE_INT, + 'argv' => self::TYPE_ARRAY, ]; const string PREFIX = 'php_'; private string $rootPath; private int $debugLine = 0; + private CLImate $climate; public function __construct(string $rootPath) { $this->rootPath = $rootPath; + $this->climate = new CLImate; + $this->climate->arguments->add([ + 'optimize' => [ + 'prefix' => 'O', + 'longPrefix' => 'optimize', + 'description' => 'Set the optimization level of the gcc compiler to 0 by default', + 'required' => false, + 'castTo' => 'int', + 'defaultValue' => 0, + ], + ]); + + $this->preprocessArgvAdvanced(); + $this->climate->arguments->parse(); + $this->optimizeLevel = $this->climate->arguments->get('optimize'); + } + + function preprocessArgvAdvanced(): void + { + global $argv; + $processed = [$argv[0]]; + + for ($i = 1; $i < count($argv); $i++) { + $arg = $argv[$i]; + if (preg_match('/^-([a-zA-Z])(.+)$/', $arg, $matches)) { + $option = $matches[1]; + $value = $matches[2]; + $processed[] = "-{$option}"; + $processed[] = $value; + } elseif (preg_match('/^-([a-zA-Z]{2,})$/', $arg, $matches)) { + $options = str_split($matches[1]); + foreach ($options as $opt) { + $processed[] = "-{$opt}"; + } + } else { + $processed[] = $arg; + } + } + $argv = $processed; } - public function parseHeaders(): string + public function genIncludeHeaderFiles(): string { $lines = []; foreach ($this->headers as $header) { @@ -82,6 +126,15 @@ class Translator extends \PhpAot\Core\Translator return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; } + public function genExternGlobalVars(): string + { + $lines[] = PHP_EOL; + foreach ($this->globalVars as $name => $type) { + $lines[] = 'extern ' . self::TYPE_VAR . ' ' . $name . ';'; + } + return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; + } + public function setPhpxDir($dir): void { $this->phpxDir = $dir; @@ -99,14 +152,8 @@ class Translator extends \PhpAot\Core\Translator $stmts = $traverser->traverse($ast); $this->indentLevel = 0; - $cppCode = $this->parseHeaders(); - - $lines[] = PHP_EOL; - foreach ($this->globalVars as $name => $type) { - $lines[] = 'extern ' . self::TYPE_VAR . ' ' . $name . ';'; - } - $cppCode .= implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; + $cppCode = ''; foreach($stmts as $v) { $type = $v->getType(); switch ($type) { @@ -123,7 +170,8 @@ class Translator extends \PhpAot\Core\Translator abort($v); } } - return $cppCode; + // include + extern global vars + function impl + return $this->genIncludeHeaderFiles() . $this->genExternGlobalVars() . $cppCode; } public function convert(string $file): string @@ -821,24 +869,28 @@ class Translator extends \PhpAot\Core\Translator return $out; } - public function compileFile($file): void + private function addOptimizeOption(string &$cmd): void { - $cmd = 'g++ -c ' . $file . ' -o ' . $file . '.o ' . $this->parseIncludes(); $cmd .= ' -O' . $this->optimizeLevel; + } + + public function compileFile($file): void + { + $cmd = $this->cppCompiler . ' -c ' . $file . ' -o ' . $file . '.o ' . $this->parseIncludes(); + $this->addOptimizeOption($cmd); if ($this->debugInfo) { $cmd .= ' -g'; } - echo $cmd . PHP_EOL; + $this->climate->comment($cmd); shell_exec($cmd); } public function compileBinary($targetFile, $objectFile): void { - // 生成全局变量 - $this->generateGlobalVars(); - $cmd = 'g++ main.cc global_vars.cc ' . $objectFile . ' -o ' . $targetFile . ' ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs(); - $cmd .= ' -O' . $this->optimizeLevel; - echo $cmd . PHP_EOL; + $this->genGlobalVars(); + $cmd = $this->cppCompiler . ' main.cc global_vars.cc ' . $objectFile . ' -o ' . $targetFile . ' ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs(); + $this->addOptimizeOption($cmd); + $this->climate->comment($cmd); shell_exec($cmd); } @@ -1363,6 +1415,7 @@ class Translator extends \PhpAot\Core\Translator foreach ($v->vars as $v) { if (!$this->hasGlobalVar($v->name)) { $this->addGlobalVar($v->name, self::TYPE_VAR); + var_dump($this->globalVars); } } return ''; @@ -1647,10 +1700,11 @@ class Translator extends \PhpAot\Core\Translator return array_key_exists($name, $this->globalVars); } - private function generateGlobalVars() + private function genGlobalVars(): void { $file = 'global_vars.cc'; - $code = $this->parseHeaders(); + $code = $this->genIncludeHeaderFiles(); + $lines = []; // 全局变量只能是 var 类型 foreach ($this->globalVars as $name => $type) { $lines[] = self::TYPE_VAR . ' ' . $name . ';';