languageRegistration->registerAll($this); } public function compile(Compiler\Context $context) : string { $context->compiler = $this; /** * Syntaxes such as {{ echo }} & {{= echo raw }} && {# comment #} */ foreach($this->syntaxObjectList as $syntax) { $syntax->parse($context, $this->sourceCode); } /** * Control structures & functions {% functionName arguments %} */ $replace = "#({$this->tagTokenOpen})(.*?)({$this->tagTokenClose})#s"; $this->sourceCode = preg_replace_callback($replace, function ($matches) use (&$context) { $matches[2] = trim($matches[2]); list($token, $arguments) = array_pad(array_filter(explode(' ', $matches[2], 2), 'strlen'), 2, null); $token = strtolower(trim($token)); $tokenName = $context->tokenName($token); $tokenOptions = $context->tokenOptions($token); if ( $this->tagList[$tokenName] ?? false ) { $this->eventExecute(CompileTokenTagEvent::class, $context, $arguments, $tokenName, $tokenOptions); return $this->tagList[$tokenName]->parse($context, $arguments, $tokenName, $tokenOptions); } elseif ( $this->extensionList[$tokenName] ?? false ) { $this->eventExecute(CompileTokenExtensionEvent::class, $context, $arguments, $tokenName, $tokenOptions); return $this->extensionList[$tokenName]->parse($context, $arguments, $tokenName, $tokenOptions); } else { throw new \LogicException("Impossible to find token `$tokenName` declared in `{$matches[2]}`. Perhapse you forgot to add a custom token to Picea's engine ?"); } }, $this->sourceCode); return $this->sourceCode; } public function loadSourceCode($html) : self { $this->sourceCode = $html; return $this; } public function registerCaching(CachingStrategy $cachingStrategy) : self { return $this; } public function registerSyntax(Syntax\Syntax $syntaxObject) : self { $this->syntaxObjectList[get_class($syntaxObject)] = $syntaxObject; return $this; } public function registerControlStructure(ControlStructure\ControlStructure $controlStructureObject) : self { foreach($controlStructureObject->tokens ?? (array) ( $controlStructureObject->token ?? [] ) as $token) { if ( strpos($token, '.') !== false ) { throw new RegisterExtensionToken(sprintf("Could not register token '%s' from control structure '%s' in this version. Options are now delt by extensions themselve instead.", $token, $controlStructureObject::class)); } $this->tagList[strtolower($token)] = $controlStructureObject; } return $this; } public function registerExtension(Extension\Extension $extension) : self { $tokens = $extension->tokens ?? (array) ( $extension->token ?? [] ); foreach($tokens as $token) { if ( strpos($token, '.') !== false ) { throw new RegisterExtensionToken(sprintf("Could not register token '%s' from extension '%s' in this version. Options are now delt by extensions themselve instead.", $token, $extension::class)); } $this->extensionList[strtolower($token)] = $extension; } if (! $tokens ) { $this->extensionList[] = $extension; } return $this; } public function registerExtensionsFunctions(Compiler\Context $context) : void { foreach($this->extensionList as $ext) { if ($ext instanceof FunctionExtension) { foreach ($ext->exportFunctions() as $name => $value) { $callable = is_string($value) ? fn(...$args) => call_user_func_array([ $ext, $value ], $args) : null; $context->pushFunction(is_numeric($name) ? $value : $name, $callable ?? $value); } } } } public function __toString() : string { return "???"; } public function getExtensionFromToken(string $name) : Extension\Extension { $tokenName = explode('.', $name)[0]; if ( ! isset($this->extensionList[$tokenName]) ) { throw new \InvalidArgumentException(<<extensionList[$tokenName]; } public function exportFunctions() : void { static $caching = []; eval( $this->context->renderFunctions() ); } }