Debug using DO

Started by Patrick on 19-Nov-2013/18:37:14-8:00
Hey Nick, I have a problem that i'm struggling with regarding debugging of code. I'd like to hear your approach to such issues, at least in r3. I like using a structured code approach where code is defined into a block and then at the end do 'ing the blocks to execute the code, like: 1000-mainline: [ do 1100-get-input do 1200-calc-value ] 1100-get-input: [ ... ] 1200-calc-value: [...] do 1000-mainline What I want to do is re-define the "do" statment to print a sequential number, then the do-block name, like this: 1 1000-mainline 2 1100-get-input 3 1200-calc-value How can I re-define the "do" to increment a counter, then print the do-block name and then perform the do itself? I tried to use the source command, but it didn't help much. I'd appreciate any insight you can give me. Thanks.
mainline-1000: [ ++ c print join c " mainline-1000" ++ c print join c " get-input-1100" do get-input-1100 ++ c print join c " calc-value-1200" do calc-value-1200 ] c: 0 get-input-1100: [print "Doing Code Block 1"] calc-value-1200: [print "Doing Code Block 2"] loop 10 [do mainline-1000]
If you put the debug code in each action block, you see a pattern (counter variable is incremented, action block label is printed, and some code is executed)): R E B O L [] mainline-1000: [ ++ c print join c " mainline-1000" do get-input-1100 do calc-value-1200 ] c: 0 get-input-1100: [ ++ c print join c " get-input-1100" ; do your stuff here ] calc-value-1200: [ ++ c print join c " calc-value-1200" ; do your stuff here ] loop 10 [do mainline-1000] halt
Because of that pattern, you can reduce the debug process above into a repeatable function, so that you don't need to include the debug code in any of your action blocks. 'Do is native, so I just created a new function called 'Doo: doo: func [x] [ ++ c print rejoin [c " " x] do to-word x ] mainline-1000: [ doo "get-input-1100" doo "calc-value-1200" ] c: 0 get-input-1100: [] calc-value-1200: [] loop 10 [doo "mainline-1000"]
Notice that the action block names are passed to the doo function as string arguments (x), so that they can be printed. "do to-word x" does the actual word referred to by that string (which itself is a label for an action block).
Excellent, I had hoped to somehow redefine the DO, but I understand what you are doing with DOO -- But wait, could I do this: native-do: :do ; takes on the native do do: func [x] [ ++ c print rejoin [c " " x] native-do to-word x ] Would this work for all "do" statements -- at least until I restore it back by do: :native-do Would that work??? -- What do you think and could there be other issues?
Yep, you can do that, but I wouldn't - I expect that there might be other mezzanine functions that potentially use 'do.
"1000-mainline?" I would almost be willing to place money on you being a former COBOL programmer. Instead of creating a new function called "doo," why not call it "perform?" I like your idea, by the way. Instead of printing your trace information, you could write it to a "circular" file where you keep only the last hundred-or-so entries, so if you program crashed you could see where it was and how it got there. I don't really know how all this works, but I wonder if the "get" function could help. What I am thinking of is a function (called PERFORM) that takes as a parameter a word that has as a value your code. In other words, you would code PERFORM '1000-mainline Note the apostrophe in front of the word so that it is not evaluated. Then, what the PERFORM function does is to print its parameter (the word 1000-mainline) and the "get" the value of 1000-mainline (your code) and "do" that code. It would be something like this: Note that I have not tested this. I can't do too much fun stuff at work these days. TRACE-COUNTER: 0 PERFORM: func [paragraph-name] [ TRACE-COUNTER: TRACE-COUNTER + 1 print rejoin [ TRACE-COUNTER ": " paragraph-name ] do get 'paragraph-name ]

Reply