feat(std-array): 添加标准数组类型支持

- 添加了 TYPE_STD_ARRAY 常量定义
- 在全局头文件列表中加入 phpx_std_array.h
- 修复了嵌套数组索引解析逻辑,使用 convertIntExpr 方法转换整数表达式
- 优化了 std::array 函数参数解析,直接获取数值而非解析标量值
- 使用 TYPE_STD_ARRAY 常量替换硬编码的 std::array 字符串
- 修改返回值为注释格式的声明字符串以便调试
pull/1/head
韩天峰 4 months ago
parent 98ca30764a
commit daa5379e46
  1. 3
      examples/array-loop/std-array.php
  2. 3
      src/Php/CompilerBase.php
  3. 8
      src/Php/Parser/StdArrayParser.php
  4. 27
      tests/aot/std-array/001.phpt

@ -8,8 +8,7 @@ function main()
$index = 9; $index = 9;
$index2 = 5; $index2 = 5;
$array[$index2][$index][0] = 2026; $array[$index2][$index][0] = 2026;
// $array = std::array(native_types::type_int, 100);
// $array[99] = 2026;
var_dump($array[$index2][$index][0]); var_dump($array[$index2][$index][0]);
var_dump($array[$index2][$index]); var_dump($array[$index2][$index]);
} }

@ -63,11 +63,11 @@ class CompilerBase extends \PhpAot\Core\Translator
public const string TYPE_FLOAT = 'php::Float'; public const string TYPE_FLOAT = 'php::Float';
public const string TYPE_OBJECT = 'php::Object'; public const string TYPE_OBJECT = 'php::Object';
public const string TYPE_ARRAY = 'php::Array'; public const string TYPE_ARRAY = 'php::Array';
public const string TYPE_STD_ARRAY = 'php::StdArray';
public const string TYPE_ARGS = 'php::Args'; public const string TYPE_ARGS = 'php::Args';
public const string TYPE_STR = 'php::Str'; public const string TYPE_STR = 'php::Str';
public const string TYPE_REF = 'php::Ref'; public const string TYPE_REF = 'php::Ref';
public const string TYPE_VOID = 'void'; public const string TYPE_VOID = 'void';
public const string TYPE_STD_ARRAY = 'std::array';
public const int DECL_TYPE_OF_RETURN = 1; public const int DECL_TYPE_OF_RETURN = 1;
public const int DECL_TYPE_OF_PROPERTY = 2; public const int DECL_TYPE_OF_PROPERTY = 2;
public const int DECL_TYPE_OF_CONST = 3; public const int DECL_TYPE_OF_CONST = 3;
@ -134,6 +134,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected array $globalHeaders = [ protected array $globalHeaders = [
'phpx.h', 'phpx.h',
'phpx_helper.h', 'phpx_helper.h',
'phpx_std_array.h',
'phpx_func.h', 'phpx_func.h',
'php_func_decl.h', 'php_func_decl.h',
'php_global_var_decl.h', 'php_global_var_decl.h',

@ -75,7 +75,7 @@ trait StdArrayParser
} }
} }
$index = $this->parseExpr($tmp->dim); $index = $this->parseExpr($tmp->dim);
$nesting[] = '[' . Symbol::safeIndex($index, $info['sizes'][$level]) . ']'; $nesting[] = '[' . Symbol::safeIndex($this->convertIntExpr($index), $info['sizes'][$level]) . ']';
$tmp = $tmp->var; $tmp = $tmp->var;
$level++; $level++;
} else { } else {
@ -103,7 +103,7 @@ trait StdArrayParser
if (!$this->isScalarInt($tmp->args[1]->value)) { if (!$this->isScalarInt($tmp->args[1]->value)) {
$this->fatalError($tmp, 'std::array() expects second argument to be an integer'); $this->fatalError($tmp, 'std::array() expects second argument to be an integer');
} }
$size = $this->parseScalar($tmp->args[1]->value); $size = $tmp->args[1]->value->value;
$nesting[] = $size; $nesting[] = $size;
$typeExpr = $tmp->args[0]->value; $typeExpr = $tmp->args[0]->value;
if ($this->isClassConstFetch($typeExpr)) { if ($this->isClassConstFetch($typeExpr)) {
@ -135,7 +135,7 @@ trait StdArrayParser
} }
} }
$decl = str_repeat('std::array<', count($nesting)); $decl = str_repeat(self::TYPE_STD_ARRAY . '<', count($nesting));
$decl .= $type; $decl .= $type;
for ($i = count($nesting) - 1; $i >= 0; $i--) { for ($i = count($nesting) - 1; $i >= 0; $i--) {
$decl .= ', ' . $nesting[$i] . '>'; $decl .= ', ' . $nesting[$i] . '>';
@ -145,6 +145,6 @@ trait StdArrayParser
'type' => $type, 'type' => $type,
'sizes' => array_reverse($nesting), 'sizes' => array_reverse($nesting),
]; ];
return ''; return '// ' . $decl;
} }
} }

@ -0,0 +1,27 @@
--TEST--
std array: 001
--FILE--
<?php
function main() {
$array = std::array(native_types::type_int, 100);
$array[99] = 2026;
var_dump($array[99]);
var_dump($array[10]);
try {
$index = 100;
var_dump($array[$index]);
} catch (throwable $e) {
echo $e->getMessage();
}
}
?>
--EXPECT--
array(1) {
[0]=>
int(2026)
}
array(1) {
[0]=>
int(0)
}
Array index out of bounds: index 100, size 100
Loading…
Cancel
Save