Re: Function recurring regardless of condition
You might be interested in https://github.com/amalloy/clusp/blob/master/src/snusp/core.clj, my Clojure interpreter for SNUSP (which is brainfuck with different control-flow mechanics). It's purely functional, and IMO does a good job of separating concerns; both of those are things it sounds like you were having trouble with, so hopefully reading it will give you some ideas. Basically my approach is to have an object (hash-map) that represents the state of the interpreter (the world), and compile each instruction to a function before doing anything. Then, I just look up the instruction at the current position, call it on the world, and use the returned world for the next step. On Saturday, April 6, 2013 4:49:36 PM UTC-7, Andrew Spano wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 28 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 29 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 30 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 31 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 32 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 33 instruct #'brainfuck.fuck/plus minus one
Re: Function recurring regardless of condition
Incidentally, this thread made me feel a sudden desire to write my own bf interpreter. Feel free to take a look at https://github.com/michalmarczyk/bf.clj if you'd like. :-) Cheers, Michał On 7 April 2013 05:23, Sean Corfield seancorfi...@gmail.com wrote: I agree. I see nothing that sets the code pointer back to the start of the loop. I also agree with Michał's suggestion that getting rid of global state and making this more functional in style will make it much easier to read, debug and maintain - as it stands it not very idiomatic for Clojure. Sean On Sat, Apr 6, 2013 at 5:16 PM, Michał Marczyk michal.marc...@gmail.com wrote: Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdnaon...@gmail.com wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 28 instruct
Re: Function recurring regardless of condition
And feel free to steal ideas from my Clojure BF-Native compiler. https://github.com/halgari/mjolnir/blob/master/src/examples/bf.clj Mjolnir Expressions are a bit different than Clojure, but it shouldn't be to hard to write a BF Clojure compiler using this as a starting place. Notice how the entire compiler builds up one gigantic S-Expression that describes the current position of the index pointer. This sort of approach works well with constant folding optimizations. Anyway just one more place to draw ideas from. Timothy Baldridge On Sun, Apr 7, 2013 at 8:06 PM, Michał Marczyk michal.marc...@gmail.comwrote: Incidentally, this thread made me feel a sudden desire to write my own bf interpreter. Feel free to take a look at https://github.com/michalmarczyk/bf.clj if you'd like. :-) Cheers, Michał On 7 April 2013 05:23, Sean Corfield seancorfi...@gmail.com wrote: I agree. I see nothing that sets the code pointer back to the start of the loop. I also agree with Michał's suggestion that getting rid of global state and making this more functional in style will make it much easier to read, debug and maintain - as it stands it not very idiomatic for Clojure. Sean On Sat, Apr 6, 2013 at 5:16 PM, Michał Marczyk michal.marc...@gmail.com wrote: Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdnaon...@gmail.com wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one
Re: Function recurring regardless of condition
Awesome! I've been re-factoring my code but I am having difficulty figuring out how to deal with state without manipulating global state; my first thought was to create a binding form within a doseq in a function that executed each instruction and mutated the cells when necessary--but that didn't work out. I like your usage of multimethods to deal with each instruction, although as a beginner some parts of your code are difficult for me to follow. This is shaping up to be a pretty good learning experience for me! I think my mind is still stuck in an imperative mode of thinking, and it's helpful to look at the code of a more seasoned clojure programmer. On Sunday, April 7, 2013 10:06:26 PM UTC-4, Michał Marczyk wrote: Incidentally, this thread made me feel a sudden desire to write my own bf interpreter. Feel free to take a look at https://github.com/michalmarczyk/bf.clj if you'd like. :-) Cheers, Michał On 7 April 2013 05:23, Sean Corfield seanco...@gmail.com javascript: wrote: I agree. I see nothing that sets the code pointer back to the start of the loop. I also agree with Michał's suggestion that getting rid of global state and making this more functional in style will make it much easier to read, debug and maintain - as it stands it not very idiomatic for Clojure. Sean On Sat, Apr 6, 2013 at 5:16 PM, Michał Marczyk michal@gmail.comjavascript: wrote: Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdn...@gmail.com javascript: wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15
Function recurring regardless of condition
Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 28 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 29 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 30 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 31 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 32 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 33 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 34 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 35 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 36 instruct #'brainfuck.fuck/-pointer minus one index: 39 yeah you are index: 37 instruct #'brainfuck.fuck/-pointer minus one index: 39 yeah you are index: 38 instruct #'brainfuck.fuck/-pointer minus one index: 39 yeah you are index: 39 instruct #'brainfuck.fuck/-pointer minus one index: 39 yeah you are index: 40 instruct #'brainfuck.fuck/minus minus one index: 39 cell counter: 9 other: 9 at 0: 9 also: 41 index: 41 instruct #'brainfuck.fuck/end-loop minus one index: 39 Exception in thread main java.lang.IllegalStateException: Attempting to call unbound fn: #'brainfuck.fuck/end-loop at clojure.lang.Var$Unbound.throwArity(Var.java:43) at
Re: Function recurring regardless of condition
If there's too much incidental complexity and you know it, try working on reducing that first. It's quite likely the bug will shake out while you're doing so, and if not, it is likely to be much easier to find after you simplify and refactor the code. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Function recurring regardless of condition
Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdnaon...@gmail.com wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 28 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 29 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 30 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 31 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 32 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 33 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 34 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 35 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 36 instruct #'brainfuck.fuck/-pointer minus one index: 39 yeah you are
Re: Function recurring regardless of condition
PS. The above would mean that the loop/recur terminates as expected, it's just that next time this function is called it starts executing instructions at the wrong spot. Anyway, I agree that factoring the code in a more manageable fashion may be a more useful first step than hunting individual bugs. In particular, there seems to be quite a lot of global state in use; one good thing to do would be to try and replace it with explicit flow of data. (Apart from improving clarity and aiding debugging at the REPL, it would allow you to run multiple brainfuck programs in parallel. :-)) As for ending loops, you could make end-loop into a real instruction jumping back to an index recorded by begin-loop. M. On 7 April 2013 02:16, Michał Marczyk michal.marc...@gmail.com wrote: Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdnaon...@gmail.com wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39
Re: Function recurring regardless of condition
I agree. I see nothing that sets the code pointer back to the start of the loop. I also agree with Michał's suggestion that getting rid of global state and making this more functional in style will make it much easier to read, debug and maintain - as it stands it not very idiomatic for Clojure. Sean On Sat, Apr 6, 2013 at 5:16 PM, Michał Marczyk michal.marc...@gmail.com wrote: Not sure why you're using (- end-index 2) in the printed message. Also, you can use (dec end-index) in your termination condition. As for the main problem, I haven't studied your program very closely, but it seems to me that your program counter may never get reset to the beginning of the loop, in which case the next call to (exec-instruction end-loop) would start executing instructions just past the end of the loop body. Cheers, Michał On 7 April 2013 01:49, Andrew Spano werdnaon...@gmail.com wrote: Hello, I'm a new clojure programmer--but after learning a bit of clojure including iteration, some core high order functions, and a little bit about state management I decided to try my hand on a brainfuck interpreter. Located here: https://github.com/recursor94/brainfuck.clj/blob/master/brainfuck/src/brainfuck/fuck.clj Handling looping complicated things. And the way I chose to deal with looping resulted in some pretty ugly functions. I hope to clean that up in the future and refractor the code into a more functional style after I've finished the first draft. The issue is in a particular function which never stops recuring even when the condition for recuring is false: (defn exec-instruction executes each function in the codemap vector in sequential order ([end-index] (inc-code-pos) ;;side affect function that moves the code pointer (I have both a code pointer and a data pointer in my interpreter) (loop [index (:index @codemap)] (let [codevec (@codemap :struct) instruct (get codevec index)] (println index: index instruct instruct minus one index: (- end-index 2)) (instruct)) (when-not (= index (- end-index 1)) (println yeah you are) (inc-code-pos) (recur (inc index) ;;end problem ([] (doseq [instruct (@codemap :struct)] (instruct) ;;higher order functions ftw (inc-code-pos And here is the function that triggers this function: (defn begin-loop run through a loop until current cell drops to zero [] (loop [loop-counter (@cells @pointer) end-loop (find-end (@codemap :index)) ;;find-end returns an integer pos (@codemap :index)] (println cell counter: loop-counter other: (@cells @pointer) at 0: (@cells @pointer) also: end-loop) ;;debug output (exec-instruction end-loop) (when-not (= loop-counter 0) (recur (@cells @pointer) end-loop pos The program is supposed to stop when it reaches a closing end brace and jump back to the opening brace in the code. But the output indicates that the program never gets passed the first iteration. For example, given this hello world brainfuck program: ++[+-]++.+.+++..+++.++.+++..+++.--..+.. The program outputs the following: index: 11 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 12 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 13 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 14 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 15 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 16 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 17 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 18 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 19 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 20 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 21 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 22 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 23 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 24 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 25 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 26 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 27 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 28 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 29 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are index: 30 instruct #'brainfuck.fuck/+pointer minus one index: 39 yeah you are index: 31 instruct #'brainfuck.fuck/plus minus one index: 39 yeah you are