CRPL return malfunction.

Started by warren, April 02, 2015, 03:35:44 PM

Previous topic - Next topic

warren

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

Telanir

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.
Want to make genius CRPL? The new top map? You can start here!

Find out more about Creeper World 3 on the wiki!

CW3, The Sleeper Menace!

Own an iOS device? Check out my game Blobivers

warren

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.

Grayzzur

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.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

warren

All three loops are necessary for the anomalous behaviour. Lose any one, and everything works as expected.

Telanir

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) 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.
Want to make genius CRPL? The new top map? You can start here!

Find out more about Creeper World 3 on the wiki!

CW3, The Sleeper Menace!

Own an iOS device? Check out my game Blobivers

warren

I cannot because I have not tested loop access between functions.

Grayzzur

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.
"Fate. It protects fools, little children, and ships named 'Enterprise.'" -William T. Riker

warren

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