cyrilleinvalides/choupas/www/admin/app/libs/sense/Sensible/SeTML/SeTMLRuntime.php

292 lines
5.1 KiB
PHP
Executable File

<?php
class SeTMLRuntime {
public static function initState ($data) {
return array(
'data' => $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);
}
}
}
?>