/
core.clj
64 lines (55 loc) · 1.59 KB
/
core.clj
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(ns braincloj.core)
(def operators {\+ :inc \- :dec
\< :prev \> :next
\, :getc \. :putc
\[ :loopin \] :loopout})
(defn- init-memory [size]
(vec (take size (repeat 0))))
(defn- loop-in [prog cp mp mem]
[(if (zero? (nth mem mp))
(loop [p cp]
(if (= (nth prog p) :loopout)
p
(recur (inc p))))
(inc cp))
mp mem])
(defn- loop-out [prog cp mp mem]
[(if (zero? (nth mem mp))
(inc cp)
(loop [p cp]
(if (= (nth prog p) :loopin)
p
(recur (dec p)))))
mp mem])
; +[+[++]++]+
(defn parse-loops [prog]
(map-indexed
(fn [idx op]
(if (= :loopin op)
"looping"
"other"))
prog))
(defn parse
"Parse a brainfuck string into a vector of keywords (see operators)"
[prog]
(vec (filter (complement nil?)
(map #(operators %) prog))))
(defn run
"Run a correct brainfuck program, parsed with braincloj.core/parse"
[prog]
(loop [cp 0 mp 0 mem (init-memory 10)]
(if (< cp (count prog))
(let [[cp mp mem] (case (nth prog cp)
:inc [(inc cp) mp (assoc mem mp (inc (nth mem mp)))]
:dec [(inc cp) mp (assoc mem mp (dec (nth mem mp)))]
:next [(inc cp) (inc mp) mem]
:prev [(inc cp) (dec mp) mem]
:loopin (loop-in prog cp mp mem)
:loopout (loop-out prog cp mp mem)
:putc (do
(print (char (nth mem mp)))
[(inc cp) mp mem])
[(inc cp) mp mem])]
;(println mem)
(recur cp mp mem)))))
(def hello-world (parse "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."))