Execute Brain****
From Rosetta Code
Execute Brain****
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
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 '[', ']', '+', '-', '<', '>', ',', and '.' instructions. Any cell size is allowed, EOF support is optional, as is whether you have bounded or unbounded memory.
Contents |
[edit] ALGOL 68
[edit] Ada
[edit] AutoHotkey
[edit] BASIC
Implementation in BASIC (QuickBasic dialect).
[edit] C
[edit] C++
[edit] Clojure
(ns brainfuck)
(def *input*)
(def *output*)
(defstruct data :ptr :cells)
(defn inc-ptr [next-cmd]
(fn [data]
(next-cmd (assoc data :ptr (inc (:ptr data))))))
(defn dec-ptr [next-cmd]
(fn [data]
(next-cmd (assoc data :ptr (dec (:ptr data))))))
(defn inc-cell [next-cmd]
(fn [data]
(let [ptr (:ptr data)
cells (:cells data)]
(next-cmd (assoc data :cells (assoc cells ptr (inc (get cells ptr 0))))))))
(defn dec-cell [next-cmd]
(fn [data]
(let [ptr (:ptr data)
cells (:cells data)]
(next-cmd (assoc data :cells (assoc cells ptr (dec (get cells ptr 0))))))))
(defn output-cell [next-cmd]
(fn [data]
(set! *output* (conj *output* (get (:cells data) (:ptr data) 0)))
(next-cmd data)))
(defn input-cell [next-cmd]
(fn [data]
(let [[input & rest-input] *input*]
(set! *input* rest-input)
(next-cmd (assoc data :cells (assoc (:cells data) (:ptr data) input))))))
(defn if-loop [next-cmd loop-cmd]
(fn [data]
(next-cmd (loop [d data]
(if (zero? (get (:cells d) (:ptr d) 0))
d
(recur (loop-cmd d)))))))
(defn terminate [data] data)
(defn split-cmds [cmds]
(letfn [(split [[cmd & rest-cmds] loop-cmds]
(when (nil? cmd) (throw (Exception. "invalid commands: missing ]")))
(case cmd
\[ (let [[c l] (split-cmds rest-cmds)]
(split c (str loop-cmds "[" l "]")))
\] [(apply str rest-cmds) loop-cmds]
(split rest-cmds (str loop-cmds cmd))))]
(split cmds "")))
(defn compile-cmds [[cmd & rest-cmds]]
(if (nil? cmd)
terminate
(case cmd
\> (inc-ptr (compile-cmds rest-cmds))
\< (dec-ptr (compile-cmds rest-cmds))
\+ (inc-cell (compile-cmds rest-cmds))
\- (dec-cell (compile-cmds rest-cmds))
\. (output-cell (compile-cmds rest-cmds))
\, (input-cell (compile-cmds rest-cmds))
\[ (let [[cmds loop-cmds] (split-cmds rest-cmds)]
(if-loop (compile-cmds cmds) (compile-cmds loop-cmds)))
\] (throw (Exception. "invalid commands: missing ["))
(compile-cmds rest-cmds))))
(defn compile-and-run [cmds input]
(binding [*input* input *output* []]
(let [compiled-cmds (compile-cmds cmds)]
(println (compiled-cmds (struct data 0 {}))))
(println *output*)
(println (apply str (map char *output*)))))
brainfuck> (compile-and-run "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." [])
{:ptr 4, :cells {4 10, 3 33, 2 100, 1 87, 0 0}}
[72 101 108 108 111 32 87 111 114 108 100 33 10]
Hello World!
nil
[edit] Common Lisp
Implementation in Common Lisp.
[edit] D
[edit] E
[edit] Erlang
[edit] Forth
[edit] F#
[edit] Haskell
[edit] Icon and Unicon
[edit] Icon
[edit] Unicon
This Icon solution works in Unicon.
[edit] J
[edit] Java
[edit] JavaScript
[edit] Lua
[edit] Modula-3
[edit] OCaml
[edit] Perl
[edit] PicoLisp
This solution uses a doubly-linked list for the cell space. That list consists of a single cell initially, and grows automatically in both directions. The value in each cell is unlimited.
(off "Program")
(de compile (File)
(let Stack NIL
(setq "Program"
(make
(in File
(while (char)
(case @
(">"
(link
'(setq Data
(or
(cddr Data)
(con (cdr Data) (cons 0 (cons Data))) ) ) ) )
("<"
(link
'(setq Data
(or
(cadr Data)
(set (cdr Data) (cons 0 (cons NIL Data))) ) ) ) )
("+" (link '(inc Data)))
("-" (link '(dec Data)))
("." (link '(prin (char (car Data)))))
("," (link '(set Data (char (read)))))
("["
(link
'(setq Code
((if (=0 (car Data)) cdar cdr) Code) ) )
(push 'Stack (chain (cons))) )
("]"
(unless Stack
(quit "Unbalanced ']'") )
(link
'(setq Code
((if (n0 (car Data)) cdar cdr) Code) ) )
(let (There (pop 'Stack) Here (cons There))
(chain (set There Here)) ) ) ) ) ) ) )
(when Stack
(quit "Unbalanced '['") ) ) )
(de execute ()
(let Data (cons 0 (cons)) # Create initial cell
(for (Code "Program" Code) # Run program
(eval (pop 'Code)) )
(while (cadr Data) # Find beginning of data
(setq Data @) )
(filter prog Data '(T NIL .)) ) ) # Return data space
Output:
: (compile "hello.bf") -> NIL : (execute) Goodbye, World! -> (0 10 33 44 71 87 98 100 114 121)
[edit] PureBasic
[edit] Python
[edit] Ruby
[edit] Standard ML
Implementation in Standard ML.
[edit] TI-83 BASIC
Implementation in TI-83 BASIC.
[edit] TI-89 BASIC
Implementation in TI-89 Basic.
[edit] Tcl
Categories: Compilers and Interpreters | Programming Tasks | Solutions by Programming Task | Implementations | Brainf*** Implementations | Brainf*** related | ALGOL 68 | Ada | AutoHotkey | BASIC | C | C++ | Clojure | Common Lisp | D | E | Erlang | Forth | F Sharp | Haskell | Icon | Unicon | J | Java | JavaScript | Lua | Modula-3 | OCaml | Perl | PicoLisp | PureBasic | Python | Ruby | Standard ML | TI-83 BASIC | TI-89 BASIC | Tcl

