SassFunctionDefinitionNode.php in Sassy 7.3
File
phpsass/tree/SassFunctionDefinitionNode.php
View source
<?php
class SassFunctionDefinitionNode extends SassNode {
const NODE_IDENTIFIER = '=';
const MATCH = '/^@function\\s+([_-\\w]+)\\s*(?:\\((.*?)\\))?\\s*$/i';
const IDENTIFIER = 1;
const NAME = 1;
const ARGUMENTS = 2;
private $name;
private $args = array();
public $parent;
public function __construct($token) {
if ($token->level !== 0) {
throw new SassMixinDefinitionNodeException('Functions can only be defined at root level', $this);
}
parent::__construct($token);
preg_match(self::MATCH, $token->source, $matches);
if (empty($matches)) {
throw new SassMixinDefinitionNodeException('Invalid Function', $this);
}
$this->name = $matches[self::NAME];
$this->name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
if (isset($matches[self::ARGUMENTS])) {
if (strlen(trim($matches[self::ARGUMENTS]))) {
foreach (explode(',', $matches[self::ARGUMENTS]) as $arg) {
$arg = explode($matches[self::IDENTIFIER] === self::NODE_IDENTIFIER ? '=' : ':', trim($arg));
$this->args[substr(trim($arg[0]), 1)] = count($arg) == 2 ? trim($arg[1]) : null;
}
}
}
}
public function parse($context) {
$context
->addFunction($this->name, $this);
return array();
}
public function getArgs() {
return $this->args;
}
public static function isa($token) {
return $token->source[0] === self::NODE_IDENTIFIER;
}
public function execute($pcontext, $arguments) {
$context = new SassContext($pcontext);
$argc = count($arguments);
$count = 0;
foreach ($this->args as $name => $value) {
if ($count < $argc) {
$arg = $this
->evaluate($arguments[$count++], $context);
$arguments[$name] = $arg;
$context
->setVariable($name, $arg);
}
elseif (!is_null($value)) {
$arguments[$name] = $value;
$context
->setVariable($name, $this
->evaluate($value, $context));
}
else {
throw new SassMixinNodeException("Function::{$name}: Required variable ({$name}) not given.\nFunction defined: ' . {$this->token}->filename . '::' . {$this->token}->line . '\nFunction used", $this);
}
}
$parser = $this->parent->parser;
$lexer = $this->parent->script->lexer;
$children = array();
try {
foreach ($this->children as $child) {
$child->parent = $this;
$children = array_merge($children, $child
->parse($context));
}
} catch (SassReturn $e) {
return $e->value;
}
return new SassBoolean('false');
}
}