User:AzaToth/Logic
Appearance
Documentation
[edit]Purpose
[edit]A simple, probably fast computation engine for wiki
Functions
[edit]- if
- switch
- map
- join
- par
- pars
- npars
String Operators
[edit]- eq
- ne
Arithmetic operators
[edit]- add
- sub
- mul
- div
- mod
- sl
- sr
Boolean operators
[edit]- and
- or
- xor
- nand
- nor
- nxor
- not
Examples
[edit]Some test examples I made that worked as expected:
{{test|E|d|F|ddd|c|r|e|b|d}}
{{test|A}}
{#add|2|5#}
{#sub|2|5#}
{#mul|2|5#}
{#div|2|5#}
{#div|2|0#}
{#mod|7|3#}
{#sl|16|2#}
{#sr|16|2#}
----
{#par|*#}
----
{#npars#}
and it using template test containing
:''Main page{#if|{#gt|{#npars#}|1#}|s#}: {#[!]map!![[!]]!, !{#[!]pars!*#}#}''
resulted in (mark copy):
Main pages: E, d, F, ddd, c, r, e, b, d
Main page: A
7 -3 10 0.4 NaN 1 64 4
0
{#[long idiotic delimiter]switch
long idiotic delimiterbar
long idiotic delimitercase foo: hello
long idiotic delimitercase bar: world
long idiotic delimiterdefault: nooo
#}
gives "world"
Code
[edit]Add this after array_push( $this->mArgStack, $args ); in Parser::replaceVariables
if($this->mOutputType == OT_HTML) {
$l = new Logic();
$text = $l->processText($args, $text);
}
The main code is:
<?php
class Logic {
var $args;
var $text;
function Logic() {
}
function processText($args, $text) {
$this->args = $args;
$this->text = $text;
// Replace until we are "done".
while(strstr($text,'{#')) {
$old_text = $text;
$text = preg_replace_callback('|\{#(?:(?!.*?\{#))(.*?)#\}|s',array(&$this, 'replaceFunctions'), $text);
if($old_text == $text) { // We are stuck in a while loop, scream out loud and halt...
$text .= "'''Error''': Stuck in a while loop, aborting!";
break;
}
}
return $text;
}
function replaceFunctions($matches) {
$block = $matches[1];
static $counter;
$delimiter = '|'; // What to split on, | per default, specified as {#[delimiter]function...#}
if(preg_match('/^\[(.+?)\]/s',$block,$m)) {
$block = preg_replace('/^\[.+?\]/s','',$block); // remove the delimiter specification now.
$delimiter = $m[1];
}
$array = explode($delimiter, $block);
$operand = $array[0];
$rest = array_slice($array,1);
switch(trim($operand)) {
/* Logic Operators */
case 'eq': // arg 1 is equal arg 2
if(trim($rest[0]) == trim($rest[1])) return 1;
else return '';
break;
case 'ne': // arg 1 is not equal arg 2
if(trim($rest[0]) != trim($rest[1])) return 1;
else return '';
break;
case 'ge': // value of arg 1 is greater than or equal to arg 2
if(trim($rest[0]) >= trim($rest[1])) return 1;
else return '';
break;
case 'le': // value of arg 1 is lesser than or equal to arg 2
if(trim($rest[0]) <= trim($rest[1])) return 1;
else return '';
break;
case 'gt': // value of arg 1 is greater than arg 2
if(trim($rest[0]) > trim($rest[1])) return 1;
else return '';
break;
case 'lt': // value of arg 1 is lesser than arg 2
if(trim($rest[0]) < trim($rest[1])) return 1;
else return '';
break;
case 'not': // return 1 if arg 1 is null, else return null
if(trim($rest[0]) != '') return '';
else return 1;
break;
case 'and': // boolean and
if(trim($rest[0]) != '' and trim($rest[1]) != '') return 1;
else return '';
break;
case 'or': // boolean or
if(trim($rest[0]) != '' or trim($rest[1]) != '') return 1;
else return '';
break;
case 'xor': // boolean exclusive or
if(trim($rest[0]) != '' xor trim($rest[1]) != '') return 1;
else return '';
break;
case 'nand': // boolean not and
if(trim($rest[0]) != '' and trim($rest[1]) != '') return '';
else return 1;
break;
case 'nor': // boolean not or
if(trim($rest[0]) != '' or trim($rest[1]) != '') return '';
else return 1;
break;
case 'nxor': // boolean not exclusive or
if(trim($rest[0]) != '' xor trim($rest[1]) != '') return '';
else return 1;
break;
/* End Logic Operators */
/* Arthimentic Operators */
case 'add': // add arg 2 to arg 1
return trim($rest[0]) + trim($rest[1]);
break;
case 'sub': // substract arg 2 from arg 1
return trim($rest[0]) - trim($rest[1]);
break;
case 'mul': // multiply arg 2 with arg 1
return trim($rest[0]) * trim($rest[1]);
break;
case 'div': // divide arg 2 from arg 1
if(trim($rest[1]) == 0) return 'NaN';
return trim($rest[0]) / trim($rest[1]);
break;
case 'mod': // return the rest of integer division of arg 1 / arg 2
return trim($rest[0]) % trim($rest[1]);
break;
case 'sl': // binary shift left arg 1 with arg 2
return trim($rest[0]) << trim($rest[1]);
break;
case 'sr':// binary shift right arg 1 with arg 2
return trim($rest[0]) >> trim($rest[1]);
break;
/* End Arthimentic Operators */
/* Functional Operators */
case 'if': // if arg 1 is not null return arg 2, else return arg 3
if(trim($rest[0]) != '') return $rest[1];
else return $rest[2];
break;
case 'switch': // if case arg 1: is found in arglist, return it's value, else return default
$values = array();
$var = 'case '.trim($rest[0]);
/**/
foreach(array_slice($rest,1) as $r) {
list($key, $value) = explode(':', $r,2);
$values[trim($key)] = $value;
}
if(array_key_exists(trim($var), $values))
return trim($values[$var]);
else
return trim($values['default']);
break;
/**
* @brief map - Map array to a complex string, ignore empty strings
*
* @param glue - glues keys to values, null if not.
* @param lwrap - left hand side wrap
* @param hwrap- right hand side wrap
* @param separator - string to separate entities with
* $param data - and array of data to map
*
* @return a mapped string of the input data
*/
case 'map':
$tmp = array();
foreach (array_slice($rest,4) as $k => $v)
{
if($v != '') {
$tmp[] = ($rest[0] == '' ? '' : ($k . $rest[0])) . $rest[1] . $v . $rest[2];
}
}
return implode($rest[3], $tmp);
break;
/**
* @brief a simple join
*
* @param separator - the string to separate the entities
* @param data - the data to join
*
* @return the joined string
*/
case 'join':
return join ($rest[0],array_slice($rest,1));
break;
/*
* @brief return the parameter
*
* @param key - the parameter to return
*
* @return the parameter
*/
case 'par':
if(array_key_exists(trim($rest[0]), $this->args)){
return $this->args[trim($rest[0])];
}
break;
/*
* @brief return a separated list of parameters, if arg1 is '*' then all parameters is returned
*
* @param arg1 - offset of parameters
* @param arg2 - length of parameters
*
* @return joined list of parameters
*/
case 'pars':
if(is_numeric($rest[0]) and is_numeric($rest[1])){
return join($delimiter,array_slice($this->args,$rest[0],$rest[1]));
} elseif(trim($rest[0]) == '*') {
return join($delimiter, $this->args);
}
break;
/*
* @brief the number of params
*
* @return the number of parameters
*/
case 'npars':
return sizeof($this->args);
break;
default: // highlight illegal code
return '<span style="color: red;">{#'.strtr($block,'|','|').'#}</span>';
break;
}
}
}
?>
See also
[edit]History
[edit]- Created
- AzaToth 04:06, 17 December 2005 (UTC)