Advertisement
Guest User

Brainfuck interpreter in 3 lines

a guest
Jan 10th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns dadinn.brainfuck (:require [clojure.string :as s] [clojure.core.async :refer [chan go-loop close! <! >!]]))
  2. (defn exec-with [in out inst] (go-loop [data {} d 0 i 0] (if (< i (count inst)) (case (nth inst i) \> (recur data (inc d) (inc i)) \< (recur data (dec d) (inc i)) \+ (let [v (get data d 0)] (recur (assoc data d (inc v)) d (inc i))) \- (let [v (get data d 0)] (recur (assoc data d (dec v)) d (inc i))) \[ (if (zero? (get data d 0)) (let [k (loop [nest 0 j (inc i)] (case (nth inst j) \] (if (< 0 nest) (recur (dec nest) (inc j)) j) \[ (recur (inc nest) (inc j)) (recur nest (inc j))))] (recur data d (inc k))) (recur data d (inc i))) \] (if (not (zero? (get data d 0))) (let [k (loop [nest 0 j (dec i)] (case (nth inst j) \[(if (< 0 nest) (recur (dec nest) (dec j)) j) \] (recur (inc nest) (dec j)) (recur nest (dec j))))] (recur data d (inc k))) (recur data d (inc i))) \. (let [v (get data d 0)] (>! out v) (recur data d (inc i))) \, (let [v (or (<! in) 0)] (recur (assoc data d v) d (inc i))) (recur data d (inc i))) (close! out))))
  3. (defn exec [in inst] (let [out (chan 1)] (exec-with in out inst) out))
  4. (defmacro pipe [in inst & more] `(-> (exec ~in ~inst) ~@(for [i more] `(exec ~i))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement