refactor(php): 重构PHP解析器中的条件表达式处理逻辑

- 修复BinaryOpTrait.php中的缩进问题,统一if语句的缩进格式
- 修改CompilerBase.php中接口常量处理逻辑,为数组类型常量添加原生名称前缀
- 重构多个辅助函数将引用传递改为返回值方式,包括appendStmtLines和相关返回函数
- 简化条件表达式和匹配表达式的代码生成逻辑,提高代码可读性
- 优化布尔表达式短路求值的实现方式
- 统一代码风格,减少不必要的变量赋值操作
pull/4/head
韩天峰 2 months ago
parent 0af331db16
commit 248156b3b4
  1. 53
      src/Php/CompilerBase.php
  2. 17
      src/Php/Parser/BinaryOpTrait.php

@ -2171,9 +2171,12 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
if (!$interfaceDef->hasConstant($const)) {
continue;
}
$classDef = $interfaceDef;
$constDef = $interfaceDef->constants[$const];
break;
$interfaceConstDef = $interfaceDef->constants[$const];
if ($interfaceConstDef->type === self::TYPE_ARRAY) {
return self::PREFIX . $this->getNativeName($interfaceConstDef->name, $interfaceDef->namespace, $interfaceDef->name);
}
$expr->setAttribute('nativeConst', $interfaceConstDef);
return $interfaceConstDef->value;
}
}
if ($constDef === null) {
@ -3970,34 +3973,36 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
$else = 'php::Var(' . $else . ')';
}
if ($hasBranchStmts) {
$appendStmtLines = function (string &$code, array $stmts): void {
if ($stmts) {
$code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
$appendStmtLines = function (array $stmts): string {
if (!$stmts) {
return '';
}
return $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
};
$appendReturn = function (string &$code, string $value, array $beforeStmts, array $afterStmts) use ($appendStmtLines): void {
$appendStmtLines($code, $beforeStmts);
$appendReturn = function (string $value, array $beforeStmts, array $afterStmts) use ($appendStmtLines): string {
$code = $appendStmtLines($beforeStmts);
if ($afterStmts) {
$tmpVar = $this->addTmpVar(self::TYPE_VAR);
$code .= $this->getIndent() . "{$tmpVar} = {$value};";
$appendStmtLines($code, $afterStmts);
$code .= $appendStmtLines($afterStmts);
$code .= $this->getIndent() . 'return ' . $tmpVar . ';';
} else {
$code .= $this->getIndent() . 'return php::Var(' . $value . ');';
}
return $code;
};
$code = '[&]() -> ' . self::TYPE_VAR . '{';
$appendStmtLines($code, $condBeforeStmts);
$code .= $appendStmtLines($condBeforeStmts);
if ($condAfterStmts) {
$condTmpVar = $this->addTmpVar(self::TYPE_VAR);
$code .= $this->getIndent() . "{$condTmpVar} = {$cond};";
$appendStmtLines($code, $condAfterStmts);
$code .= $appendStmtLines($condAfterStmts);
$cond = $condTmpVar;
}
$code .= $this->getIndent() . 'if (' . $cond . ') {';
$appendReturn($code, $if, $ifBeforeStmts, $ifAfterStmts);
$code .= $appendReturn($if, $ifBeforeStmts, $ifAfterStmts);
$code .= $this->getIndent() . '} else {';
$appendReturn($code, $else, $elseBeforeStmts, $elseAfterStmts);
$code .= $appendReturn($else, $elseBeforeStmts, $elseAfterStmts);
$code .= $this->getIndent() . '}';
$code .= $this->getIndent() . '}()';
return $code;
@ -4030,24 +4035,26 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
return [$value, $beforeStmts, $afterStmts];
};
$appendStmtLines = function (string &$code, array $stmts): void {
if ($stmts) {
$code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
$appendStmtLines = function (array $stmts): string {
if (!$stmts) {
return '';
}
return $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
};
$appendMatchReturn = function (string &$code, NodeAbstract $body) use ($parseExprWithStmts, $appendStmtLines): void {
$appendMatchReturn = function (NodeAbstract $body) use ($parseExprWithStmts, $appendStmtLines): string {
$this->assertExprCanBeUsedAsValue($body, 'match arm');
[$value, $beforeStmts, $afterStmts] = $parseExprWithStmts($body);
$appendStmtLines($code, $beforeStmts);
$code = $appendStmtLines($beforeStmts);
if ($afterStmts) {
$tmpVar = $this->addTmpVar(self::TYPE_VAR);
$code .= $this->getIndent() . "{$tmpVar} = {$value};";
$appendStmtLines($code, $afterStmts);
$code .= $appendStmtLines($afterStmts);
$code .= $this->getIndent() . 'return ' . $tmpVar . ';';
} else {
$code .= $this->getIndent() . 'return ' . $value . ';';
}
return $code;
};
$code = '[&]() -> ' . self::TYPE_VAR . '{';
@ -4066,24 +4073,24 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
$this->assertExprCanBeUsedAsValue($cond, 'match arm condition');
[$condValue, $beforeStmts, $afterStmts] = $parseExprWithStmts($cond);
$code .= $this->getIndent() . 'if (!' . $matched . ') {';
$appendStmtLines($code, $beforeStmts);
$code .= $appendStmtLines($beforeStmts);
if ($afterStmts) {
$condTmpVar = $this->addTmpVar(self::TYPE_VAR);
$code .= $this->getIndent() . "{$condTmpVar} = {$condValue};";
$appendStmtLines($code, $afterStmts);
$code .= $appendStmtLines($afterStmts);
$condValue = $condTmpVar;
}
$code .= $this->getIndent() . $matched . ' = php::same(' . $var . ', ' . $condValue . ');';
$code .= $this->getIndent() . '}';
}
$code .= $this->getIndent() . 'if (' . $matched . ') {';
$appendMatchReturn($code, $arm->body);
$code .= $appendMatchReturn($arm->body);
$code .= $this->getIndent() . '}';
}
if ($default) {
$code .= $this->getIndent() . '{';
$appendMatchReturn($code, $default);
$code .= $appendMatchReturn($default);
$code .= $this->getIndent() . '}';
} else {
$code .= $this->getIndent() . '{ return php::throwException("UnhandledMatchError", "Unhandled match case"); }';

@ -39,7 +39,7 @@ trait BinaryOpTrait
if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) {
$this->fatalError($left, 'Cannot mix BigFloat and Decimal implicitly. Use std::bigFloat() to convert explicitly.');
}
if ($leftType !== self::TYPE_BIGFLOAT) {
if ($leftType !== self::TYPE_BIGFLOAT) {
$leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGFLOAT) {
@ -61,7 +61,7 @@ trait BinaryOpTrait
if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) {
$this->fatalError($left, 'Cannot mix BigInt and Decimal implicitly. Use std::decimal() or std::bigInt() to convert explicitly.');
}
if ($leftType !== self::TYPE_DECIMAL) {
if ($leftType !== self::TYPE_DECIMAL) {
$leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $left);
}
if ($rightType !== self::TYPE_DECIMAL) {
@ -92,7 +92,7 @@ trait BinaryOpTrait
$method = ($op === '<<') ? 'bitShiftLeft' : 'bitShiftRight';
return 'php::BigInt::' . $method . '(' . $leftExpr . ', ' . $rightExpr . ')';
}
if ($leftType !== self::TYPE_BIGINT) {
if ($leftType !== self::TYPE_BIGINT) {
$leftExpr = $this->convertBigIntExpr($leftExpr, $leftType);
}
if ($rightType !== self::TYPE_BIGINT) {
@ -427,21 +427,22 @@ trait BinaryOpTrait
return '(' . $leftBool . ' ' . $op . ' ' . $this->convertBoolExpr((string) $rightExpr) . ')';
}
$appendStmtLines = function (string &$code, array $stmts): void {
if ($stmts) {
$code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
$appendStmtLines = function (array $stmts): string {
if (!$stmts) {
return '';
}
return $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL;
};
$shortCircuitValue = $op === '&&' ? 'false' : 'true';
$rightCondition = $op === '&&' ? $leftBool : '!(' . $leftBool . ')';
$code = '[&]() -> bool {';
$code .= $this->getIndent() . 'if (' . $rightCondition . ') {';
$appendStmtLines($code, $rightBeforeStmts);
$code .= $appendStmtLines($rightBeforeStmts);
if ($rightAfterStmts) {
$rightTmpVar = $this->addTmpVar(self::TYPE_VAR);
$code .= $this->getIndent() . $rightTmpVar . ' = ' . $rightExpr . ';';
$appendStmtLines($code, $rightAfterStmts);
$code .= $appendStmtLines($rightAfterStmts);
$rightExpr = $rightTmpVar;
}
$code .= $this->getIndent() . 'return ' . $this->convertBoolExpr((string) $rightExpr) . ';';

Loading…
Cancel
Save