169 lines
3.3 KiB
PHP
Executable File
169 lines
3.3 KiB
PHP
Executable File
<?php
|
|
|
|
abstract class Expression {
|
|
|
|
static protected $types = array();
|
|
|
|
public static function getParserExtension () {
|
|
|
|
$context = get_called_class();
|
|
|
|
return function ( &$parseState, $token, $nodes ) use ( $context ) {
|
|
|
|
return $context::parse($parseState, $token, $nodes);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
public static function dispatch ( $type, $action ) {
|
|
|
|
//~ echo get_called_class(), "\n";
|
|
|
|
if ( !empty(static::$types[$type][$action]) )
|
|
return static::$types[$type][$action]['value'];
|
|
|
|
$class = get_called_class() . 'Type' . ucfirst($type);
|
|
$delegate = get_called_class() . ucfirst($action);
|
|
|
|
$method = $action . ucfirst($type);
|
|
|
|
if ( class_exists($class) )
|
|
$caller = array(
|
|
$class,
|
|
$action
|
|
);
|
|
|
|
elseif ( class_exists($delegate) && method_exists($delegate, $method) )
|
|
$caller = array(
|
|
$delegate,
|
|
$method
|
|
);
|
|
|
|
elseif ( get_called_class() !== __CLASS__ )
|
|
$caller = call_user_func(
|
|
array(get_parent_class(get_called_class()), 'dispatch'),
|
|
$type,
|
|
$action
|
|
);
|
|
|
|
else $caller = null;
|
|
|
|
return static::$types[$type][$action]['value'] = $caller;
|
|
|
|
}
|
|
|
|
public static function build ( $type ) {
|
|
|
|
$args = func_get_args();
|
|
array_shift($args);
|
|
|
|
if ( $func = static::dispatch($type, __FUNCTION__) )
|
|
return call_user_func_array(
|
|
$func,
|
|
$args
|
|
);
|
|
|
|
else throw static::buildException($type, __FUNCTION__);
|
|
|
|
}
|
|
|
|
public static function parse ( &$parseState, $token, $nodes ) {
|
|
|
|
if ( $func = static::dispatch($token['type'], __FUNCTION__) )
|
|
return call_user_func(
|
|
$func,
|
|
$parseState,
|
|
$token,
|
|
$nodes
|
|
);
|
|
|
|
else return $nodes;
|
|
|
|
}
|
|
|
|
public static function serialize ( $ast ) {
|
|
|
|
if ( $func = static::dispatch($ast['type'], __FUNCTION__) )
|
|
return call_user_func(
|
|
$func,
|
|
get_called_class(),
|
|
$ast
|
|
);
|
|
|
|
else throw static::buildException($type, __FUNCTION__);
|
|
|
|
}
|
|
|
|
public static function compile ( $ast ) {
|
|
|
|
if ( $func = static::dispatch($ast['type'], __FUNCTION__) )
|
|
return call_user_func(
|
|
$func,
|
|
get_called_class(),
|
|
$ast
|
|
);
|
|
|
|
else throw static::buildException($ast['type'], __FUNCTION__);
|
|
|
|
}
|
|
|
|
public static function run ( $ast ) {
|
|
|
|
if ( $func = static::dispatch($ast['type'], __FUNCTION__) )
|
|
return call_user_func(
|
|
$func,
|
|
get_called_class(),
|
|
$ast
|
|
);
|
|
|
|
else throw static::buildException($type, __FUNCTION__);
|
|
|
|
}
|
|
|
|
public static function fromData ( $data ) {
|
|
|
|
if ( is_array($data) ) {
|
|
|
|
$elements = array();
|
|
foreach ( $data as $k => $v )
|
|
$elements[] = array(
|
|
static::fromData($k),
|
|
static::fromData($v)
|
|
);
|
|
|
|
return static::build($elements);
|
|
|
|
} elseif ( is_float($data) )
|
|
return static::buildFloat($data);
|
|
|
|
elseif ( is_numeric($data) )
|
|
return static::buildInteger($data);
|
|
|
|
elseif ( is_bool($data) )
|
|
return $data ? static::buildTrue() : static::buildFalse();
|
|
|
|
elseif ( is_null($data) )
|
|
return static::buildNull();
|
|
|
|
elseif ( is_string($data) )
|
|
$code = "'" . implode('\' +. "\n" +. \'', explode("\n", addslashes($data))) . "'";
|
|
|
|
else throw new Exception('Object cannot be build from data : ' . get_class($data));
|
|
|
|
}
|
|
|
|
public static function buildException ( $type, $action ) {
|
|
|
|
return new Exception(sprintf(
|
|
'%1$s error : type "%2$s" has no action "%3$s" !',
|
|
get_called_class(),
|
|
$type,
|
|
$action
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|