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 <[email protected]> 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 <[email protected]> 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 >> 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 clojure.lang.AFn.invoke(AFn.java:35) >> at clojure.lang.Var.invoke(Var.java:411) >> at brainfuck.fuck$exec_instruction.invoke(fuck.clj:142) >> at brainfuck.fuck$begin_loop.invoke(fuck.clj:94) >> at clojure.lang.Var.invoke(Var.java:411) >> at brainfuck.fuck$exec_instruction.invoke(fuck.clj:149) >> at brainfuck.fuck$_main.invoke(fuck.clj:165) >> at clojure.lang.Var.invoke(Var.java:411) >> at user$eval218.invoke(NO_SOURCE_FILE:1) >> at clojure.lang.Compiler.eval(Compiler.java:6511) >> at clojure.lang.Compiler.eval(Compiler.java:6501) >> at clojure.lang.Compiler.eval(Compiler.java:6477) >> at clojure.core$eval.invoke(core.clj:2797) >> at clojure.main$eval_opt.invoke(main.clj:297) >> at clojure.main$initialize.invoke(main.clj:316) >> at clojure.main$null_opt.invoke(main.clj:349) >> at clojure.main$main.doInvoke(main.clj:427) >> at clojure.lang.RestFn.invoke(RestFn.java:421) >> at clojure.lang.Var.invoke(Var.java:419) >> at clojure.lang.AFn.applyToHelper(AFn.java:163) >> at clojure.lang.Var.applyTo(Var.java:532) >> at clojure.main.main(main.java:37) >> >> >> Aside from too much incidental complexity, I can't figure out what I did >> wrong here and why the loop never seems to stop iterating when it clearly >> should. Any help at all is sincerely appreciated. In fact, I'd love any >> pointers about the program structure itself if you care to take a look at my >> github. >> >> Thanks, >> >> --Andrew >> >> -- >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to [email protected] >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> [email protected] >> 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 [email protected]. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to [email protected] > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > [email protected] > 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 [email protected]. > For more options, visit https://groups.google.com/groups/opt_out. > > -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ "Perfection is the enemy of the good." -- Gustave Flaubert, French realist novelist (1821-1880) -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] 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 [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
