', '', $code); $code = str_replace('><', '', $code); $code = str_replace('+-', '', $code); $code = str_replace('-+', '', $code); $code = str_replace('[-][-]', '', $code); // A wonderful optimization would be removing the complete second bracket and all its contents $p = strpos($code, '[-]['); // TODO: hier könnte noch ein "." dazwischenstehen if ($p !== false) { $c = 0; for ($i=$p+3; $i $rSrc) { pbf_right($rDst-$rSrc); } else if ($rDst < $rSrc) { pbf_left($rSrc-$rDst); } else { // The references are equal. Nothing to do. } } // Description: Adds or subtracts until the current cell value will be $vDst // Input parameters: (Integer constant) vSrc // (Integer constant) vDst // Moves pointer to: Does not move pointer function pbf_deltainc($vSrc, $vDst) { if ($vDst > $vSrc) { pbf_inc($vDst-$vSrc); } else if ($vDst > $vSrc) { pbf_dec($vSrc-$vDst); } else { // The values are equal. Nothing to do. } } // Description: Goes to the cell referenced with rReference // Input parameters: (Reference) rReference // Moves pointer to: rReference function pbf_goto($rReference) { global $_curreference; pbf_deltamove($_curreference, $rReference); $_curreference = $rReference; } // Description: Returns the reference to the current pointer. Does only work if the pointer is consistent // Input parameters: None // Moves pointer to: Pointer will not be moved function pbf_get_cur_reg() { global $_curreference; return $_curreference; } // Description: Allocates a cell having the value $vValue, and returns the reference // Input parameters: None // Moves pointer to: Newly allocated reference function pbf_getmem_v($vValue) { $rOut = pbf_getmem_z(); pbf_goto($rOut); pbf_inc($vValue); return $rOut; } // Description: Allocates a cell (having an arbitary value), and returns the reference // Input parameters: None // Moves pointer to: Pointer will not be moved function pbf_getmem() { global $_curreference, $_memmap, $_cfg_getmem_occupies_zeroed_cells, $_max_memmap; if (!isset($_memmap[$_curreference])) { // Bingo $_memmap[$_curreference] = 2; // occupied $_max_memmap = max($_max_memmap, $_curreference); return $_curreference; } $m = $_cfg_getmem_occupies_zeroed_cells ? 2 : 1; for ($i=$_curreference+1; true; $i++) { if (!isset($_memmap[$i]) || ($_memmap[$i] < $m)) { $steps_right = $i-$_curreference; $reg_right = $i; break; } } $reg_left = null; for ($i=$_curreference-1; $i>=0; $i--) { if (!isset($_memmap[$i]) || ($_memmap[$i] < $m)) { $steps_left = $_curreference-$i; $reg_left = $i; break; } } if (isset($reg_left) && ($steps_right > $steps_left)) { $_memmap[$reg_left] = 2; // occupied $_max_memmap = max($_max_memmap, $reg_left); return $reg_left; } else { $_memmap[$reg_right] = 2; // occupied $_max_memmap = max($_max_memmap, $reg_right); return $reg_right; } } // Description: Allocates a cell with the value being guaranteed zero, and returns the reference // Input parameters: None // Moves pointer to: UNDEFINED! You must use _go() or any other statement to get a consistant memory pointer again function pbf_getmem_z() { global $_curreference, $_memmap, $_cfg_zero_max_search_range, $_max_memmap, $_cfg_safe_getmem_z, $_cur_bracket_indent; if (isset($_memmap[$_curreference]) && ($_memmap[$_curreference] == 1)) { // Bingo $_memmap[$_curreference] = 2; // occupied $_max_memmap = max($_max_memmap, $_curreference); // we need explicit zeroing, because during a loop in runtime, the cell (which is reserved during compile time) is multiple times used. if ($_cfg_safe_getmem_z && ($_cur_bracket_indent > 0)) pbf_zero($_curreference); return $_curreference; } $reg_right = null; for ($i=$_curreference+1; $i<$_curreference+1+$_cfg_zero_max_search_range; $i++) { if (isset($_memmap[$i]) && ($_memmap[$i] == 1)) { $steps_right = $i-$_curreference; $reg_right = $i; break; } } $reg_left = null; for ($i=$_curreference-1; $i>=max(-1,$_curreference-1-$_cfg_zero_max_search_range); $i--) { if (isset($_memmap[$i]) && ($_memmap[$i] == 1)) { $steps_left = $_curreference-$i; $reg_left = $i; break; } } if (isset($reg_left) && ($steps_right > $steps_left)) { $_memmap[$reg_left] = 2; // occupied $_max_memmap = max($_max_memmap, $reg_left); if ($_cfg_safe_getmem_z && ($_cur_bracket_indent > 0)) pbf_zero($reg_left); return $reg_left; } else if (isset($reg_right)) { $_memmap[$reg_right] = 2; // occupied $_max_memmap = max($_max_memmap, $reg_right); if ($_cfg_safe_getmem_z && ($_cur_bracket_indent > 0)) pbf_zero($reg_right); return $reg_right; } else { // Nothing found around $max_search_range $reg = pbf_getmem(); pbf_zero($reg); $_max_memmap = max($_max_memmap, $reg); if ($_cfg_safe_getmem_z && ($_cur_bracket_indent > 0)) pbf_zero($reg); return $reg; } } // Description: Frees the cell reference, so the cell can be re-allocated using a getmem() function later // Input parameters: (Reference) rReference // Moves pointer to: Does not move pointer function pbf_freemem($rReference) { global $_memmap, $_cur_bracket_indent, $_to_free, $_cfg_safe_memory_reservation; if ($_cfg_safe_memory_reservation && ($_cur_bracket_indent > 0)) { // We need to free the memory later, since we are in a loop, which can only be evaluated in runtime. $_to_free[] = $rReference; } else { $_memmap[$rReference] = 0; } } // Description: Frees the cell reference, so the cell can be re-allocated using a getmem() function later // Input parameters: (Reference) r0Reference (cell has to be zero!) // Moves pointer to: Does not move pointer function pbf_freemem_0($r0Reference) { global $_memmap, $_cur_bracket_indent, $_to_free_z, $_cfg_safe_memory_reservation; if ($_cfg_safe_memory_reservation && ($_cur_bracket_indent > 0)) { // We need to free the memory later, since we are in a loop, which can only be evaluated in runtime. $_to_free_z[] = $r0Reference; } else { $_memmap[$r0Reference] = 1; } } // Description: Adds a constant integer to the currently selected cell // Input parameters: (Integer constant) vAmount : Amount to add // Moves pointer to: Currently selected cell function pbf_inc($vAmount=1) { pbf_emit_bf(str_repeat('+', $vAmount)); } // Description: Substracts a constant integer to the currently selected cell // Input parameters: (Integer constant) vAmount : Amount to substract // Moves pointer to: Currently selected cell function pbf_dec($vAmount=1) { pbf_emit_bf(str_repeat('-', $vAmount)); } // Description: Moves the pointer vAmount times to the left // Input parameters: (Integer constant) vAmount // Moves pointer to: vAmount cells to the left function pbf_left($vAmount=1) { global $_cur_bracket_indent, $_curreference, $_cfg_optimize_shiftcontrol; if ($_cfg_optimize_shiftcontrol && ($_cur_bracket_indent == 0)) $_curreference -= $vAmount; pbf_emit_bf(str_repeat('<', $vAmount)); } // Description: Moves the pointer vAmount times to the right // Input parameters: (Integer constant) vAmount // Moves pointer to: vAmount cells to the right function pbf_right($vAmount=1) { global $_cur_bracket_indent, $_curreference, $_cfg_optimize_shiftcontrol; if ($_cfg_optimize_shiftcontrol && ($_cur_bracket_indent == 0)) $_curreference += $vAmount; pbf_emit_bf(str_repeat('>', $vAmount)); } // Description: Start marker of a loop at cell referenced by $rReference // Input parameters: (Reference) rReference // Moves pointer to: rReference if $rReference is set, otherwise stay at current cell function pbf_beginloop($rReference=null) { global $_cur_bracket_indent; if (!is_null($rReference)) pbf_goto($rReference); $_cur_bracket_indent++; pbf_emit_bf('['); } // Description: End marker of a loop at cell referenced by $rReference // Input parameters: (Reference) rReference // Moves pointer to: rReference if $rReference is set, otherwise stay at current cell function pbf_endloop($rReference=null) { global $_cur_bracket_indent, $_to_free, $_to_free_z; if (!is_null($rReference)) pbf_goto($rReference); $_cur_bracket_indent--; if ($_cur_bracket_indent == 0) { foreach ($_to_free as $r) { pbf_freemem($r); } $_to_free = array(); foreach ($_to_free_z as $rz) { pbf_freemem_0($rz); } $_to_free_z = array(); } pbf_emit_bf(']'); } function pbf_out($vAmount=1) { pbf_emit_bf(str_repeat('.', $vAmount)); } function pbf_in($vAmount=1) { pbf_emit_bf(str_repeat(',', $vAmount)); } // --- HIGHER LEVEL FUNCTIONS --- // Description: Calculates [raDst] <- [rzSrc] // [rzSrc] <- 0 // Input parameters: (Reference[s]) raDst // (Reference) rzSrc (becomes zeroed) // Moves pointer to: rzSrc function pbf_mov_z($raDst, $rzSrc) { if (!is_array($raDst)) $raDst = array($raDst); if (in_array($rzSrc, $raDst)) { throw new Exception("Src and Dst must be different references.\n"); } pbf_zero($raDst); pbf_add_z($raDst, $rzSrc); } // Description: Calculates [raDst] <- [rzSrc] // Input parameters: (Reference[s]) raDst // (Reference) rSrc // Moves pointer to: rtzTmp function pbf_cpy($raDst, $rSrc) { // doesn't work because of circular reference between pbf_cpy() and pbf_add() /* pbf_zero($raDst); pbf_add($raDst, $rSrc); return; */ if (!is_array($raDst)) $raDst = array($raDst); $rtzTmp = pbf_getmem(); $a = $raDst; $a[] = $rtzTmp; pbf_mov_z($a, $rSrc); pbf_add_z($rSrc, $rtzTmp); pbf_freemem_0($rtzTmp); } // Description: Calculates [raDst] <- [rzSrc] // [rzSrc] <- 0 // Input parameters: (Reference[s]) raDst // (Reference) rzSrc (becomes zeroed) // Moves pointer to: rzSrc function pbf_add_z($raDst, $rzSrc) { if (!is_array($raDst)) $raDst = array($raDst); if (in_array($rzSrc, $raDst)) { throw new Exception("Src and Dst must be different references.\n"); } pbf_beginloop($rzSrc); pbf_dec(); foreach ($raDst as $rDst) { pbf_goto($rDst); pbf_inc(); } pbf_endloop($rzSrc); } // Description: Calculates [raDst] <- [raDst] + vAmount // Input parameters: (Reference[s]) raDst // (Integer constant) vAmount // Moves pointer to: raDst function pbf_add_v($raDst, $vAmount) { if (!is_array($raDst)) $raDst = array($raDst); foreach ($raDst as $rDst) { pbf_goto($rDst); pbf_inc($vAmount); } } // Description: Calculates [raDst] <- [raDst] + [rSrc] // Input parameters: (Reference[s]) raDst // (Reference) rSrc // Moves pointer to: rtzSrcBak function pbf_add($raDst, $rSrc) { $rtzSrcBak = pbf_getmem(); pbf_cpy($rtzSrcBak, $rSrc); pbf_add_z($raDst, $rtzSrcBak); pbf_freemem_0($rtzSrcBak); } // Description: Prints a string // Input parameters: (String constant) vStr // Moves pointer to: Moves pointer to freed cell function pbf_printstr($vStr) { if ($vStr == '') return; $rChar = pbf_getmem_z(); pbf_goto($rChar); $c_prev = 0; for ($i=0; $i