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 <[email protected]> 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 <[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. > > -- -- 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.
