Skip to content

Instantly share code, notes, and snippets.

@igorw
Last active December 22, 2015 10:09
Show Gist options
  • Save igorw/6456447 to your computer and use it in GitHub Desktop.
Save igorw/6456447 to your computer and use it in GitHub Desktop.
(ns igorw.brainfuck)
; limitations:
; * does not support nested loops
(defn- iter [code {:keys [ip tape p in out]}]
(condp = (get code ip)
\> {:p (inc p)}
\< {:p (dec p)}
\+ {:tape (update-in tape [p] inc)}
\- {:tape (update-in tape [p] dec)}
\. {:out (conj out (char (get tape p)))}
\, (let [input-char (int (or (first in) 0))]
{:tape (assoc tape p input-char) :in (rest in)})
\[ (if (zero? (get tape p))
(let [code-segment (subs code (+ ip 1))
ip-offset (count (take-while #(not= % \]) code-segment))
ip (+ ip ip-offset 2)] ; hop over the ] bracket
{:ip ip})
{})
\] (let [code-segment (reverse (subs code 0 ip))
ip-offset (count (take-while #(not= % \[) code-segment))
ip (- ip ip-offset 1)] ; hop onto the [ bracket
{:ip ip})
{}))
(defn execute [code input]
(loop [state {:ip 0
:tape (vec (repeat 30000 0))
:p 0
:in input
:out []}]
; (prn ip (get code ip) (take 10 tape) p in out)
(let [{:keys [ip out]} state]
(if (= ip (count code))
(apply str out)
(recur (merge state
{:ip (inc ip)}
(iter code state)))))))
; hello world
(prn (execute ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+." ""))
; cat
(prn (execute ",[.,]" "foobar"))
(ns igorw.brainfuck)
; limitations:
; * does not support nested loops
(defn execute [code input]
(loop [ip 0
tape (vec (repeat 30000 0))
p 0
in input
out []]
; (prn ip (get code ip) (take 10 tape) p in out)
(if (= ip (count code))
(apply str out)
(condp = (get code ip)
\> (recur (inc ip) tape (inc p) in out)
\< (recur (inc ip) tape (dec p) in out)
\+ (recur (inc ip) (update-in tape [p] inc) p in out)
\- (recur (inc ip) (update-in tape [p] dec) p in out)
\. (recur (inc ip) tape p in (conj out (char (get tape p))))
\, (let [input-char (int (or (first in) 0))]
(recur (inc ip) (assoc tape p input-char) p (rest in) out))
\[ (if (zero? (get tape p))
(let [code-segment (subs code (+ ip 1))
ip-offset (count (take-while #(not= % \]) code-segment))
ip (+ ip ip-offset 2)] ; hop over the ] bracket
(recur ip tape p in out))
(recur (inc ip) tape p in out))
\] (let [code-segment (reverse (subs code 0 ip))
ip-offset (count (take-while #(not= % \[) code-segment))
ip (- ip ip-offset 1)] ; hop onto the [ bracket
(recur ip tape p in out))
(recur (inc ip) tape p in out)))))
; hello world
(prn (execute ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+." ""))
; cat
(prn (execute ",[.,]" "foobar"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment