Knuckle Cracker

Knuckle Cracker => Support => Topic started by: warren on April 02, 2015, 03:35:44 PM

Title: CRPL return malfunction.
Post by: warren on April 02, 2015, 03:35:44 PM
Is it possible to leave a function more times than entering it?
Apparently:

  ShowTraceLog
  20 0 do
    @renderBox
  loop

:renderBox
  "in" Trace

  6 0 do
    6 0 do
      "out" I J Trace3
      return

    loop
    "hello" Trace
  loop
    "bye" Trace
Title: Re: CRPL return malfunction.
Post by: Telanir on April 06, 2015, 08:52:27 PM
I wouldn't think of a function as more than a block of executed script in CRPL. In essence that's all they really are so you aren't really "leaving" anything so much more as you are 'injecting' code into a single statement of @MyFunction.

What do you mean by 'leaving' and 'entering'?
If you mean you're getting "out" more than you're getting "in" traced that's probably because "out" is in the loop.
Title: Re: CRPL return malfunction.
Post by: warren on April 07, 2015, 05:08:32 PM
Pay close attention to that loop. It only gets executed once before hitting a return statement.

What you are referring to is inlining, and inlining is not supposed to have any effect on the behaviour of control structures.
Title: Re: CRPL return malfunction.
Post by: Grayzzur on April 07, 2015, 06:45:44 PM
Looks to me like it's the convergence of calling a function in a loop, and returning from that function in a loop. The loop call in the main script is triggering the next cycle of the inner loop inside the function. The whole thing is stack based, so even though you're returning out of a function in the script, it still has 3 active nested loops going (because you haven't broken out of or ended them), and the loop statement iterates over the innermost one.
Title: Re: CRPL return malfunction.
Post by: warren on April 07, 2015, 06:52:54 PM
All three loops are necessary for the anomalous behaviour. Lose any one, and everything works as expected.
Title: Re: CRPL return malfunction.
Post by: Telanir on April 07, 2015, 07:10:06 PM
No you're right, I retract my statement after doing some poking around. :P

One detail I'm not too sure about is whether K extends beyond functions, since according to the stack (at least I'd assume) the outermost loop (according to wiki (http://knucklecracker.com/wiki/doku.php?id=crpl:docs:k)) is still that one. And it always shows 0, there's no break statement in the first loop so it's baffling why it works like that. None of the loops are functioning at this point. Could you point out my mistake? I used Trace4 and added K after I J, always 0.
Title: Re: CRPL return malfunction.
Post by: warren on April 07, 2015, 09:07:42 PM
I cannot because I have not tested loop access between functions.
Title: Re: CRPL return malfunction.
Post by: Grayzzur on April 08, 2015, 09:11:34 AM
I would think at this point, you shouldn't expect a "bug fix" but should work on writing code that doesn't hit this bug. Can you provide an actual example where returning from a loop in a function is actually useful? Maybe we can help steer the code in a direction that doesn't hit this issue.
Title: Re: CRPL return malfunction.
Post by: warren on April 08, 2015, 01:23:27 PM
I have already fixed the issue with a workaround in my own code.

Here it is is in situ:
:renderBox
  FALSE ->forcereturn

  #render six by six square
  6 <-y1 do
    <-forcereturn if return endif
    I ->y1
    <-y0 <-y1 add dup ->y MapHeight gte if break endif
    6 <-x1 do
      I ->x1
      <-x0 <-x1 add dup ->x MapWidth gte if break endif

      #Watch the maximum time spent calculating
      <-load 10000 gt if TRUE ->forcereturn return endif
      @renderPoint ->terr
      <-map <-x <-y MapWidth mul add <-terr SetListElement
      @updateMap

    loop
    0 ->x1
  loop
  0 ->y1

  #Do the next box next time.
  <-y0 6 add dup ->y0 MapHeight gte if
    0 ->y0
    <-x0 6 add dup ->x0 MapWidth gte if
      0 ->x0
      #Unless you get to the end then trigger cleaning.
      FALSE ->isRendering
      TRUE ->isCleaning
      0 ->y0
      0 ->x1
      0 ->y1
      "Left click to zoom
Right click to start" SetText
      "Retro23" PlaySound
      return
    else
      <-x0 12 mod eq0 if "Misc9" else "Misc14" endif PlaySound
    endif
  endif

      "Rendering:
" <-x0 <-y0 MapHeight asfloat div 5 mul add
    MapWidth asfloat div 100 mul asint concat "%" concat SetText