Zbex debugging instructions
Special variables and labels
Conditional compiles and other features
The Zbex language provides several tools for debugging programs. When you write a program, there are three levels of success that you need to achieve. The first is to have your program compile. This means following the proper syntax of the language. Zbex includes an extensive set of compiler time error messages which not only identify errors in your code but also try to explain what you need to do to fix the code. The second level of success is to have your program run. The most common run time error in Zbex programs is a subscript error. The Zbex interpreter knows the size of all of your strings and arrays, and if you try to address memory outside of this range, the interpreter will stop the execution of your program and tell you the line number in your program where the error occurred and what the offending subscript values were. The third level of success is to get your program to do what you want it to do. For large programs, this is the most difficult and most time consuming level to achieve. Most of Zbex's debugging tools are designed to help you solve this problem.
dputc and dputp
These instructions are identical to putc and putp except that the line number where they sit in your program is also displayed (printed out). This way, you can check on the value of certain variables at different points in your program and always be able to tell where those points are. Example:
Program --------------------- 1 int i 2 3 loop for i = 1 to 3 4 i = i + 6 5 repeat 6 dputc i = ~i 7 run
Execution ------------------------------------- ** S=6, P=20, L=233, M=410 ** T0006 i = 7 Ready for program
The behavior of Zbex in certain situations is determined by a set of flags. The state of these flags can be changed using the setflag instruction. This instruction has two formats.
Format 1: setflag x[xxxxxxxxxxxxxxxx] (x = 0 or 1) Format 2: setflag x,y (x = bit number, y = 0 or 1)
In format 1, from 1 to 12 bits are specified in the second field of the instruction. Format 1 can be used to set the state of all twelve flags at one time. In format 2, you supply a bit number and its new setting. With format 2, you can set the state on only one flag at a time.
The twelve flags control the following aspects of Zbex operation. The default setting of all flags is 0 (no action).
|Bit Num||Zbex behavior when bit is 1|
|1||Give warning on overflow on integer multiply|
|2||Give warning on overflow on conversion of ASCII string to integer|
|3||Give warning on attempt to divide by zero|
|4||Give warning on overflow on floating point number to integer conversion|
|5||I/O flag -- convert out-of-bounds fixed decimal floating point representation to floating decimal floating point representation|
|6||Give warning on attempt to read/write partially outside of bounds of a file (read/writing totally outside is cause for termination)|
|7||Give warning when LHS of string statement with subscripts has a different length than the RHS|
|8||Give warning when the argument of a real function is outside the proper domain|
|9||Give warning when string subscripts are out-of-bounds in relational statements|
|10||Suppress warnings for writing more than 100,000 records or more than 6 MB in a file|
|11||Give warning when the initial value of loop counter is set outside the loop limits|
|12||When open fails, don't prompt for a file name. Instead, set the err variable to a positive number. 0 = normal.|
trace and untrace
These commands take a single variable as an argument. The trace command is actually a command to the compiler. Whenever an instruction is compiled that could possibly change the value of the given variable, a putc type instruction is also compiled into the code, which will display the value of the variable at run time. The untrace command will turn trace off for the given variable. The purpose of the trace command is to allow you to see where a particular variable is being modified, and to track its value during the execution of a program. Example:
Program --------------------- int i trace i loop for i = 1 to 5 i = i + 1 repeat untrace i i = 10 run
Execution ------------------------------------- ** S=8, P=18, L=233, M=410 ** Trace activated at line number 6 Integer counter: i = 1 Final value = 5 Trace activated at line number 8 Integer variable: i = 2 Trace activated at line number 6 Integer counter: i = 3 Final value = 5 Trace activated at line number 8 Integer variable: i = 4 Trace activated at line number 6 Integer counter: i = 5 Final value = 5 Trace activated at line number 8 Integer variable: i = 6 Ready for program
When all else fails, there is always the examine command. examine puts your program into step mode. From the point where the examine occurs, you can step through your program by pressing the F9 key. While in examine mode, you can examine the value of any string, bit-string, integer or real variable; and you can change the value of any such variable. You can also exit examine mode and return to normal operation of the program. Examine statements can be put anywhere in your program, and you can put in as many as you like. examine is a tedious way to find program bugs, but for some types of problems, it has proven to be the fastest way to find the source of trouble.
When you enter examine mode, you are presented with the following menu:
*** Entering examine mode at source line number <#> *** /x, = examine value of variable /h, = examine value of variable in hex format /c, = change value of variable F9 = step one line in program /e = exit examine mode; continue with program = [<procedure name>]<variable name>(<subscripts>) (a dot may be substituted for [<current procedure>])
It is important understand how to specify a variable. If you want to know the value of the integer variable i, for example, you need to specify whether this is a global variable (a variable in the main program), or a variable in a procudure. If you precede the variable with a dot, it means that you are specifying a local variable (within the current procudure). Example:
Program --------------------- int i loop for i = 1 to 1 perform pro1 repeat stop procedure pro1 int i i = 20 examine perform pro2 return procedure pro2 int i i = 10000 return run
Execution ------------------------------------- ** S=16, P=29, L=237, M=410 ** *** Entering examine mode at source line number 11 *** /x, = examine value of variable /h, = examine value of variable in hex format /c, = change value of variable F9 = step one line in program /e = exit examine mode; continue with program = [<procedure name>]<variable name>(<subscripts>) (a dot may be substituted for [<current procedure>]) /x,i Integer variable i = 1 /x,.i Integer variable .i = 20 /x,[pro2]i Integer variable [pro2]i = 0 /e Ready for program
Examine mode will work only when your source program comes from a file, not from a window. This is because the interpreter needs to have runtime access to the source code in order to display the lines of your program at run time. When in examine mode, you will see 15 lines of your program at a time, with a highlight on the fourth line (i.e., you can see three lines back of where you currently are and eleven lines ahead of where you currently are). If you change to another window while in examine mode, when you change back, the program lines are no longer there. Simply press the Enter key, and they will return.
Special variables and labels
Conditional compiles and other features