命令行参数

pull/1/head
韩天峰 8 months ago
parent 9c72ef6ff4
commit e867d32e60
  1. 4
      cli.php
  2. 3
      composer.json
  3. 225
      composer.lock
  4. 12
      examples/fannkuchredux.php
  5. 11
      main.cc
  6. 4
      main.php
  7. 94
      src/Php/Translator.php

@ -0,0 +1,4 @@
#!/usr/bin/env php
<?php
include $argv[1];
main();

@ -1,6 +1,7 @@
{ {
"require": { "require": {
"nikic/php-parser": "^5.0" "nikic/php-parser": "^5.0",
"league/climate": "^3.10"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^10.4", "phpunit/phpunit": "^10.4",

225
composer.lock generated

@ -4,8 +4,74 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "4a6f5101e00fb97f23585b135496857b", "content-hash": "444c2cea70677ebaa81d75c9b93a9eb7",
"packages": [ "packages": [
{
"name": "league/climate",
"version": "3.10.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/climate.git",
"reference": "237f70e1032b16d32ff3f65dcda68706911e1c74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/climate/zipball/237f70e1032b16d32ff3f65dcda68706911e1c74",
"reference": "237f70e1032b16d32ff3f65dcda68706911e1c74",
"shasum": ""
},
"require": {
"php": "^7.3 || ^8.0",
"psr/log": "^1.0 || ^2.0 || ^3.0",
"seld/cli-prompt": "^1.0"
},
"require-dev": {
"mikey179/vfsstream": "^1.6.12",
"mockery/mockery": "^1.6.12",
"phpunit/phpunit": "^9.5.10",
"squizlabs/php_codesniffer": "^3.10"
},
"suggest": {
"ext-mbstring": "If ext-mbstring is not available you MUST install symfony/polyfill-mbstring"
},
"type": "library",
"autoload": {
"psr-4": {
"League\\CLImate\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Joe Tannenbaum",
"email": "hey@joe.codes",
"homepage": "http://joe.codes/",
"role": "Developer"
},
{
"name": "Craig Duncan",
"email": "git@duncanc.co.uk",
"homepage": "https://github.com/duncan3dc",
"role": "Developer"
}
],
"description": "PHP's best friend for the terminal. CLImate allows you to easily output colored text, special formats, and more.",
"keywords": [
"cli",
"colors",
"command",
"php",
"terminal"
],
"support": {
"issues": "https://github.com/thephpleague/climate/issues",
"source": "https://github.com/thephpleague/climate/tree/3.10.0"
},
"time": "2024-11-18T09:09:55+00:00"
},
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.4.0", "version": "v5.4.0",
@ -63,6 +129,111 @@
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
}, },
"time": "2024-12-30T11:07:19+00:00" "time": "2024-12-30T11:07:19+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": "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": [ "packages-dev": [
@ -1270,56 +1441,6 @@
}, },
"time": "2019-01-08T18:20:26+00:00" "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", "name": "react/cache",
"version": "v1.2.0", "version": "v1.2.0",
@ -4100,5 +4221,5 @@
"prefer-lowest": false, "prefer-lowest": false,
"platform": {}, "platform": {},
"platform-dev": {}, "platform-dev": {},
"plugin-api-version": "2.6.0" "plugin-api-version": "2.9.0"
} }

@ -25,15 +25,15 @@ function fannkuch($n)
while ($i < $n) { while ($i < $n) {
$perm[$i] = $perm1[$i]; $perm[$i] = $perm1[$i];
$i += 1; $i += 1;
//
var_dump($perm, $perm1); // var_dump($perm, $perm1);
var_dump('[i] i=' . $i); // var_dump('[i] i=' . $i);
} }
// Count flips and update max and checksum // Count flips and update max and checksum
$f = 0; $f = 0;
$k = $perm[0]; $k = $perm[0];
var_dump('[xxx] k=' . $k); // var_dump('[xxx] k=' . $k);
while ($k != 0) { while ($k != 0) {
$i = 0; $i = 0;
@ -46,7 +46,7 @@ function fannkuch($n)
$k = $perm[0]; $k = $perm[0];
$f += 1; $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); 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; if ($count[$r] > 0) $more = false; else $r += 1;
} }
$nperm += 1; $nperm += 1;
sleep(1);
} }
return $flips; return $flips;
} }

@ -3,10 +3,15 @@
void php_main(); void php_main();
int main(int argc, char **argv) { extern php::Var argc;
php_embed_init(argc, argv); extern php::Var argv;
int main(int cpp_argc, char **cpp_argv) {
php_embed_init(cpp_argc, cpp_argv);
int rc = 0; int rc = 0;
zend_first_try { zend_first_try {
argc = php::global("argc");
argv = php::global("argv");
php_main(); php_main();
} }
zend_catch { zend_catch {
@ -14,6 +19,8 @@ int main(int argc, char **argv) {
} }
zend_end_try(); zend_end_try();
argc.unset();
argv.unset();
php_embed_shutdown(); php_embed_shutdown();
return rc; return rc;
} }

@ -1,4 +0,0 @@
#!/usr/bin/env php
<?php
include __DIR__ . '/examples/' . $argv[1];
main();

@ -2,6 +2,7 @@
namespace PhpAot\Php; namespace PhpAot\Php;
use League\CLImate\CLImate;
use PhpAot\Php\Visitor; use PhpAot\Php\Visitor;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Expr\Variable; use PhpParser\Node\Expr\Variable;
@ -27,6 +28,7 @@ class Translator extends \PhpAot\Core\Translator
private string $phpxDir = '~/workspace/projects/phpx'; private string $phpxDir = '~/workspace/projects/phpx';
protected string $lang = 'PHP'; protected string $lang = 'PHP';
private string $cppCompiler = 'g++';
private array $scope = []; private array $scope = [];
private array $arguments = []; private array $arguments = [];
private int $tmpVarIndex = 0; private int $tmpVarIndex = 0;
@ -43,7 +45,7 @@ class Translator extends \PhpAot\Core\Translator
private array $internalFunctions = []; private array $internalFunctions = [];
private int $optimizeLevel = 5; private int $optimizeLevel = 0;
private int $floatPrecision = 17; private int $floatPrecision = 17;
private bool $debugInfo = true; private bool $debugInfo = true;
private bool $verbose = false; private bool $verbose = false;
@ -62,18 +64,60 @@ class Translator extends \PhpAot\Core\Translator
'_SESSION' => self::TYPE_ARRAY, '_SESSION' => self::TYPE_ARRAY,
'_REQUEST' => self::TYPE_ARRAY, '_REQUEST' => self::TYPE_ARRAY,
'GLOBALS' => self::TYPE_ARRAY, 'GLOBALS' => self::TYPE_ARRAY,
'argc' => self::TYPE_INT,
'argv' => self::TYPE_ARRAY,
]; ];
const string PREFIX = 'php_'; const string PREFIX = 'php_';
private string $rootPath; private string $rootPath;
private int $debugLine = 0; private int $debugLine = 0;
private CLImate $climate;
public function __construct(string $rootPath) public function __construct(string $rootPath)
{ {
$this->rootPath = $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 = []; $lines = [];
foreach ($this->headers as $header) { foreach ($this->headers as $header) {
@ -82,6 +126,15 @@ class Translator extends \PhpAot\Core\Translator
return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; 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 public function setPhpxDir($dir): void
{ {
$this->phpxDir = $dir; $this->phpxDir = $dir;
@ -99,14 +152,8 @@ class Translator extends \PhpAot\Core\Translator
$stmts = $traverser->traverse($ast); $stmts = $traverser->traverse($ast);
$this->indentLevel = 0; $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) { foreach($stmts as $v) {
$type = $v->getType(); $type = $v->getType();
switch ($type) { switch ($type) {
@ -123,7 +170,8 @@ class Translator extends \PhpAot\Core\Translator
abort($v); abort($v);
} }
} }
return $cppCode; // include + extern global vars + function impl
return $this->genIncludeHeaderFiles() . $this->genExternGlobalVars() . $cppCode;
} }
public function convert(string $file): string public function convert(string $file): string
@ -821,24 +869,28 @@ class Translator extends \PhpAot\Core\Translator
return $out; 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; $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) { if ($this->debugInfo) {
$cmd .= ' -g'; $cmd .= ' -g';
} }
echo $cmd . PHP_EOL; $this->climate->comment($cmd);
shell_exec($cmd); shell_exec($cmd);
} }
public function compileBinary($targetFile, $objectFile): void public function compileBinary($targetFile, $objectFile): void
{ {
// 生成全局变量 $this->genGlobalVars();
$this->generateGlobalVars(); $cmd = $this->cppCompiler . ' main.cc global_vars.cc ' . $objectFile . ' -o ' . $targetFile . ' ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs();
$cmd = 'g++ main.cc global_vars.cc ' . $objectFile . ' -o ' . $targetFile . ' ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs(); $this->addOptimizeOption($cmd);
$cmd .= ' -O' . $this->optimizeLevel; $this->climate->comment($cmd);
echo $cmd . PHP_EOL;
shell_exec($cmd); shell_exec($cmd);
} }
@ -1363,6 +1415,7 @@ class Translator extends \PhpAot\Core\Translator
foreach ($v->vars as $v) { foreach ($v->vars as $v) {
if (!$this->hasGlobalVar($v->name)) { if (!$this->hasGlobalVar($v->name)) {
$this->addGlobalVar($v->name, self::TYPE_VAR); $this->addGlobalVar($v->name, self::TYPE_VAR);
var_dump($this->globalVars);
} }
} }
return ''; return '';
@ -1647,10 +1700,11 @@ class Translator extends \PhpAot\Core\Translator
return array_key_exists($name, $this->globalVars); return array_key_exists($name, $this->globalVars);
} }
private function generateGlobalVars() private function genGlobalVars(): void
{ {
$file = 'global_vars.cc'; $file = 'global_vars.cc';
$code = $this->parseHeaders(); $code = $this->genIncludeHeaderFiles();
$lines = [];
// 全局变量只能是 var 类型 // 全局变量只能是 var 类型
foreach ($this->globalVars as $name => $type) { foreach ($this->globalVars as $name => $type) {
$lines[] = self::TYPE_VAR . ' ' . $name . ';'; $lines[] = self::TYPE_VAR . ' ' . $name . ';';

Loading…
Cancel
Save