changed git call from https to git readonly
[atutor.git] / mods / wiki / plugins / mpi / off / mpi_brainfuck.php
1 <?php
2
3 /*
4    This plugin allows you to use the toy programming language known
5    as "Brainfuck", which is turing complete with only 8 commands:
6
7    > increment pointer into data array
8    < decrement the data pointer
9    + increment the byte at the pointer
10    - decrement the data byte
11    . output the byte at the pointer
12    , input a byte, store it into the data array
13    [ starts a code block, only run if current data byte is zero
14    ] loop back to the opening bracket
15
16    You simply write:
17    <?plugin BrainFuck
18       ++>++++++++++[-<+++++++>]<.+>+++++++[-<++++>]<.++>++
19       +++[-<+>]<..+++.------>+++++++++[-<-------->]<.
20    ?>
21    Or
22    <?plugin-input BrainFuck ....code.... ?>
23
24    You must first create a symlink in the mpi/ main directory to
25    here, else this can't be used (disabled because it could slow
26    down wiki sites).
27 */
28
29
30 $ewiki_plugins["mpi"]["brainfuck"] = "ewiki_mpi_brainfuck";
31 function ewiki_mpi_brainfuck($action, $args, &$iii, &$s)
32 {
33    global $ewiki_id;
34
35    if ($action == "input") {
36       return('<form action="'.ewiki_script("", $ewiki_id).'">'
37             .'<input name="i" type="text"> '
38             .'<input type="hidden" name="id" value="'.htmlentities($ewiki_id).'">'
39             .'<input type="submit"></form>'
40       );
41    }
42    else {
43       $input = "";
44       foreach ($_REQUEST as $i=>$str) {
45          if (strlen($i)==1) {
46             $input .= $str;
47          }
48       }
49       return(bf_exec($args["_"], $input));
50    }
51 }
52
53
54 function bf_exec(&$code, $in)
55 {
56    $out = "";
57    $data[0] = 0;
58    $p = 0;
59    $in_len = strlen($in);
60    $in_p = 0;
61    $code_len = strlen($code);
62    $pc = 0;
63
64    while ($pc < $code_len) {
65       switch ($c=$code{$pc}) {
66
67          case ">":      // increment data pointer
68            $p++;
69            if ($p >= count($data)) {
70               $data[$p] = 0;
71            }
72            break;
73
74          case "<":      // decrement data pointer
75            if ($p) {
76               $p--;
77            }
78            break;
79
80          case "+":      // inc data byte
81            $data[$p]++;
82            break;
83
84          case "-":      // dec data byte
85            $data[$p]--;
86            break;
87
88          case ".":
89             $out .= chr($data[$p]);
90             break;
91
92          case ",":
93             if ($in_p < $in_len) {
94                $data[$p] = ord($in[$in_p++]);
95             }
96             else {
97                $data[$p] = 0;
98             }
99             break;
100
101          case "[":      // skip loop, if data byte is zero
102            if ($data[$p] == 0) {
103               $s = 1;
104               while ($s) {
105                  $c = $code[++$pc];
106                  if ($c == "[") {
107                     $s++;
108                  }
109                  elseif ($c == "]") {
110                     $s--;
111                  }
112               }
113            }
114            break;
115
116          case "]":      // repeat
117               $s = 1;
118               while ($s) {
119                  $c = $code[--$pc];
120                  if ($c == "[") {
121                     $s--;
122                  }
123                  elseif ($c == "]") {
124                     $s++;
125                  }
126               }             
127               $pc--;
128            break;
129
130          case "\n":
131          case "\r":
132          case "\f":
133          case "\t":
134          case " ":
135             break;
136
137          default:
138             $out .= " (PARSING ERROR '$c' at position #$pc)";
139             return($out);
140             break;
141       }
142
143       $pc++;
144    }
145
146    return($out);
147 }
148
149
150 ?>