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.
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.
See the attached map for a demonstration:
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'.
Ah, wow ... that was faster than I expected. :P
Thanks for addressing this, Virgil.
Grab the new 1.07 beta build and see if that fixes it (and hopefully doesn't break anything else).
http://knucklecracker.com/forums/index.php?topic=14505.0