feat(parser): 添加对Big*数值类型不支持运算符的检查

- 在BinaryOpTrait中添加Big*类型运算符支持检查逻辑
- 检测到BigFloat、Decimal或BigInt类型使用不支持的运算符时抛出错误
- 添加测试用例验证模运算符%对BigFloat类型的不支持
- 添加测试用例验证按位与运算符&对Decimal类型的不支持
- 添加测试用例验证左移运算符<<对BigFloat类型的不支持
- 添加测试用例验证按位或运算符|对Decimal类型的不支持
pull/1/head
韩天峰 3 months ago
parent 051c4a45fd
commit 8aa1745e1d
  1. 9
      phpunit/code/bigfloat-unsupported-mod.php
  2. 9
      phpunit/code/bigfloat-unsupported-shift.php
  3. 9
      phpunit/code/decimal-unsupported-bitand.php
  4. 9
      phpunit/code/decimal-unsupported-bitor.php
  5. 24
      phpunit/src/BigNumberUnsupportedOpTest.php
  6. 6
      src/Php/Parser/BinaryOpTrait.php

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
use native_types;
function main()
{
$a = std::bigFloat("3.14");
$b = std::bigFloat("2.71");
$c = $a % $b;
}

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
use native_types;
function main()
{
$a = std::bigFloat("10.0");
$b = 2;
$c = $a << $b;
}

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
use native_types;
function main()
{
$a = std::decimal("3.14");
$b = std::decimal("2.71");
$c = $a & $b;
}

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
use native_types;
function main()
{
$a = std::decimal("100");
$b = std::decimal("200");
$c = $a | $b;
}

@ -0,0 +1,24 @@
<?php
class BigNumberUnsupportedOpTest extends \BaseTest
{
public function testBigFloatMod()
{
$this->exec("Operator '%' is not supported for Big* numeric types", 'bigfloat-unsupported-mod.php');
}
public function testDecimalBitAnd()
{
$this->exec("Operator '&' is not supported for Big* numeric types", 'decimal-unsupported-bitand.php');
}
public function testBigFloatShiftLeft()
{
$this->exec("Operator '<<' is not supported for Big* numeric types", 'bigfloat-unsupported-shift.php');
}
public function testDecimalBitOr()
{
$this->exec("Operator '|' is not supported for Big* numeric types", 'decimal-unsupported-bitor.php');
}
}

@ -106,6 +106,12 @@ trait BinaryOpTrait
}
}
// Any Big*-typed operand reaching here means no Big* block handled the operator
$bigTypes = [self::TYPE_BIGFLOAT, self::TYPE_DECIMAL, self::TYPE_BIGINT];
if (in_array($leftType, $bigTypes, true) || in_array($rightType, $bigTypes, true)) {
$this->fatalError($left, "Operator '{$op}' is not supported for Big* numeric types");
}
// Only promote between native types (Int ↔ Float). When one side is
// php::Var, let the Variant operator handle type coercion so that
// run-time PHP type-juggling rules are followed correctly.

Loading…
Cancel
Save