/** * Generates some code for program * * @param ProgramInterface $program * @return string */ public function generate(ProgramInterface $program) { try { $this->code = $program->getInstructions(); $out = []; $out[] = $this->generateHeader(); $out[] = $this->generateBody(); return implode("\n", $out); } finally { $this->code = []; } }
/** * Make optimization * * @param ProgramInterface $program * @return ProgramInterface optimizer program * @throws BrainfuckException */ public function optimize(ProgramInterface $program) { if (!$program instanceof BrainfuckProgram) { throw new BrainfuckException("Ouch crap... I can't optimize a not brainfuck programs"); } $code = $program->getInstructions(); $code = $this->toFixedAdressSpace($code); $code = $this->optimizeIncDecMasturbation($code); $code = $this->optimizeShiftMasturbation($code); $code = $this->optimizeDelays($code); $code = $this->restoreNativeAddressSpace($code); return new BrainfuckProgram($code); }
/** * {@inheritdoc} * * @param ProgramInterface $program */ public function execute(ProgramInterface $program) { $this->mem = array_fill(0, $this->memoryCapacity, 0x0); $this->cursor = 0; $p = $program->getInstructions(); for ($i = 0; $i < count($p); $i++) { $instr = $p[$i]; //printf("%d\t%s\n", $i, is_array($instr) ? sprintf("%s:%d", $instr[0], $instr[1]) : $instr); switch ($instr[0]) { case BC::TOKEN_ADD: $this->mem[$this->cursor] += $instr[1]; break; case BC::TOKEN_SUB: $this->mem[$this->cursor] -= $instr[1]; break; case BC::TOKEN_SHIFT: $this->cursor += $instr[1]; break; case BC::TOKEN_OUT: echo chr($this->mem[$this->cursor]); break; case BC::TOKEN_IN: while (true) { echo "Input integer value (0-255): "; $v = (int) trim(readline()); if (!is_int($v) || $v < 0x0 || $v > 0xff) { printf("Invalid value, try again\n"); continue; } $this->mem[$this->cursor] = $v; break; } break; case BC::TOKEN_NOOP: //noop break; case BC::TOKEN_JNE: if (!$this->mem[$this->cursor]) { $i = $instr[1] - 1; } break; case BC::TOKEN_JMP: $i = $instr[1] - 1; break; } } }