public
Created

  • Download Gist
brainfuck.clj
Clojure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
(defn pair-brackets [indexed]
(reduce
(fn [pairs cur]
(condp = (cur 1)
\[ (merge-with conj pairs {:pend (cur 0)})
\] (merge pairs
{(first (pairs :pend)) (cur 0)
(cur 0) (first (pairs :pend))
:pend (pop (pairs :pend))})
pairs))
{:pend ()} indexed))
 
(defn brainfuck [insns]
(let
[valid (set "[]<>-+.,")
program (vec (keep #(valid %) insns))
jumps (pair-brackets
(map vector (range) program))]
(loop
[pc 0 ; program counter
bp 0 ; byte pointer
tape {}]
(if (< pc (count program))
(let [insn (program pc)
cur (tape bp 0)]
(if (= \. insn)
(print (char cur)))
(recur
((cond
(and (= \[ insn) (= 0 cur)) jumps
(and (= \] insn) (not= 0 cur)) jumps
:else inc) pc)
(({\< dec \> inc} insn identity) bp)
(cond
(#{\- \+} insn)
(merge tape {bp (({\- dec \+ inc} insn) cur)})
(= \, insn)
(merge tape {bp (. System/in read)})
:else tape)))))))
 
(-> *command-line-args*
last slurp brainfuck)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.