diff --git a/src/Php/Constants.php b/src/Php/Constants.php index 5e7fd3ca..b028dcb5 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -58,7 +58,6 @@ class Constants ]; public const UNSUPPORTED_FUNCTIONS = [ - 'compact', 'extract', ]; } diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index cf66b2a8..edc124c6 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -126,6 +126,9 @@ trait FuncCallOptimizer return 'true'; } } + if ($name === 'compact') { + return $this->genCompact($expr); + } if ($name === 'get_class') { return $this->genGetClass($expr); } @@ -166,4 +169,29 @@ trait FuncCallOptimizer } return 'php::fn::get_class(' . $this->parseIdentifier($object) . ')'; } + + protected function genCompact(Node\Expr\FuncCall $expr): string + { + $list = []; + + $this->indentLevel++; + foreach ($expr->args as $arg) { + if (!$this->isScalarString($arg->value)) { + $this->fatalError($expr, 'The argument of compact function can only be literal string'); + } + $var = $arg->value->value; + if (!$this->hasVar($var)) { + $this->errorUndefinedVariable($var); + } + if ($this->isSuperGlobal($var)) { + $this->fatalError($expr, 'Cannot use super global variable `' . $var . '` in compact function'); + } + + $key = $this->getLiteralString($var); + $list[] = $this->getIndent() . '{ ' . $key . '.str(), ' . $var . ' }'; + } + $this->indentLevel--; + + return $this->genArray($list); + } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index a5901523..2f189b03 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -369,6 +369,10 @@ class Preprocessor extends CompilerBase if ($this->hasFunction($name)) { $this->fatalError($v, "Duplicate function `{$name}`"); } + // 禁止重定义内置函数 + if (!$this->methodDef and $this->isInternalFunction($name)) { + $this->fatalError($v, "The function `{$name}` is a built-in function and cannot be redefined"); + } $functionDef = $this->parseFunctionDecl($v); $this->addFunction($name, $functionDef); if ($this->methodDef) { diff --git a/tests/aot/functions/compact.phpt b/tests/aot/functions/compact.phpt new file mode 100644 index 00000000..1715d11d --- /dev/null +++ b/tests/aot/functions/compact.phpt @@ -0,0 +1,22 @@ +--TEST-- +compact +--FILE-- + +--EXPECT-- +array(3) { + ["event"]=> + string(8) "SIGGRAPH" + ["city"]=> + string(13) "San Francisco" + ["state"]=> + string(2) "CA" +} \ No newline at end of file