/** * Define macro * * @param Tokenizer $tokens * @param Scope $scope * @throws InvalidUsageException */ public static function macroOpen(Tokenizer $tokens, Scope $scope) { $scope["name"] = $tokens->get(Tokenizer::MACRO_STRING); $scope["recursive"] = false; $args = array(); $defaults = array(); if (!$tokens->valid()) { return; } $tokens->next()->need('(')->next(); if ($tokens->is(')')) { return; } while ($tokens->is(Tokenizer::MACRO_STRING, T_VARIABLE)) { $args[] = $param = $tokens->getAndNext(); if ($tokens->is('=')) { $tokens->next(); if ($tokens->is(T_CONSTANT_ENCAPSED_STRING, T_LNUMBER, T_DNUMBER) || $tokens->isSpecialVal()) { $defaults[$param] = $tokens->getAndNext(); } else { throw new InvalidUsageException("Macro parameters may have only scalar defaults"); } } $tokens->skipIf(','); } $tokens->skipIf(')'); $scope["macro"] = array("name" => $scope["name"], "args" => $args, "defaults" => $defaults, "body" => "", "recursive" => false); return; }
/** * Parse parameters as $key=$value * param1=$var param2=3 ... * * @static * @param Tokenizer $tokens * @param array $defaults * @throws \Exception * @return array */ public function parseParams(Tokenizer $tokens, array $defaults = null) { $params = array(); while ($tokens->valid()) { if ($tokens->is(Tokenizer::MACRO_STRING)) { $key = $tokens->getAndNext(); if ($defaults && !isset($defaults[$key])) { throw new InvalidUsageException("Unknown parameter '{$key}'"); } if ($tokens->is("=")) { $tokens->next(); $params[$key] = $this->parseExpr($tokens); } else { throw new InvalidUsageException("Invalid value for parameter '{$key}'"); } } elseif ($tokens->is(Tokenizer::MACRO_SCALAR, '"', T_VARIABLE, "[", '(')) { $params[] = $this->parseExpr($tokens); } else { break; } } if ($defaults) { $params += $defaults; } return $params; }