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)