Skip to content

Instantly share code, notes, and snippets.

@alexpw
Created March 6, 2014 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexpw/9399593 to your computer and use it in GitHub Desktop.
Save alexpw/9399593 to your computer and use it in GitHub Desktop.
https://ochronus.com/brainfuck-in-clojure-in-40-lines/ - reformatted to be fewer lines (27) with no compromises in readability, and no more 1-line if statements.
(ns bf.core)
(defn bf-interpreter [program]
(letfn [(find-bracket [start-bracket end-bracket idx dir-fn]
(loop [i (dir-fn idx) opened 0]
(condp = (nth program i)
start-bracket (recur (dir-fn i) (inc opened))
end-bracket (if (zero? opened)
i
(recur (dir-fn i) (dec opened)))
(recur (dir-fn i) opened))))]
(loop [cells [0N], cell 0, idx 0]
(case (get program idx)
\< (recur cells (dec cell) (inc idx))
\+ (recur (update-in cells [cell] inc) cell (inc idx))
\- (recur (update-in cells [cell] dec) cell (inc idx))
\> (let [next-ptr (inc cell)
next-cells (if (= next-ptr (count cells))
(conj cells 0N)
cells)]
(recur next-cells next-ptr (inc idx)))
\. (do (print (char (nth cells cell)))
(recur cells cell (inc idx)))
\, (recur (assoc cells cell (.read System/in)) cell (inc idx))
\[ (recur cells cell (inc (if (zero? (nth cells cell))
(find-bracket \[ \] idx inc)
idx)))
\] (recur cells cell (find-bracket \] \[ idx dec))
nil cells
(recur cells cell (inc idx))))))
(defn -main [& args]
(if (nth args 0)
(bf-interpreter (slurp (nth args 0)))
(println "Please specify a brainfuck file as the first argument")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment