- Added an URL extension which allows routes and URLs. - Fixed some bug within ClassTemplate
119 lines
3.5 KiB
PHP
119 lines
3.5 KiB
PHP
<?php declare(strict_types=1);
|
|
|
|
namespace Picea;
|
|
|
|
use Picea\Language\LanguageRegistration;
|
|
|
|
class Compiler
|
|
{
|
|
protected string $sourceCode = "";
|
|
|
|
protected array $syntaxObjectList = [];
|
|
|
|
protected array $tagList = [];
|
|
|
|
protected string $tagTokenOpen = "\{%";
|
|
|
|
protected string $tagTokenClose = "%\}";
|
|
|
|
public array $extensionList = [];
|
|
|
|
public ? LanguageRegistration $languageRegistration;
|
|
|
|
public function __construct(?LanguageRegistration $languageRegistration = null)
|
|
{
|
|
$this->languageRegistration = $languageRegistration;
|
|
$this->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);
|
|
|
|
# @TODO Refractor this parts to allows registration to the tag's name
|
|
if ( $this->tagList[$token] ?? false ) {
|
|
return $this->tagList[$token]->parse($context, $arguments, $token);
|
|
}
|
|
elseif ( $this->extensionList[$token] ?? false ) {
|
|
return $this->extensionList[$token]->parse($context, $arguments, $token);
|
|
}
|
|
else {
|
|
throw new \LogicException("Impossible to find token `$token` 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) {
|
|
$this->tagList[$token] = $controlStructureObject;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function registerExtension(Extension\Extension $extension) : self
|
|
{
|
|
foreach($extension->tokens ?? (array) ( $extension->token ?? [] ) as $token) {
|
|
$this->extensionList[$token] = $extension;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getExtensionFromToken(string $name) : Extension\Extension
|
|
{
|
|
if ( false === $this->extensionList[$name] ?? false ) {
|
|
throw new \InvalidArgumentException(<<<MSG
|
|
Requested extension from token `$name` could not be found from loaded Picea compiler's extension.
|
|
MSG);
|
|
}
|
|
|
|
return $this->extensionList[$name];
|
|
}
|
|
|
|
public function exportFunctions() : void
|
|
{
|
|
static $caching = [];
|
|
eval( $this->context->renderFunctions() );
|
|
}
|
|
|
|
}
|