$data, 'alloc' => array( '' => null, ), ); } /* execution environnement */ public $engine = null, $flow = null, $alloc = null, $frame = null, $blocks = array(), $stack = array(); public function __construct ( $data ) { $this->frame = self::initState($data); $this->flow = &$this->frame['alloc']['']; $this->alloc = &$this->frame['alloc']; } public function run ( $code, Engine $engine = null, $file = false ) { $en = $this->engine; $this->engine = $engine; $this->exec($this, $code, $file); $this->engine = $en; return $this; } private function exec ($runtime, $code, $file = false) { if ( $file ) include($code); else eval($code); } public function getData( $idx = false ) { if ( $idx !== false ) return $this->frame['alloc'][$idx]; return $this->frame['alloc']; } public function appendContent ( $data ) { if ( is_array($this->flow) ) { if ( empty($this->flow['']) ) $this->flow[''] = $data; else $this->flow[''] .= $data; } else $this->flow .= $data; return $this; } public function cpush ( &$pointer, $map = false ) { $this->stack[] = array( &$this->flow, &$this->alloc, ); $this->alloc = &$pointer; if ( is_array($map) ) { foreach ( $map as $k => $v ) $this->alloc[$k] = $v; $this->flow = &$pointer['']; } else $this->flow = &$pointer; return $this; } public function cpop () { $data = $this->frame['alloc']; $alloc = array_pop($this->stack); $this->flow = &$alloc[0]; $this->alloc = &$alloc[1]; return $data; } public function lpush ( $data = array() ) { $this->stack[] = array( &$this->flow, &$this->alloc, $this->frame['alloc'] ); $this->frame['alloc'] = $data; $this->flow = &$this->frame['alloc']['']; $this->alloc = &$this->frame['alloc']; } public function lpop () { $data = $this->frame['alloc']; $alloc = array_pop($this->stack); $this->flow = &$alloc[0]; $this->alloc = &$alloc[1]; $this->frame['alloc'] = $alloc[2]; return $data; } public function mpush ( $data = array() ) { $this->stack[] = array( &$this->flow, &$this->alloc, $this->frame, $this->blocks ); $this->frame = self::initState($data); } public function mpop () { $data = $this->frame; $frame = array_pop($this->stack); $this->flow = &$frame[0]; $this->alloc = &$frame[1]; $this->frame = $frame[2]; $this->blocks = array_merge($frame[3], array_diff_key($this->blocks, $frame[3])); return $data; } public function mergeFrame ( $frame ) { foreach ( $frame['alloc'] as $k => $v ) if ( $k !== '' ) $this->frame['alloc'][$k] = $v; $this->appendContent($frame['alloc']['']); } public function setBlock ( &$pointer, $block, $scope = array() ) { $pointer = array( $block, $scope ); } public function callBlock ( $pointer, $data = array() ) { if ( empty($pointer) ) throw new Exception(sprintf('RuntimeError block does not exists !')); $block = $pointer[0]; $this->mpush(array_merge($pointer[1], $data)); $block($this); $this->mergeFrame($this->mpop()); } public function includeTemplate ( $file, $data, $asis = false ) { $engine = $this->engine; $file = Path::get(preg_replace('!//+!', '/', preg_match('!^/!', $file) ? $file : $this->engine->getDir() . '/' . $file)); try { $tpl = Template::fromFile( $file, $this->engine->getRoot(), $this->engine->getCache() ); if ( $asis ) $this->appendContent($tpl->getSource()); else { $this->mpush($data); $tpl->run($this); $this->mergeFrame($this->mpop()); } } catch ( Exception $e ) { throw new Exception(sprintf( 'RuntimeError during inclusion of file "%1$s" in root directory' . "\n" . '"%2$s"' . "\n" . 'specified in file "%3$s"!', $file, $engine->getRoot(), $engine->getBasename() ), 0, $e); } } public function metaTemplate ( Closure $template, $cache = null ) { $engine = $this->engine; try { $data = $template($this); $this->mpush($data); if ( !$cache ) { Template::fromString( $data[''], $this->engine->getDir(), $this->engine->getRoot(), $this->engine->getCache() )->run($this); } else { Template::fromFile( Path::get($cache[0] === DIRECTORY_SEPARATOR ? $cache : $this->engine->getDir() . DIRECTORY_SEPARATOR . $cache), $this->engine->getRoot(), $this->engine->getCache(), $data[''] )->run($this); } $this->mergeFrame($this->mpop()); } catch ( Exception $e ) { throw new Exception(sprintf( 'RuntimeError during meta processing of file "%1$s" in root directory' . "\n" . '"%2$s"%3$s !', $engine->getBasename(), $engine->getRoot(), $cache ? ".\nMeta template available in mirror file " . $cache : '.' ), 0, $e); } } } ?>