- WIP on RAW token
- WIP on caching interface - Work done on easing template rendering for the controller
This commit is contained in:
		
							parent
							
								
									f8e3dbd60f
								
							
						
					
					
						commit
						bcd49884fc
					
				
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
| 
 | ||||
| Copyright (c) 2019 Dave Mc Nicoll | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "mcnd/picea", | ||||
|     "description": "A templating engine based on Twig's syntax and Plates's native uses of PHP.", | ||||
|     "description": "A templating engine based on Twig's syntax and Plates's native uses of PHP transpiling code into vanilla PHP template.", | ||||
|     "type": "library", | ||||
|     "license": "MIT", | ||||
|     "authors": [ | ||||
| @ -9,10 +9,12 @@ | ||||
|             "email": "mcndave@gmail.com" | ||||
|         } | ||||
|     ], | ||||
|     "require": {}, | ||||
|     "autoload": { | ||||
|         "psr-4": { | ||||
|             "Picea\\": "src/" | ||||
|         } | ||||
|     }, | ||||
|     "require": { | ||||
|         "psr/http-message": "^1.0" | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										68
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								composer.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| { | ||||
|     "_readme": [ | ||||
|         "This file locks the dependencies of your project to a known state", | ||||
|         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||
|         "This file is @generated automatically" | ||||
|     ], | ||||
|     "content-hash": "9771fcd7256da80520a2d0d0f95bf311", | ||||
|     "packages": [ | ||||
|         { | ||||
|             "name": "psr/http-message", | ||||
|             "version": "1.0.1", | ||||
|             "source": { | ||||
|                 "type": "git", | ||||
|                 "url": "https://github.com/php-fig/http-message.git", | ||||
|                 "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" | ||||
|             }, | ||||
|             "dist": { | ||||
|                 "type": "zip", | ||||
|                 "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", | ||||
|                 "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", | ||||
|                 "shasum": "" | ||||
|             }, | ||||
|             "require": { | ||||
|                 "php": ">=5.3.0" | ||||
|             }, | ||||
|             "type": "library", | ||||
|             "extra": { | ||||
|                 "branch-alias": { | ||||
|                     "dev-master": "1.0.x-dev" | ||||
|                 } | ||||
|             }, | ||||
|             "autoload": { | ||||
|                 "psr-4": { | ||||
|                     "Psr\\Http\\Message\\": "src/" | ||||
|                 } | ||||
|             }, | ||||
|             "notification-url": "https://packagist.org/downloads/", | ||||
|             "license": [ | ||||
|                 "MIT" | ||||
|             ], | ||||
|             "authors": [ | ||||
|                 { | ||||
|                     "name": "PHP-FIG", | ||||
|                     "homepage": "http://www.php-fig.org/" | ||||
|                 } | ||||
|             ], | ||||
|             "description": "Common interface for HTTP messages", | ||||
|             "homepage": "https://github.com/php-fig/http-message", | ||||
|             "keywords": [ | ||||
|                 "http", | ||||
|                 "http-message", | ||||
|                 "psr", | ||||
|                 "psr-7", | ||||
|                 "request", | ||||
|                 "response" | ||||
|             ], | ||||
|             "time": "2016-08-06T14:39:51+00:00" | ||||
|         } | ||||
|     ], | ||||
|     "packages-dev": [], | ||||
|     "aliases": [], | ||||
|     "minimum-stability": "stable", | ||||
|     "stability-flags": [], | ||||
|     "prefer-stable": false, | ||||
|     "prefer-lowest": false, | ||||
|     "platform": [], | ||||
|     "platform-dev": [] | ||||
| } | ||||
| @ -10,12 +10,12 @@ class %CLASSNAME% %EXTENDS% { | ||||
| 
 | ||||
| 	protected array $__variables_list = []; | ||||
| 
 | ||||
| 	public function output() : void | ||||
| 	public final function __output() : void | ||||
| 	{ | ||||
|         extract($this->__variables_list); ?>%CONTENT%<?php
 | ||||
| 	} | ||||
| 
 | ||||
| 	public function __renderSection($name) : void | ||||
| 	public final function __renderSection($name) : void | ||||
|     { | ||||
|         foreach([ 'prepend', 'default', 'append' ] as $item) { | ||||
|             usort($this->__section_list[$name][$item], fn($a, $b) => $a['order'] <=> $b['order']); | ||||
| @ -30,9 +30,9 @@ class %CLASSNAME% %EXTENDS% { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public function __renderTemplate() { | ||||
|     public final function __invoke() { | ||||
|         ob_start(); | ||||
|         $this->output(); | ||||
|         $this->__output(); | ||||
|         return ob_get_clean(); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										11
									
								
								src/Caching/Cache.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/Caching/Cache.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\Caching; | ||||
| 
 | ||||
| interface Cache { | ||||
| 
 | ||||
|     public function handle(string $fileName) : bool; | ||||
| 
 | ||||
|     public function load(); | ||||
| 
 | ||||
| } | ||||
| @ -2,31 +2,21 @@ | ||||
| 
 | ||||
| namespace Picea\Caching; | ||||
| 
 | ||||
| class Memory { | ||||
| class Memory implements Cache { | ||||
| 
 | ||||
|     protected string $cachePath = ""; | ||||
| 
 | ||||
|     public function __construct(string $cachePath) | ||||
|     public function handle(string $fileName) : bool | ||||
|     { | ||||
|         $this->cachePath = $cachePath; | ||||
|     } | ||||
| 
 | ||||
|     public function loadFile(string $fileName) : bool | ||||
|     { | ||||
|         if ( file_exists($path = $this->filePath($fileName)) ) { | ||||
|             require_once($path); | ||||
|         } | ||||
|         #if ( file_exists($path = $this->filePath($fileName)) ) {
 | ||||
|         #    require_once($path);
 | ||||
|         #}
 | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public function load() {} | ||||
| 
 | ||||
|     public function saveFile(string $fileName) : bool | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public function filePath(string $fileName) : string | ||||
|     { | ||||
|         return $this->cachePath . $fileName; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,16 +2,16 @@ | ||||
| 
 | ||||
| namespace Picea\Caching; | ||||
| 
 | ||||
| class Opcache { | ||||
| class Opcache implements Cache { | ||||
| 
 | ||||
|     protected string $cachePath = ""; | ||||
| 
 | ||||
|     public function __construct(string $cachePath) | ||||
|     public function __construct(?string $cachePath = null) | ||||
|     { | ||||
|         $this->cachePath = $cachePath; | ||||
|         $this->cachePath = $cachePath ?? sys_get_temp_dir(); | ||||
|     } | ||||
| 
 | ||||
|     public function loadFile(string $fileName) : bool | ||||
|     public function handle(string $fileName) : bool | ||||
|     { | ||||
|         if ( file_exists($path = $this->filePath($fileName)) ) { | ||||
|             require_once($path); | ||||
| @ -23,6 +23,8 @@ class Opcache { | ||||
| 
 | ||||
|     public function saveFile(string $fileName, string $content) : bool | ||||
|     { | ||||
|         $this->validateCachePath(); | ||||
| 
 | ||||
|         file_put_contents($this->filePath($fileName), $content); | ||||
| 
 | ||||
|         return false; | ||||
| @ -32,4 +34,21 @@ class Opcache { | ||||
|     { | ||||
|         return $this->cachePath . $fileName; | ||||
|     } | ||||
| 
 | ||||
|     protected function validateCachePath() : bool | ||||
|     { | ||||
|         if ( ! file_exists($this->cachePath) ) { | ||||
|             mkdir($this->cachePath, 0750, true); | ||||
|         } | ||||
| 
 | ||||
|         if ( ! is_writeable($this->cachePath) ) { | ||||
|             throw new \RuntimeException( | ||||
|                 sprintf("Given cache path `%s` is not writeable by `%s`", $this->cachePath, static::class) | ||||
|             ); | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,8 @@ | ||||
| 
 | ||||
| namespace Picea; | ||||
| 
 | ||||
| use Picea\Language\LanguageRegistration; | ||||
| 
 | ||||
| class Compiler | ||||
| { | ||||
|     protected string $sourceCode = ""; | ||||
| @ -16,8 +18,16 @@ class Compiler | ||||
| 
 | ||||
|     protected array $extensionList = []; | ||||
| 
 | ||||
|     protected ? LanguageRegistration $languageRegistration; | ||||
| 
 | ||||
|     public function __construct(?LanguageRegistration $languageRegistration = null) | ||||
|     { | ||||
|         $this->languageRegistration = $languageRegistration; | ||||
|     } | ||||
| 
 | ||||
|     public function compile(Compiler\Context $context) : string | ||||
|     { | ||||
|         $this->languageRegistration->registerAll($this); | ||||
|         $context->compiler = $this; | ||||
| 
 | ||||
|         /** | ||||
| @ -39,7 +49,7 @@ class Compiler | ||||
| 
 | ||||
|             # @TODO Refractor this parts to allows registration to the tag's name
 | ||||
|             if ( $this->tagList[$token] ?? false ) { | ||||
|                 return $this->tagList[$token]->parse($context, $arguments); | ||||
|                 return $this->tagList[$token]->parse($context, $arguments, $token); | ||||
|             } | ||||
|             elseif ( $this->extensionList[$token] ?? false ) { | ||||
|                 return $this->extensionList[$token]->parse($context, $arguments, $token); | ||||
| @ -59,12 +69,6 @@ class Compiler | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
|     public function registerExtension(Extension\Extension $extension) : self | ||||
|     { | ||||
|         $this->extensionList[$extension->token] = $extension; | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
|     public function registerCaching(CachingStrategy $cachingStrategy) : self | ||||
|     { | ||||
|     	return $this; | ||||
| @ -72,13 +76,25 @@ class Compiler | ||||
| 
 | ||||
|     public function registerSyntax(Syntax\Syntax $syntaxObject) : self | ||||
|     { | ||||
|         $this->syntaxObjectList[] = $syntaxObject; | ||||
|         $this->syntaxObjectList[get_class($syntaxObject)] = $syntaxObject; | ||||
|         return $this; | ||||
|     } | ||||
| 
 | ||||
|     public function registerControlStructure(ControlStructure\ControlStructure $controlStructureObject) : self | ||||
|     { | ||||
|         $this->tagList[$controlStructureObject->token] = $controlStructureObject; | ||||
|         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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -41,4 +41,9 @@ abstract class Context { | ||||
|     { | ||||
|         return implode(",", $context->useStack ?? []); | ||||
|     } | ||||
| 
 | ||||
|     public function variables(array $variables) : void | ||||
|     { | ||||
|         $this->variables = $variables; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class BreakToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "break"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php break; ?>"; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ class CaseToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "case"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $output = ""; | ||||
| 
 | ||||
|         if ( $context->switchStack ) { | ||||
|  | ||||
| @ -3,5 +3,5 @@ | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| interface ControlStructure { | ||||
|     public function parse(\Picae\Compiler\Context &$context, string $sourceCode); | ||||
|     public function parse(\Picae\Compiler\Context &$context, string $sourceCode, string $token); | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class DefaultToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "default"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $output = ""; | ||||
| 
 | ||||
|         if ( $context->switchStack ) { | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ElseIfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "elseif"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php elseif ($arguments): ?>"; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ElseToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "else"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php else: ?>"; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ class EndIfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endif"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php endif ?>"; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/ControlStructure/EndRawToken.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/ControlStructure/EndRawToken.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndRawToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endraw"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -6,7 +6,7 @@ class EndSectionToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endsection"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( empty($context->sections) ) { | ||||
|             throw new \RuntimeException("A section closing tag {% endsection %} was found without an opening {% section %} tag"); | ||||
|         } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class EndSwitchToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endswitch"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php endswitch; ?>"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class EndforToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endfor"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( end($context->iterationStack)['or'] === false ) { | ||||
|             $output = "<?php endfor; ?>"; | ||||
|         } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class EndforeachToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endforeach"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( end($context->iterationStack)['or'] === false ) { | ||||
|             $output = "<?php endforeach; ?>"; | ||||
|         } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ExtendsToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "extends"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $path) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $path, string $token) { | ||||
|         # Triming string's quotes
 | ||||
|         $path = trim($path, "\"\' \t"); | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ForToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "for"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $uid = "$".uniqid("for_"); | ||||
| 
 | ||||
|         $context->iterationStack[] = [ | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ForeachToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "foreach"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $uid = "$".uniqid("foreach_"); | ||||
| 
 | ||||
|         $context->iterationStack[] = [ | ||||
|  | ||||
| @ -6,7 +6,7 @@ class IfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "if"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php if ($arguments): ?>"; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ class NamespaceToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "namespace"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $context->namespace = $arguments; | ||||
|         return ""; | ||||
|     } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class OrToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "or"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( empty($context->iterationStack) ) { | ||||
|             throw new \LogicException("Token `or` was used outside of iterator. Make sure your `for` or `foreach` declaration are properly made."); | ||||
|         } | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/ControlStructure/RawToken.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/ControlStructure/RawToken.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class RawToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "raw"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -6,7 +6,7 @@ class SectionToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "section"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         list($name, $options) = array_pad(explode(',', $arguments), 2, null); | ||||
| 
 | ||||
|         if ( $options ?? false ) { | ||||
|  | ||||
| @ -6,7 +6,7 @@ class SwitchToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "switch"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $context->switchStack[] = true; | ||||
|         return "<?php switch($arguments):"; | ||||
|     } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class UseToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "use"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $context->useStack[] = $arguments; | ||||
|         return ""; | ||||
|     } | ||||
|  | ||||
| @ -6,7 +6,7 @@ class ViewToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "view"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) { | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         #$context->switchStack[] = true;
 | ||||
|         #return "<?php switch($arguments):";
 | ||||
|     } | ||||
|  | ||||
							
								
								
									
										36
									
								
								src/Extension/ExtensionTrait.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/Extension/ExtensionTrait.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\Extension; | ||||
| 
 | ||||
| trait ExtensionTrait { | ||||
| 
 | ||||
|     protected function parseOptions(?string $options) : array | ||||
|     { | ||||
|         if ( $options ?? false ) { | ||||
|             $attributes = eval("return $options;"); | ||||
| 
 | ||||
|             if ( ! is_array($attributes) ) { | ||||
|                throw new InvalidArgumentException("Given options `$options` is not a valid attributes array."); | ||||
|             } | ||||
| 
 | ||||
|             return $attributes; | ||||
|         } | ||||
| 
 | ||||
|         return []; | ||||
|     } | ||||
| 
 | ||||
|     protected function trim(string $value) : string | ||||
|     { | ||||
|         $value = trim($value, " \t"); | ||||
| 
 | ||||
|         if ( in_array(substr($value, 0, 1), [ "'", '"' ]) ) { | ||||
|             if ( ! in_array(substr($value, strlen($value) - 1), [ "'", '"' ]) ) { | ||||
|                 throw new \InvalidArgumentException("Given argument `$value` string is not closed"); | ||||
|             } | ||||
| 
 | ||||
|             return substr($value, 1, -1); | ||||
|         } | ||||
| 
 | ||||
|         return $value; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/Language/DefaultRegistrations.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/Language/DefaultRegistrations.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| <?php declare(strict_types=1); | ||||
| 
 | ||||
| namespace Picea\Language; | ||||
| 
 | ||||
| use Picea\Compiler; | ||||
| 
 | ||||
| class DefaultRegistrations implements LanguageRegistration | ||||
| { | ||||
|     public function registerAll(Compiler $compiler) : void | ||||
|     { | ||||
|         $this->registerSyntax($compiler); | ||||
|         $this->registerControlStructure($compiler); | ||||
|         $this->registerExtension($compiler); | ||||
|     } | ||||
| 
 | ||||
|     public function registerSyntax(Compiler $compiler) : void | ||||
|     { | ||||
|         $compiler->registerSyntax(new \Picea\Syntax\PhpTagToken()); | ||||
|         $compiler->registerSyntax(new \Picea\Syntax\CommentToken()); | ||||
|         $compiler->registerSyntax(new \Picea\Syntax\EchoRawToken()); | ||||
|         $compiler->registerSyntax(new \Picea\Syntax\EchoSafeToken()); | ||||
|     } | ||||
| 
 | ||||
|     public function registerControlStructure(Compiler $compiler) : void | ||||
|     { | ||||
| # @TODO -- a rewrite on the compiler has to be done to accept this kind of functionnality
 | ||||
| #          $compiler->registerControlStructure(new \Picea\ControlStructure\RawToken());
 | ||||
| #        $compiler->registerControlStructure(new \Picea\ControlStructure\EndRawToken());
 | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\NamespaceToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\UseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\IfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ElseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ElseIfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndIfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ForeachToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ForToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\OrToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndforeachToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndforToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\CaseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndCaseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndSwitchToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndSectionToken()); | ||||
|     } | ||||
| 
 | ||||
|     public function registerExtension(Compiler $compiler) : void | ||||
|     { | ||||
|         $compiler->registerExtension(new \Picea\Extension\JsonExtension()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/Language/LanguageRegistration.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Language/LanguageRegistration.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| <?php declare(strict_types=1); | ||||
| 
 | ||||
| namespace Picea\Language; | ||||
| 
 | ||||
| use Picea\Compiler; | ||||
| 
 | ||||
| interface LanguageRegistration | ||||
| { | ||||
|     public function registerSyntax(Compiler $compiler) : void; | ||||
| 
 | ||||
|     public function registerControlStructure(Compiler $compiler) : void; | ||||
| 
 | ||||
|     public function registerExtension(Compiler $compiler) : void; | ||||
| } | ||||
							
								
								
									
										111
									
								
								src/Picea.php
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								src/Picea.php
									
									
									
									
									
								
							| @ -2,16 +2,56 @@ | ||||
| 
 | ||||
| namespace Picea; | ||||
| 
 | ||||
| class Picea | ||||
| use Closure; | ||||
| use Picea\Language\LanguageRegistration; | ||||
| use Psr\Http\Message\ResponseInterface; | ||||
| 
 | ||||
| class Picea implements LanguageRegistration | ||||
| { | ||||
|     const DEFAULT_BUILDER_TEMPLATE = "/Builder/ClassTemplate.php"; | ||||
| 
 | ||||
|     public Compiler\Context $context; | ||||
| 
 | ||||
|     public Compiler $compiler; | ||||
| 
 | ||||
|     public function __construct(?Context $context = null, ?Compiler $compiler = null) | ||||
|     { | ||||
|     public LanguageRegistration $languageRegistration; | ||||
| 
 | ||||
|     public string $builderTemplatePath; | ||||
| 
 | ||||
|     public Closure $responseHtml; | ||||
| 
 | ||||
|     public Caching\Cache $cache; | ||||
| 
 | ||||
|     public function __construct( | ||||
|         ?Closure $responseHtml = null, | ||||
|         ?Cache $cache = null, | ||||
|         ?Context $context = null, | ||||
|         ?Compiler $compiler = null, | ||||
|         ?LanguageRegistration $languageRegistration = null, | ||||
|         ?string $builderTemplatePath = null | ||||
|     ){ | ||||
|         $this->response = $responseHtml; | ||||
|         $this->cache = $cache ?? new Caching\Memory(""); | ||||
|         $this->context = $context ?? new Compiler\BaseContext(); | ||||
|         $this->compiler = $compiler ?: $this->instanciateCompiler(); | ||||
|         $this->compiler = $compiler ?? $this->instanciateCompiler(); | ||||
|         $this->languageRegistration = $languageRegistration ?? new Language\DefaultRegistrations(); | ||||
|         $this->builderTemplatePath = $builderTemplatePath ?? dirname(__FILE__) . static::DEFAULT_BUILDER_TEMPLATE; | ||||
|     } | ||||
| 
 | ||||
|     public function outputHtml(string $viewPath, array $variables) : ResponseInterface | ||||
|     { | ||||
|         if ( $this->response ?? false ) { | ||||
|             if ( false === $content = $this->cache->handle($viewPath) ) { | ||||
|                 # if ( )
 | ||||
|             } | ||||
| 
 | ||||
|             $source = $this->compileSource($source ?? "test"); | ||||
| 
 | ||||
|             $response = $this->response; | ||||
|             return $response("abc"); | ||||
|         } | ||||
| 
 | ||||
|         throw new \InvalidArgumentException("No \Psr\Http\Message\ResponseInterface closure provided. Please provide one using the constructor or assinging it to the class variable `responseHtml`."); | ||||
|     } | ||||
| 
 | ||||
|     public function compileSource(string $source) : array | ||||
| @ -27,11 +67,11 @@ class Picea | ||||
|     public function compileFile(string $filePath) : array | ||||
|     { | ||||
|         if (! file_exists($filePath) ) { | ||||
|             throw new \InvalidArgumentException("File `$filePath` cannot be found or it is a permission problem"); | ||||
|             throw new \InvalidArgumentException("File `$filePath` cannot be found or there is a permission problem."); | ||||
|         } | ||||
| 
 | ||||
|         if ( false === $fileContent = file_get_contents($filePath) ) { | ||||
|             throw new \ErrorException("Given file could not be opened `$filePath`. This could indicate a permission misconfiguration on your file or folder"); | ||||
|             throw new \ErrorException("Given file could not be opened `$filePath`. This could indicate a permission misconfiguration on your file or folder."); | ||||
|         } | ||||
| 
 | ||||
|         $this->compiler->loadSourceCode($fileContent); | ||||
| @ -64,64 +104,35 @@ class Picea | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public function instanciateCompiler(string $sourceCode = "") : Compiler | ||||
|     public function instanciateCompiler() : Compiler | ||||
|     { | ||||
|         $compiler = new Compiler(); | ||||
|         $compiler->loadSourceCode($sourceCode); | ||||
| 
 | ||||
|         $this->registerSyntax($compiler) | ||||
|             ->registerControlStructure($compiler) | ||||
|             ->registerExtension($compiler); | ||||
| 
 | ||||
|         return $compiler; | ||||
|         return new Compiler($this->languageRegistration); | ||||
|     } | ||||
| 
 | ||||
|     public function instanciateBuilder() : Builder | ||||
|     { | ||||
|         $builder = new Builder(dirname(__FILE__) . "/Builder/ClassTemplate.php"); | ||||
|         return $builder; | ||||
|         return new Builder($this->builderTemplatePath); | ||||
|     } | ||||
| 
 | ||||
|     protected function registerSyntax(Compiler $compiler) : self | ||||
|     public function registerAll(Compiler $compiler) : void | ||||
|     { | ||||
|         $compiler->registerSyntax( new \Picea\Syntax\PhpTagToken() ); | ||||
|         $compiler->registerSyntax( new \Picea\Syntax\CommentToken() ); | ||||
|         $compiler->registerSyntax( new \Picea\Syntax\EchoRawToken() ); | ||||
|         $compiler->registerSyntax( new \Picea\Syntax\EchoSafeToken() ); | ||||
| 
 | ||||
|         return $this; | ||||
|         $this->registerSyntax($compiler); | ||||
|         $this->registerControlStructure($compiler); | ||||
|         $this->registerExtension($compiler); | ||||
|     } | ||||
| 
 | ||||
|     protected function registerControlStructure(Compiler $compiler) : self | ||||
|     public function registerSyntax(Compiler $compiler) : void | ||||
|     { | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\NamespaceToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\UseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\IfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ElseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ElseIfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndIfToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ForeachToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ForToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\OrToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndforeachToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndforToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\CaseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndCaseToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndSwitchToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\EndSectionToken()); | ||||
| 
 | ||||
|         return $this; | ||||
|         $this->languageRegistration->registerSyntax($compiler); | ||||
|     } | ||||
| 
 | ||||
|     protected function registerExtension(Compiler $compiler) : self | ||||
|     public function registerControlStructure(Compiler $compiler) : void | ||||
|     { | ||||
|         $compiler->registerExtension(new \Picea\Extension\JsonExtension()); | ||||
|         $this->languageRegistration->registerControlStructure($compiler); | ||||
|     } | ||||
| 
 | ||||
|         return $this; | ||||
|     public function registerExtension(Compiler $compiler) : void | ||||
|     { | ||||
|         $this->languageRegistration->registerExtension($compiler); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,8 @@ namespace Picea\Syntax; | ||||
| 
 | ||||
| class CommentToken implements Syntax { | ||||
| 
 | ||||
|     public string $token = "#"; | ||||
| 
 | ||||
|     protected string $tokenOpen = "\{\#"; | ||||
| 
 | ||||
|     protected string $tokenClose = "\#\}"; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user