CRPL Bug: Do-Loops break when you return from a do-looped function call

Started by Captain Ford, November 01, 2013, 07:08:37 PM

Previous topic - Next topic

Captain Ford

Here is a concise script that demonstrates the issue:

ClearTraceLog
ShowTraceLog
6 0 do
"MainLoop" I Trace2
I 2 eq if
"BeforeFuncCall" I Trace2
@CallAnotherDoLoop
"AfterFuncCall" I Trace2
endif
loop
"AfterLoop"

:CallAnotherDoLoop
3 0 do
return
loop


The expected output:
MainLoop 0
MainLoop 1
MainLoop 2
BeforeFuncCall 2
AfterFuncCall 2
MainLoop 3
MainLoop 4
MainLoop 5
AfterLoop

The actual output:

MainLoop 0
MainLoop 1
MainLoop 2
BeforeFuncCall 2
AfterFuncCall 2


The return statement must be in a do loop in another function call. If the function call doesn't have a do loop, the return causes no problems.

Also note that the "AfterLoop" trace is missing, so it allows the remainder of the main loop to complete and then kills the execution of the entire script.

I hope this is enough detail to identify and fix the problem.

Captain Ford

Spoiler
...?!?

Suddenly, the test script started working fine for me. I carefully reverted the changes I'd made in another script (the one where I first observed this behavior), and it broke again.

...so this is weird.


Disregard this, I can't reproduce it again.
[close]

See the attached map for a demonstration:

knucracker

That was tricky to fix...
Basically, the loop stack internal data structure wasn't getting pop'd when return was called (it does get pop'd if you call 'break' to exit the loop, then call return).  It's tricky to fix because 'return' has to know if it is nested in a looping structure.  The 'break' command already knows this and it is determined at compile time.  So, I just added the same logic to 'return'.

Captain Ford

Ah, wow ... that was faster than I expected. :P

Thanks for addressing this, Virgil.

knucracker