Skip to content

Instantly share code, notes, and snippets.

@isopsephile
Created November 14, 2012 23:53
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 isopsephile/4075696 to your computer and use it in GitHub Desktop.
Save isopsephile/4075696 to your computer and use it in GitHub Desktop.
(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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment