Function for PHP version of VMX::Template

databind
vitalif 2010-05-19 10:31:07 +00:00 committed by Vitaliy Filippov
parent 9959ce66dc
commit 0c12d83c39
1 changed files with 33 additions and 11 deletions

View File

@ -367,6 +367,11 @@ class Template
$st->in_set--;
return $this->varref($in[1]) . " = \$t;\n\$t = array_pop(\$stack);\n";
}
elseif ($w == 'function')
{
$st->in_set--;
return "EOF);\n";
}
elseif ($w == 'begin' || $w == 'for')
{
if ($w == 'begin')
@ -382,9 +387,8 @@ $v = array_pop(\$stack);
return "}\n";
}
// @TODO FUNCTION varref ... END
// SET varref ... END
// FUNCTION varref ... END
// SET varref = expression
function compile_code_fragment_set($st, $kw, $t)
{
@ -392,6 +396,11 @@ $v = array_pop(\$stack);
return NULL;
if ($m[3])
{
if ($kw != 'set')
{
$this->error("Only SET is allowed for inline expressions, but '".strtoupper($kw)."' given (expression = $m[3])");
return NULL;
}
$e = $this->compile_expression($m[3]);
if ($e === NULL)
{
@ -400,8 +409,10 @@ $v = array_pop(\$stack);
}
return $this->varref($m[1]) . ' = ' . $e . ";\n";
}
$st->in[] = array('set', $m[1]);
$st->in[] = array($kw, $m[1]);
$st->in_set++;
if ($kw == 'function')
return $this->varref($m[1]) . ' = create_function(<<<EOF';
return "\$stack[] = \$t;\n\$t = '';\n";
}
@ -562,16 +573,13 @@ $iset";
$e = str_replace('$', '\\$', $e);
return $e;
}
// функция нескольких аргументов
else if (preg_match('/^([a-z_][a-z0-9_]*)\s*\((.*)$/is', $e, $m))
// функция нескольких аргументов или вызов замыкания
else if (preg_match('/^([a-z_][a-z0-9_]*((?:\.[a-z0-9_]+)*))\s*\((.*)$/is', $e, $m))
{
$f = strtolower($m[1]);
if (!method_exists($this, "function_$f"))
{
$this->error("Unknown function: '$f'");
return NULL;
}
$a = $m[2];
if ($m[2] || !method_exists($this, "function_$f"))
$varref = $self->varref($m[1]);
$a = $m[3];
$args = array();
while (!is_null($e = $this->compile_expression($a, array(&$a))))
{
@ -597,6 +605,8 @@ $iset";
return NULL;
$after[0] = $a;
}
if ($varref)
return "\$this->exec_call('$f', $varref, array(".implode(",", $args)."))";
return call_user_func_array(array($this, "function_$f"), $args);
}
// функция одного аргумента
@ -731,6 +741,15 @@ $iset";
return false;
}
// вызов своей функции
function exec_call($f, $sub, $args)
{
if (is_callable($sub))
return call_user_func_array($sub, $args);
$this->error("Unknown function: '$f'");
return NULL;
}
/* функции */
/* "или", "и", +, -, *, /, конкатенация */
@ -868,6 +887,9 @@ $iset";
// подмассив по кратности номеров элементов
function function_subarray_divmod() { $a = func_get_args(); return "self::exec_subarray_divmod(" . join(",", $a) . ")"; }
// объединение массивов
function function_array_merge() { $a = func_get_args(); return "array_merge(" . join(",", $a) . ")"; }
// получить элемент хеша/массива по неконстантному ключу (например get(iteration.array, rand(5)))
// по-моему, это лучше, чем Template Toolkit'овский ад - hash.key.${another.hash.key}.зюка.хрюка и т.п.
function function_get($a, $k) { return $a."[$k]"; }