User:ClueBot II/ClueBot Script/Interpreter

You will need the following files for this:
 * 1) cbs_interpreter.php (below)
 * 2) cluebot2.cbsfunctions.php (below)
 * 3) wikibot.classes.php (found here)
 * 4) cluebot2.config.php (below)
 * 5) test.cbs (below)

Usage
php cbs_interpreter.php file.cbs

For example: php cbs_interpreter.php test.cbs

CBS Functions
(cluebot2.cbsfunctions.php) &lt;?PHP $debug = true; function getarguments ($data,&amp;$return,&amp;$session,$conditionals = true,$delimiter = ' ') { $pos = 0; $depthp = 0; $depthb = 0; $quotes1 = 0; $quotes2 = 0; $tmp = ''; $chr = ''; $data = trim($data); $array = array;

while ($pos &lt; strlen($data)) { $chr = $data{$pos}; if (($quotes1 == 1) and ($chr == '&quot;')) { $quotes1 = 0; } elseif (($quotes2 == 1) and ($chr == &quot;'&quot;)) { $quotes2 = 0; } elseif (($quotes1 == 0) and ($quotes2 == 0)) { if ($depthb == 0) { if ($chr == '(') $depthp++;                                       if ($chr == ')') $depthp--; }                               if ($depthp == 0) { if ($chr == '{') $depthb++; if ($chr == '}') $depthb--; }                               if ($chr == '&quot;') $quotes1 = 1; if ($chr == &quot;'&quot;) $quotes2 = 1; if (($chr == $delimiter) and ($depthp == 0) and ($depthb == 0)) { $array[] = $tmp; $tmp = ''; $pos++; continue; } }                       $tmp .= $chr; $pos++; }               $array[] = $tmp;

foreach ($array as $arg) { if ($arg{0} == '%') { $return[] = &amp;$session['vars'][substr($arg,1)]; } elseif ($arg{0} == '{') { $return[] = $arg; } elseif (($conditionals == false) and ($arg{0} == '(')) {                               $return[] = $arg;                        } else {                                $return[] = evalconditional($arg,&amp;$session);                        }                }        }

function evalfunction ($function,&amp;$session) { if (preg_match('/^\$([^(]+)\((.*)\)$/',trim($function),$m)) {                       $func = strtolower($m[1]);                        $args = array;                        getarguments($m[2],&amp;$args,&amp;$session,true,',');                        switch ($func) {                                case '+':                                case 'cat':                                        $ret = '';                                        foreach ($args as $arg) {                                                $ret .= $arg;                                        }                                        return $ret;                                        break;                                case 'mid':                                case 'substr':                                        if (count($args) == 2) {                                                return substr($args[0],$args[1]); } elseif (count($args) == 3) { return substr($args[0],$args[1],$args[2]); }                                       break; case 'gettok': if (count($args) &gt;= 3) { if (count($args) == 4) { $x = explode($args[1],$args[0],$args[3]); } elseif (count($args) == 3) { $x = explode($args[1],$args[0]); }                                               if ($args[2] == 0) { return count($x); } else { return $x[$args[2] - 1]; }                                       }                                        break; case 'settok': if (count($args) == 4) { $x = explode($args[1],$args[0]); $x[$args[2] - 1] = $args[3]; return implode($args[1],$x); }                                       break; case 'addtok': if (count($args) == 3) { $x = explode($args[1],$args[0]); $x[] = $args[2]; return implode($args[1],$x); }                                       break; case 'deltok': if (count($args) == 3) { $x = explode($args[1],$args[0]); unset($x[$args[2] - 1]); return implode($args[1],$x); }                                       break; case 'strpos': if (count($args) == 2) { return ((($x = strpos($args[0],$args[1])) === false)?-1:$x); } elseif (count($args) == 3) { return ((($x = strpos($args[0],$args[1],$args[2])) === false)?-1:$x); }                                       break; case 'stripos': if (count($args) == 2) { return ((($x = stripos($args[0],$args[1])) === false)?-1:$x); } elseif (count($args) == 3) { return ((($x = stripos($args[0],$args[1],$args[2])) === false)?-1:$x); }                                       break; case 'replace': if ((count($args) % 2) == 1) { $search = array; $replace = array; $data = $args[0]; for ($i=1;$i&lt;count($args);$i+=2) { $search[] = $args[$i]; $replace[] = $args[$i + 1]; }                                               return str_replace($search,$replace,$data); }                                       break; case 'pregreplace': if (count($args) == 3) { return preg_replace($args[1],$args[2],$args[0]); }                                       break; case 'time': return time; break; }               }        }

function evalconditional ($conditional,&amp;$session) { global $debug; if ($debug) echo 'evalconditional(&quot;'.$conditional.'&quot;,'.serialize($session).');'.&quot;\n&quot;; $pos = 0; $depth = 0; $part = 1; $quotes1 = 0; $quotes2 = 0; $c1 = ''; $op = ''; $c2 = '';

while ($pos &lt; strlen($conditional)) { $chr = $conditional{$pos}; $chr2 = $conditional{$pos+1}; $chr3 = $conditional{$pos+2}; if (($quotes1 == 1) and ($chr == '&quot;')) { $quotes1 = 0; } elseif (($quotes2 == 1) and ($chr == &quot;'&quot;)) { $quotes2 = 0; } elseif (($quotes1 == 0) and ($quotes2 == 0)) { if ($chr == '(') $depth++;                               if ($chr == ')') $depth--; if ($chr == '&quot;') $quotes1 = 1; if ($chr == &quot;'&quot;) $quotes2 = 1; }                       if (($depth == 0) and (preg_match('/^(\&lt;=|\&gt;=|\&lt;|\&gt;|==|or|\|\||and|&amp;&amp;|!=|\+|\-| \% |\^|\=|\||\&amp;)/i',$chr.$chr2.$chr3,$m)) and ($quotes1 == 0) and ($quotes2 == 0)) { $op = $m[1]; $part = 2; $pos += (strlen($op) - 1); } elseif ($part == 1) { $c1 .= $chr; } elseif ($part == 2) { $c2 .= $chr; }                       $pos++; }               $c1 = trim($c1); $op = trim($op); $c2 = trim($c2);

if (substr($c1,0,1) == '%') { $d1 = '$e1'; $e1 = &amp;$session['vars'][substr($c1,1)]; } elseif (substr($c1,0,1) == '$') { $d1 = 'evalfunction($c1,&amp;$session)'; } elseif ((substr($c1,0,1) == '(') and (substr($c1,-1,1) == ')')) { $d1 = 'evalconditional($e1,&amp;$session)'; $e1 = substr($c1,1,-1); } elseif (((substr($c1,0,1) == '&quot;') and (substr($c1,-1,1) == '&quot;')) or ((substr($c1,0,1) == &quot;'&quot;) and (substr($c1,-1,1) == &quot;'&quot;))) { $d1 = '$e1'; if (substr($c1,0,1) == '&quot;') { $c1 = str_replace(array('\n', '\r'),array(&quot;\n&quot;, &quot;\r&quot;),$c1); } $e1 = substr($c1,1,-1); } elseif (preg_match('/^[0-9+-]*$/',$c1)) { $d1 = $c1; } else { $d1 = 'false'; }

if (($op) and ($c2)) { if (substr($c2,0,1) == '%') { $d2 = '$e2'; $e2 = &amp;$session['vars'][substr($c2,1)]; } elseif (substr($c2,0,1) == '$') { $d2 = 'evalfunction($c2,&amp;$session)'; } elseif ((substr($c2,0,1) == '(') and (substr($c2,-1,1) == ')')) { $d2 = 'evalconditional($e2,&amp;$session)'; $e2 = substr($c2,1,-1); } elseif (((substr($c2,0,1) == '&quot;') and (substr($c2,-1,1) == '&quot;')) or ((substr($c2,0,1) == &quot;'&quot;) and (substr($c2,-1,1) == &quot;'&quot;))) { $d2 = '$e2'; if (substr($c2,0,1) == '&quot;') { $c2 = str_replace(array('\n', '\r'),array(&quot;\n&quot;, &quot;\r&quot;),$c2); } $e2 = substr($c2,1,-1); } elseif (preg_match('/^[0-9+-]*$/',$c2)) { $d2 = $c2; } else { $d2 = 'false'; }

if ($debug) echo 'eval(\'$ret = ('.$d1.' '.$op.' '.$d2.');\');'.&quot;\n&quot;; eval('$ret = ('.$d1.' '.$op.' '.$d2.');'); } else { if ($debug) echo 'eval(\'$ret = '.$d1.';\');'.&quot;\n&quot;; eval('$ret = '.$d1.';'); }               return $ret; }

function evalstatement ($statement,&amp;$session) { global $wpq; global $wpapi; global $wpi; global $debug;

if ($debug) echo 'evalstatement(&quot;'.$statement.'&quot;,'.serialize($session).');'.&quot;\n&quot;; $statements = array (                       'if',                   'set',                        'unset',                'while',                        'foreach',              'pagereplace',                        'pageappend',           'pagepregreplace',                        'pageget',              'pageset',                        'pageprepend',          'varappend',                        'varprepend',           'getrecentchanges',                        'getcategorymembers',   'eval',                        'getmodifiedtime',      'getbacklinks',                        'getembeddedin'                        );

foreach ($statements as $s) { if (strtolower(substr($statement,0,strlen($s))) == $s) { $rest = substr($statement,strlen($s)); switch ($s) { case 'while': case 'if': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session,false); //                                             print_r($tmp); if ($s == 'if') { if (evalconditional($tmp[0],&amp;$session)) { evalscript($tmp[1],&amp;$session); }                                               } elseif ($s == 'while') { while (evalconditional($tmp[0],&amp;$session)) { evalscript($tmp[1],&amp;$session); }                                               }                                                break; case 'set': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); $tmp[0] = $tmp[1]; break; case 'unset': $rest = trim($rest); if ($rest{0} == '%') { unset($session['vars'][substr($rest,1)]); }                                               break; case 'pagereplace': case 'pagepregreplace': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); $page = $tmp[0]; $search = $tmp[1]; $replace = $tmp[2]; if (isset($tmp[3])) { $editsummary = $tmp[3]; } else { $editsummary = 'Replacing &quot;'.$search.'&quot; with &quot;'.$replace.'&quot;. (bot)'; }                                               if ($s == 'pagereplace') { $wpi-&gt;post($page,str_replace($search,$replace,$wpq-&gt;getpage($page)),$editsummary); } elseif ($s == 'pagepregreplace') { $wpi-&gt;post($page,preg_replace($search,$replace,$wpq-&gt;getpage($page)),$editsummary); }                                               break; case 'pageappend': case 'pageprepend': case 'pageset': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); $page = $tmp[0]; $data = $tmp[1]; if (isset($tmp[2])) { $editsummary = $tmp[2]; } else { if ($s == 'pageappend') { $editsummary = 'Appending &quot;'.((strlen($data) &gt; 150)?substr($data,0,150).'...':$data).'&quot;. (bot)'; } elseif ($s == 'pageset') { $editsummary = 'Setting page to &quot;'.((strlen($data) &gt; 100)?substr($data,0,100).'...':$data).'&quot;. (bot)'; }                                               }                                                if ($s == 'pageappend') { $data = $wpq-&gt;getpage($page).$data; } elseif ($s == 'pageprepend') { $data = $data.$wpq-&gt;getpage($page); }                                               $wpi-&gt;post($page,$data,$editsummary); break; case 'pageget': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); $page = $tmp[0]; $tmp[1] = $wpq-&gt;getpage($page); break; case 'varappend': case 'varprepend': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if ($s == 'varprepend') { $tmp[0] = $tmp[1].$tmp[0]; } elseif ($s == 'varappend') { $tmp[0] .= $tmp[1]; }                                               break; case 'foreach': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); foreach (explode($tmp[1],$tmp[0]) as $tmp[2]) { evalscript(trim($tmp[3]),&amp;$session); }                                               break; case 'getrecentchanges': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if (count($tmp) == 2) { $x = $wpapi-&gt;recentchanges; } elseif (count($tmp) == 3) { $x = $wpapi-&gt;recentchanges($tmp[2]); }                                               $z = array; foreach ($x as $y) { $z[] = $y['title']; }                                               $tmp[0] = implode($tmp[1],$z); break; case 'getcategorymembers': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if (count($tmp) == 3) { $x = $wpapi-&gt;categorymembers($tmp[2]); } elseif (count($tmp) == 4) { $x = $wpapi-&gt;categorymembers($tmp[2],$tmp[3]); } elseif (count($tmp) == 5) { $x = $wpapi-&gt;categorymembers($tmp[2],$tmp[3],$tmp[4]); }                                               $z = array; foreach ($x as $y) { $z[] = $y['title']; } $tmp[0] = implode($tmp[1],$z); break; case 'getbacklinks': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if (count($tmp) == 3) { $x = $wpapi-&gt;backlinks($tmp[2]); } elseif (count($tmp) == 4) { $x = $wpapi-&gt;backlinks($tmp[2],$tmp[3]); } elseif (count($tmp) == 5) { $x = $wpapi-&gt;backlinks($tmp[2],$tmp[3],$tmp[4]); }                                               $z = array; foreach ($x as $y) { $z[] = $y['title']; } $tmp[0] = implode($tmp[1],$z); break; case 'getembeddedin': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if (count($tmp) == 3) { $x = $wpapi-&gt;embeddedin($tmp[2]); } elseif (count($tmp) == 4) { $x = $wpapi-&gt;embeddedin($tmp[2],$tmp[3]); } elseif (count($tmp) == 5) { $x = $wpapi-&gt;embeddedin($tmp[2],$tmp[3],$tmp[4]); }                                               $z = array; foreach ($x as $y) { $z[] = $y['title']; } $tmp[0] = implode($tmp[1],$z); break; case 'getmodifiedtime': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); if (count($tmp) == 2) { $x = $wpapi-&gt;revisions($tmp[1]); if (preg_match('/(\d+)\-(\d+)\-(\d+)T(\d+):(\d+):(\d+)/',$x[0]['timestamp'],$m)) { $tmp[0] = gmmktime($m[4],$m[5],$m[6],$m[2],$m[3],$m[1]); }                                               }                                                break; case 'eval': $tmp = array; getarguments($rest,&amp;$tmp,&amp;$session); evalscript($tmp[0],&amp;$session); break; }                               break; }               }        }

function evalscript ($script,&amp;$session = array) { /* Ok, we need to evaluate a ClueBot Script. */               global $debug; if ($debug) echo 'evalscript(&quot;'.$script.'&quot;,'.serialize($session).');'.&quot;\n&quot;;

$pos = 0; $quotes1 = 0; $quotes2 = 0; $depth = 0; $script = trim($script); $tmp = '';

if ((substr($script,0,1) == '{') and (substr($script,-1,1) == '}')) { $script = trim(substr($script,1,-1)); }

while ($pos &lt; strlen($script)) { if (($quotes1 == 1) and ($script{$pos} == '&quot;')) $quotes1 = 0; elseif (($quotes2 == 1) and ($script{$pos} == &quot;'&quot;)) $quotes2 = 0; elseif (($quotes1 == 0) and ($quotes2 == 0)) { if ($script{$pos} == '&quot;') $quotes1 = 1; if ($script{$pos} == &quot;'&quot;) $quotes2 = 1; if ($script{$pos} == '{') $depth++; if ($script{$pos} == '}') $depth--; if ((($script{$pos} == ';') or ($script{$pos} == '}')) and ($depth == 0)) { if ($script{$pos} == '}') $tmp .= $script{$pos}; evalstatement(trim($tmp),&amp;$session); $tmp = ''; $pos++; continue; }                       }                        $tmp .= $script{$pos}; $pos++; }       } ?&gt;

Interpreter
(cbs_interpreter.php)

&lt;?PHP include 'cluebot2.cbsfunctions.php'; include 'wikibot.classes.php'; include 'cluebot2.config.php';

$wpq = new wikipediaquery; $wpi = new wikipediaindex; $wpapi = new wikipediaapi;

$wpapi-&gt;login($user,$pass);

$debug = false; $session = array; evalscript(file_get_contents($_SERVER['argv'][1]),&amp;$session); /* Comment the following lines out if you don't want debugging */ if (is_array($session['vars'])) { foreach ($session['vars'] as $var =&gt; $value) { echo '%'.$var.' = '.$value.&quot;\n&quot;; }       } ?&gt;

Config
(cluebot2.config.php)

&lt;?PHP $owner = '';/* Put your username between the two single quotes. */       $user = ''; /* Put your bot's username between the two single quotes. */       $pass = ''; /* Put your bot's password between the two single quotes. */       $status = 'rw'; $maxlag = 2; /* Max lag */ $maxlagkeepgoing = true; /* If we get a maxlag error, keep going */ ?&gt;

Example
(test.cbs)

pageappend &quot;Wikipedia:Sandbox&quot; &quot;\n\nThis is a test.\n&quot;;

Documentation
See ClueBot Script documentation.