paladin-t / my_basic

A lightweight BASIC interpreter written in standard C in dual files. Aims to be embeddable, extendable and portable.
http://paladin-t.github.io/my_basic/
MIT License
507 stars 118 forks source link

Unexpected Step Handler Events #57

Closed nurbles closed 2 years ago

nurbles commented 2 years ago

I've created a little debugger to use with MY-BASIC scripts in my application and I've noticed some unexpected behavior with when the STEP handler is called.

  1. The first line between IF/THEN and ENDIF lines never triggers a step.
  2. The IF and/or ENDIF lines may trigger TWO steps (I think I've seen this with other lines, too.)
  3. When a subroutine (DEF/ENDDEF) contained within an INCLUDEd file returns, I get an 'intermediate' step that reports the NAME of the INCLUDE file but the ROW from the calling file where the call will return to. If this is intentional, is there a way to detect that this is the 'RETURN' event to avoid confusing users of my debugger?
  4. Sometimes, when returning from INCLUDEd code a step for ROW 0 is generated. (I'm ignoring all steps for ROW 0, but I'm not sure why I get them and this may be a mistake.)
  5. When a file is INCLUDEd, a step is generated for the first line of the included file -- even when the first line is a comment.

I'm attaching two short scripts that you may run with a step handler to see the unexpected (or not see the missing) steps. (For reference, I have the semicolon set as the EOL marker for PRINT statements.) I'm also attaching debug output produced from a test run with the example files that shows the row, column and source name for every call to the step handler, in case you are unable to duplicate my conditions.

Oh, I'm working with the 6/27/2021 version of the source (perhaps you could add a version number with he next update? ) If there's anything I can do to help, please let me know.

The files in the ZIP are:

example.zip

paladin-t commented 2 years ago

Now the mb_debug_set_stepped_handler function accepts two step handlers, prev and post, use prev to trace execution point.

It is v1.2.1 now, since the API has been changed.

nurbles commented 2 years ago

Thanks. I will need some time to figure out how to make the best use of this new feature. However, it does not appear to address the strange post step that occurs when leaving an imported file. I added debug output (attached) to every prev and post step call for the dbgTest/dbgSub files provided earlier. In the absence of documentation (and your deep understanding of your code) I cannot explain all of the 'Line 0' steps, or the final post step each time the function in dbgSub is called. Can you explain why these are correct or are you still looking at them?

Sorry I missed the version buried in the source file... I was expecting to see it in the header comment and on the github readme page. My bad there.

dbgTestSteps.zip

paladin-t commented 2 years ago

TL;DR: Sorry I didn't mention that post handler is no longer needed to write step-by-step debugging; and all line 0 steps in prev could be omitted.

BASIC code is parsed into intermediate structures, let's call it AST in this page. Most of the AST nodes are transformed from code, however there would be some dynamically created ones not in regard to any source code, but they perform particular roles in an AST. So when stepping over these position-less nodes, it feeds the handler with 0. Which could be omitted most of the time.

The post handler was the only step handler in the old version, as their names imply, prev and post are called before and after a step respectively. A post event is triggered after a statement is executed, the position is not the accurate end of that statement, but the beginning of the next statement sometimes. So the post position looks strange, and even stranger comparing to the prev position. I didn't change its behaviour, because it might break some existing projects' logic.