matex
matex copied to clipboard
Exception: Empty argument in Evaluator->addArgument() when custom function without arguments
I have and EvalMathFunctions class, holding a 'random' function without arguments.
class EvalMathFunctions {
static public function random() {
return rand();
}
}
I register this in matex:
$this->evaluator->functions = [
'random' => ['ref' => '\\EvalMathFunctions::random', 'arc' => 0]
];
I then call the function:
$this->evaluator->execute('random()');
And get the error.
This seems to fix it (see changes in bold)
private function getFunction(string $name) { $routine = $this->functions[$name] ?? null; $arguments = array(); if (!isset($routine) && isset($this->onFunction)) { call_user_func_array($this->onFunction, [$name, &$routine]); $this->functions[$name] = $routine; } if (!isset($routine)) throw new Exception('Unknown function: ' . $name, 6); if (isset($routine['arc']) && $routine['arc'] > 0 && !$this->getArguments($arguments)) throw new Exception('Syntax error', 1); if (isset($routine['arc']) && ($routine['arc'] != count($arguments))) throw new Exception('Invalid argument count', 3); return call_user_func_array($routine['ref'], $this->proArguments($arguments)); }
yup, seems functions without arguments not tested yet ) thanks i'll look on it
Hi @madorin, great, simple (not so simple xd) and efficient code for Evaluator ! If i understand correctly arc parameter * $routine['arc'] = null - any number of arguments * $routine['arc'] = 0 - function without arguments * $routine['arc'] > 1 - specified number of arguments So in addition to condition that wrote @koosvanderkolk
private function getFunction(string $name)
{
$routine = $this->functions[$name] ?? null;
$arguments = [];
if (!isset($routine) && isset($this->onFunction)) {
call_user_func_array($this->onFunction, [$name, &$routine]);
$this->functions[$name] = $routine;
}
if (!isset($routine))
throw new Exception('Unknown function: ' . $name, 6);
// +++++
if (((isset($routine['arc']) && $routine['arc'] > 0) || is_null($routine['arc']) ) &&
!$this->getArguments($arguments))
throw new Exception('Syntax error', 1);
// +++++
if (isset($routine['arc']) && ($routine['arc'] != count($arguments)))
throw new Exception('Invalid argument count', 3);
return call_user_func_array($routine['ref'], $this->proArguments($arguments));
}
Thanks very much for sharing.
It works only for single function formula - formula without arguments. Example: "DATENOW()" but for 'bigger' formulas not working Example: ""some text "+ DATENOW() + "text ""
For it to work proArguments() method needs:
private function proArguments($arguments): array
{
// +++++
if (empty($arguments)) {
$this->pos += 2;
return [];
}
// +++++
$ops = $this->pos;
$otx = $this->text;
$result = [];
foreach ($arguments as $argument)
$result[] = $this->perform($argument);
$this->pos = $ops;
$this->text = $otx;
return $result;
}