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.


Reply via email to