Skip to content

Instantly share code, notes, and snippets.

@durka
Created May 29, 2009 06:33
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 durka/119815 to your computer and use it in GitHub Desktop.
Save durka/119815 to your computer and use it in GitHub Desktop.
(defn drive-subleq
"Runs an OISC SUBLEQ program. Given the program (as a list of integers) and the input (in the same way), it runs the program and returns the output."
[program input]
(let [-out- (count program)
-in- (inc -out-)
input-len (count input)]
(loop [mem (vec (concat program
[0 (if (zero? input-len) -1 (nth input 0))] ; fill in the first char of the input now, unless there is no input, in which case give EOF right away
(vec (range 0 1023)))) ; memory starts out as the program, then the special output cell, then the special input cell, followed by 1024 memory cells filled with the numbers from 0 to 1023
regs {:ip 0}
output ""]
(let [[mem regs] (subleq -in- -out- mem regs)]
(if (and (:in regs)
(neg? (mem -in-)))
[output (- -1 (mem -in-))] ; if wrote a negative value to -in-, exit with one less than its absolute value (so write -1 to exit with code 0)
(let [output (str output
(if (:out regs) ; if there is new output, append it
(char (mem -out-))))
mem (assoc mem -in- (if (:in regs) ; if something was written to IN, honor it
(if (or (>= (mem -in-) input-len)
(neg? (mem -in-)))
-1
(nth input (mem -in-)))
(mem -in-))
-out- 0) ; OUT should always contain zero
regs (dissoc regs :in :out)]
(recur mem regs output)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment