feat(compiler): 添加原生类型支持和标准库函数

- 引入 native_types 类常量定义基本类型
- 添加 std 类提供 int、float、bool 类型转换方法
- 实现 objval 函数进行对象类型验证
- 在 CompilerBase 中添加 nativeTypes 属性控制类型行为
- 修改 getNativeType 方法使用 nativeTypes 判断
- 更新 use 语句解析支持 native_types 导入
- 在 micro_bench 示例中启用严格类型声明
- 添加 str_byte 示例文件测试字符串字节操作
pull/1/head
韩天峰 5 months ago
parent f6cb3278cb
commit 8312de6c73
  1. 24
      examples/assign_cmp.php
  2. 15
      examples/micro_bench.php
  3. 7
      examples/str_byte.php
  4. 41
      src/Php/CompilerBase.php
  5. 13
      src/functions.php
  6. 40
      src/polyfills.php

@ -1,28 +1,4 @@
<?php <?php
class std
{
static function int(int $value): int
{
return $value;
}
static function float(float $value): float
{
return $value;
}
static function bool(bool $value): bool
{
return $value;
}
static function string(string $str): resource
{
return fopen('php://stdin', 'r');
}
}
function main() function main()
{ {
$a = std::int(100); $a = std::int(100);

@ -1,14 +1,17 @@
<?php <?php
declare(strict_types=1);
use native_types;
function hallo() { function hallo() {
} }
function simpleucall($n) { function simpleucall(int $n) {
for ($i = 0; $i < $n; $i++) for ($i = 0; $i < $n; $i++)
hallo(); hallo();
} }
function simpleudcall($n) { function simpleudcall(int $n) {
for ($i = 0; $i < $n; $i++) for ($i = 0; $i < $n; $i++)
hallo2(); hallo2();
} }
@ -16,11 +19,15 @@ function simpleudcall($n) {
function hallo2() { function hallo2() {
} }
function simpleicall($n) function simpleicall(int $n)
{ {
// $array = [new ArrayObject()];
// $o = $array[0];
$o = new stdClass();
for ($i = 0; $i < $n; $i++) { for ($i = 0; $i < $n; $i++) {
// $ret = function_exists('hallo'); // $ret = function_exists('hallo');
$ret = class_exists('Foo2'); // $ret = class_exists('Foo2');
$ret = get_class($o);
} }
} }

@ -0,0 +1,7 @@
<?php
function main()
{
$str = "hello world";
$str[2] = "$";
var_dump($str);
}

@ -241,11 +241,11 @@ class CompilerBase extends \PhpAot\Core\Translator
]; ];
protected array $globalVars = []; protected array $globalVars = [];
protected bool $strictTypes = false; protected bool $strictTypes = false;
protected bool $nativeTypes = false;
protected string $rootPath; protected string $rootPath;
protected string $buildDir; protected string $buildDir;
protected int $debugLine = 0; protected int $debugLine = 0;
protected CLImate $climate; protected CLImate $climate;
protected bool $defaultNativeType = true;
protected bool $stubFile = false; protected bool $stubFile = false;
protected bool $enableProfiler = false; protected bool $enableProfiler = false;
protected bool $forTest = false; protected bool $forTest = false;
@ -612,11 +612,12 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function resetFile(): void protected function resetFile(): void
{ {
$this->indentLevel = 0; $this->indentLevel = 0;
$this->strictTypes = false; $this->strictTypes = false;
$this->classesDefineInFile = []; $this->nativeTypes = false;
$this->classesDefineInFile = [];
$this->interfacesDefineInFile = []; $this->interfacesDefineInFile = [];
$this->functionDefineInFile = []; $this->functionDefineInFile = [];
} }
protected function resetNamespace(): void protected function resetNamespace(): void
@ -1307,7 +1308,7 @@ class CompilerBase extends \PhpAot\Core\Translator
return $this->parseAssignFinally($left, $right); return $this->parseAssignFinally($left, $right);
} }
protected function parseAssignFinally(Node\Expr $left, Node\Expr $right): string protected function parseAssignFinally(Expr $left, Expr $right): string
{ {
if ($left instanceof Expr\List_) { if ($left instanceof Expr\List_) {
$items = $left->items; $items = $left->items;
@ -3392,7 +3393,7 @@ class CompilerBase extends \PhpAot\Core\Translator
*/ */
protected function getNativeType(string $type): string protected function getNativeType(string $type): string
{ {
return $this->defaultNativeType ? $type : self::TYPE_VAR; return $this->nativeTypes ? $type : self::TYPE_VAR;
} }
protected function detectConstType($expr): string protected function detectConstType($expr): string
@ -4018,11 +4019,6 @@ class CompilerBase extends \PhpAot\Core\Translator
/** /**
* @param NodeAbstract $expr 仅用于输出错误日志 * @param NodeAbstract $expr 仅用于输出错误日志
* @param string $property
* @param string $class
* @param string $namespace
* @param bool $static
* @return string|null
*/ */
protected function findNativeProperty(NodeAbstract $expr, string $property, string $class, string $namespace = '', bool $static = false): ?string protected function findNativeProperty(NodeAbstract $expr, string $property, string $class, string $namespace = '', bool $static = false): ?string
{ {
@ -4320,7 +4316,7 @@ class CompilerBase extends \PhpAot\Core\Translator
{ {
$declares = $v->declares; $declares = $v->declares;
foreach ($declares as $declare) { foreach ($declares as $declare) {
$key = $this->parseIdentifier($declare->key); $key = $this->parseIdentifier($declare->key);
$value = $this->parseIdentifier($declare->value); $value = $this->parseIdentifier($declare->value);
if ($key === 'ticks') { if ($key === 'ticks') {
$this->fatalError($v, 'declare(ticks=1) is not supported'); $this->fatalError($v, 'declare(ticks=1) is not supported');
@ -4328,8 +4324,11 @@ class CompilerBase extends \PhpAot\Core\Translator
if (strtolower($value) !== 'utf-8') { if (strtolower($value) !== 'utf-8') {
$this->fatalError($v, 'declare(encoding="' . $value . '") is not supported, only UTF-8 is supported'); $this->fatalError($v, 'declare(encoding="' . $value . '") is not supported, only UTF-8 is supported');
} }
} elseif ($key === 'strict_types') {
$this->strictTypes = boolval(intval($value));
} else {
$this->fatalError($v, 'declare(' . $key . '=' . $value . ') is not supported');
} }
$this->strictTypes = boolval(intval($value));
} }
} }
@ -4340,14 +4339,18 @@ class CompilerBase extends \PhpAot\Core\Translator
$id = $this->parseIdentifier($use->name); $id = $this->parseIdentifier($use->name);
if ($use->type === Node\Stmt\Use_::TYPE_FUNCTION) { if ($use->type === Node\Stmt\Use_::TYPE_FUNCTION) {
$rpos = strrpos($id, '\\'); $rpos = strrpos($id, '\\');
$fn = substr($id, $rpos + 1); $fn = substr($id, $rpos + 1);
$ns = substr($id, 0, $rpos); $ns = substr($id, 0, $rpos);
// fn => namespace // fn => namespace
$this->useFunctions[$fn] = $ns; $this->useFunctions[$fn] = $ns;
} else { } else {
$this->useNamespaces[] = $id; if ($id === 'native_types') {
if ($use->alias) { $this->nativeTypes = true;
$this->useAliases[$use->alias->toString()] = $id; } else {
$this->useNamespaces[] = $id;
if ($use->alias) {
$this->useAliases[$use->alias->toString()] = $id;
}
} }
} }
} }

@ -1,11 +1,17 @@
<?php <?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
use PhpAot\Core\Translator; use PhpAot\Core\Translator;
use PhpAot\Php\Exception\Unsupported; use PhpAot\Php\Exception\Unsupported;
function abort($v) function abort($v)
{ {
/** /*
* @var $translator Translator * @var $translator Translator
*/ */
global $translator; global $translator;
@ -38,12 +44,11 @@ function if_not_empty_debug($if_expr, $v)
} }
} }
function debug() function debug()
{ {
foreach(func_get_args() as $arg) { foreach (func_get_args() as $arg) {
var_dump($arg); var_dump($arg);
} }
debug_print_backtrace(); debug_print_backtrace();
exit; exit;
} }

@ -0,0 +1,40 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
class native_types
{
public const type_int = 'int';
public const type_float = 'float';
public const type_bool = 'bool';
}
class std
{
public static function int(mixed $value): int
{
return intval($value);
}
public static function float(mixed $value): float
{
return floatval($value);
}
public static function bool(mixed $value): bool
{
return boolval($value);
}
}
function objval(mixed $obj, string $class): object
{
if ($obj instanceof $class) {
return $obj;
}
throw new Exception('Invalid object type');
}
Loading…
Cancel
Save