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.


Reply via email to