refactor(php): 重构二进制运算符相等性比较逻辑

- 移除重复的类型检测和转换代码
- 引入 genBigNumericCmp 方法统一处理大数值比较
- 简化 Equal 和 NotEqual 运算符的实现
- 优化 Spaceship 运算符的比较逻辑
- 统一字符串转换方法的调用方式
pull/1/head
韩天峰 3 months ago
parent 215c077291
commit a510801d24
  1. 116
      src/Php/CompilerBase.php

@ -3979,82 +3979,14 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseBinaryOpEqual(Expr\BinaryOp\Equal $expr): string protected function parseBinaryOpEqual(Expr\BinaryOp\Equal $expr): string
{ {
$leftType = $this->detectTypeOfExpr($expr->left); return $this->genBigNumericCmp($expr, ' == 0')
$rightType = $this->detectTypeOfExpr($expr->right); ?? 'php::equals(' . $this->parseCompareExpr($expr->left) . ', ' . $this->parseCompareExpr($expr->right) . ')';
if ($leftType === self::TYPE_BIGFLOAT || $rightType === self::TYPE_BIGFLOAT) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGFLOAT) {
$leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGFLOAT) {
$rightExpr = $this->convertBigFloatExpr($rightExpr, $rightType);
}
return 'php::BigFloat::cmp(' . $leftExpr . ', ' . $rightExpr . ') == 0';
}
if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGINT) {
$leftExpr = $this->convertBigIntExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGINT) {
$rightExpr = $this->convertBigIntExpr($rightExpr, $rightType);
}
return 'php::BigInt::cmp(' . $leftExpr . ', ' . $rightExpr . ') == 0';
}
if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_DECIMAL) {
$leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $expr->left);
}
if ($rightType !== self::TYPE_DECIMAL) {
$rightExpr = $this->convertDecimalExpr($rightExpr, $rightType, $expr->right);
}
return 'php::Decimal::cmp(' . $leftExpr . ', ' . $rightExpr . ') == 0';
}
return 'php::equals(' . $this->parseCompareExpr($expr->left) . ', ' . $this->parseCompareExpr($expr->right) . ')';
} }
protected function parseBinaryOpNotEqual(Expr\BinaryOp\NotEqual $expr): string protected function parseBinaryOpNotEqual(Expr\BinaryOp\NotEqual $expr): string
{ {
$leftType = $this->detectTypeOfExpr($expr->left); return $this->genBigNumericCmp($expr, ' != 0')
$rightType = $this->detectTypeOfExpr($expr->right); ?? '!php::equals(' . $this->parseCompareExpr($expr->left) . ', ' . $this->parseCompareExpr($expr->right) . ')';
if ($leftType === self::TYPE_BIGFLOAT || $rightType === self::TYPE_BIGFLOAT) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGFLOAT) {
$leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGFLOAT) {
$rightExpr = $this->convertBigFloatExpr($rightExpr, $rightType);
}
return 'php::BigFloat::cmp(' . $leftExpr . ', ' . $rightExpr . ') != 0';
}
if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGINT) {
$leftExpr = $this->convertBigIntExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGINT) {
$rightExpr = $this->convertBigIntExpr($rightExpr, $rightType);
}
return 'php::BigInt::cmp(' . $leftExpr . ', ' . $rightExpr . ') != 0';
}
if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) {
$leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_DECIMAL) {
$leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $expr->left);
}
if ($rightType !== self::TYPE_DECIMAL) {
$rightExpr = $this->convertDecimalExpr($rightExpr, $rightType, $expr->right);
}
return 'php::Decimal::cmp(' . $leftExpr . ', ' . $rightExpr . ') != 0';
}
return '!php::equals(' . $this->parseCompareExpr($expr->left) . ', ' . $this->parseCompareExpr($expr->right) . ')';
} }
protected function parseBinaryOpIdentical(Expr\BinaryOp $expr): string protected function parseBinaryOpIdentical(Expr\BinaryOp $expr): string
@ -4247,11 +4179,18 @@ class CompilerBase extends \PhpAot\Core\Translator
} }
protected function parseBinaryOpSpaceship(Expr\BinaryOp\Spaceship $expr): string protected function parseBinaryOpSpaceship(Expr\BinaryOp\Spaceship $expr): string
{
return $this->genBigNumericCmp($expr)
?? 'php::compare(' . $this->parseIdentifier($expr->left) . ', ' . $this->parseIdentifier($expr->right) . ')';
}
protected function genBigNumericCmp(Expr\BinaryOp $expr, string $suffix = ''): ?string
{ {
$leftType = $this->detectTypeOfExpr($expr->left); $leftType = $this->detectTypeOfExpr($expr->left);
$rightType = $this->detectTypeOfExpr($expr->right); $rightType = $this->detectTypeOfExpr($expr->right);
if ($leftType === self::TYPE_BIGFLOAT || $rightType === self::TYPE_BIGFLOAT) { if ($leftType === self::TYPE_BIGFLOAT || $rightType === self::TYPE_BIGFLOAT) {
$leftExpr = $this->parseExpr($expr->left); $leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right); $rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGFLOAT) { if ($leftType !== self::TYPE_BIGFLOAT) {
$leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType); $leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType);
@ -4259,10 +4198,10 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($rightType !== self::TYPE_BIGFLOAT) { if ($rightType !== self::TYPE_BIGFLOAT) {
$rightExpr = $this->convertBigFloatExpr($rightExpr, $rightType); $rightExpr = $this->convertBigFloatExpr($rightExpr, $rightType);
} }
return 'php::BigFloat::cmp(' . $leftExpr . ', ' . $rightExpr . ')'; return 'php::BigFloat::cmp(' . $leftExpr . ', ' . $rightExpr . ')' . $suffix;
} }
if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) { if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) {
$leftExpr = $this->parseExpr($expr->left); $leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right); $rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_BIGINT) { if ($leftType !== self::TYPE_BIGINT) {
$leftExpr = $this->convertBigIntExpr($leftExpr, $leftType); $leftExpr = $this->convertBigIntExpr($leftExpr, $leftType);
@ -4270,10 +4209,10 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($rightType !== self::TYPE_BIGINT) { if ($rightType !== self::TYPE_BIGINT) {
$rightExpr = $this->convertBigIntExpr($rightExpr, $rightType); $rightExpr = $this->convertBigIntExpr($rightExpr, $rightType);
} }
return 'php::BigInt::cmp(' . $leftExpr . ', ' . $rightExpr . ')'; return 'php::BigInt::cmp(' . $leftExpr . ', ' . $rightExpr . ')' . $suffix;
} }
if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) { if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) {
$leftExpr = $this->parseExpr($expr->left); $leftExpr = $this->parseExpr($expr->left);
$rightExpr = $this->parseExpr($expr->right); $rightExpr = $this->parseExpr($expr->right);
if ($leftType !== self::TYPE_DECIMAL) { if ($leftType !== self::TYPE_DECIMAL) {
$leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $expr->left); $leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $expr->left);
@ -4281,11 +4220,10 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($rightType !== self::TYPE_DECIMAL) { if ($rightType !== self::TYPE_DECIMAL) {
$rightExpr = $this->convertDecimalExpr($rightExpr, $rightType, $expr->right); $rightExpr = $this->convertDecimalExpr($rightExpr, $rightType, $expr->right);
} }
return 'php::Decimal::cmp(' . $leftExpr . ', ' . $rightExpr . ')'; return 'php::Decimal::cmp(' . $leftExpr . ', ' . $rightExpr . ')' . $suffix;
} }
$left = $this->parseIdentifier($expr->left);
$right = $this->parseIdentifier($expr->right); return null;
return 'php::compare(' . $left . ', ' . $right . ')';
} }
/** /**
@ -4429,18 +4367,10 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseCastString(Expr\Cast\String_ $node): string protected function parseCastString(Expr\Cast\String_ $node): string
{ {
$type = $this->detectTypeOfExpr($node->expr); return $this->convertExprToStringByType(
$expr = $this->parseExpr($node->expr); $this->parseExpr($node->expr),
if ($type === self::TYPE_BIGINT) { $this->detectTypeOfExpr($node->expr)
return 'php::BigInt::toString(' . $expr . ')'; );
}
if ($type === self::TYPE_BIGFLOAT) {
return 'php::BigFloat::toString(' . $expr . ')';
}
if ($type === self::TYPE_DECIMAL) {
return 'php::Decimal::toString(' . $expr . ')';
}
return $this->convertStringExpr($expr);
} }
protected function parseCastBool(Expr\Cast\Bool_ $node): string protected function parseCastBool(Expr\Cast\Bool_ $node): string

Loading…
Cancel
Save