Execute Brain**** is an implementation of Brainf***.
Other implementations of Brainf***.
RCBF is a set of Brainf*** compilers and interpreters written for Rosetta Code in a variety of languages.

Below are links to each of the versions of RCBF.

An implementation need only properly implement the following instructions:



Command

Description


 > 
 Move the pointer to the right


 < 
 Move the pointer to the left


 + 
 Increment the memory cell under the pointer


 - 
 Decrement the memory cell under the pointer


 . 
 Output the character signified by the cell at the pointer


 , 
 Input a character and store it in the cell at the pointer


 [ 
 Jump past the matching ] if the cell under the pointer is 0


 ] 
 Jump back to the matching [ if the cell under the pointer is nonzero

Any cell size is allowed,   EOF   (End-O-File)   support is optional, as is whether you have bounded or unbounded memory.




#!/usr/bin/env bash
# BrainF*** interpreter in bash
if (( ! $# )); then
  printf >&2 'Usage: %s program-file\n' "$0"
  exit 1
fi
 
# load the program
exec 3<"$1"
program=()
while IFS=  read -r line <&3; do
  mapfile -t instr < <(tr -cd '[]<>.,+-' <<<"$line" | sed $'s/./&\\\n/g')
  program+=("${instr[@]}")
done
exec 3<&-
 
# parse loops
loops=()
matches=()
for pc in "${!program[@]}"; do
  instr=${program[pc]}
  if [[ $instr == '[' ]]; then
    loops=("$pc" "${loops[@]}")
  elif [[ $instr == ']' ]]; then
    matches[$pc]=${loops[0]}
    matches[${loops[0]}]=$pc
    loops=(${loops[@]:1})
  fi
done
 
# execute program
memory=(0)
mp=0
pc=0
while (( pc < ${#program[@]} )); do
  instr=${program[pc]}
  (( pc+=1 ))
  mem=${memory[mp]}
  case "$instr" in 
    '[') if (( ! mem )); then (( pc=${matches[pc-1]}+1 )); fi;;
    ']') if (( mem )); then (( pc=${matches[pc-1]}+1 )); fi;;
    +) memory[mp]=$(( (mem + 1) % 256 ));;
    -) memory[mp]=$(( (mem - 1) % 256 ));;
    '>') (( mp+=1 )); if (( mp >= ${#memory[@]} )); then memory+=(0); fi;;
    '<') (( mp-=1 )); if (( mp < 0 )); then memory=(0 "${memory[@]}"); mp=0; fi;;
    .) printf %b $(printf '\\%03o' "$mem");;
    ,) read -n1 c; memory[mp]=$(LC_CTYPE=C printf '%d' "'$c");;
  esac
done