Page Numbers: Yes First Page: 20 X: 527 Y: 10.5"
Margins: Binding: 13
Odd Heading:
Debugger Interpreter
Even Heading: Not-on-first-page
Debugger Interpreter
Section 5: Debugger Interpreter
The Mesa debugger contains an interpreter that handles a subset of the Mesa language; it is useful for common operations such as assignments, dereferencing, procedure calls, indexing, field access, addressing, displaying variables (also TYPEs), and simple type conversion. It is a powerful extension to the debugger command language, as it allows you to more closely specify variables while debugging, thus giving you more complete information with fewer keystrokes.
A specific subset of the Mesa language is acceptable to the interpreter (see below for details on the grammar). Several specialized notations (abbreviations) have been introduced in the interpreter grammar; these are valid only for debugging purposes and are not part of the Mesa language. The interpreter operates much like the compiler; strict target typing is performed on assignments and procedure calls.
Statement Syntax
Typing space (SP) to the command processor enables interpreting mode; the limited command processors of Display Stack and Display Process also permit a space. At this point the debugger is ready to interpret any expression that is valid in the (debugger) grammar.
Multiple statements are separated by semicolons; the last statement on a line should be followed by a carriage return (CR). If the statement is a simple expression (not an assignment), the result is displayed after evaluation.
For example, to perform an assignment and print the result in one command, you would type:
foo ← exp; foo.
Loopholes
A more concise LOOPHOLE notation has been introduced to make it easy to display arbitrary data in any format. The character "%" may be used instead of LOOPHOLE[exp, type], with the expression on the left of the %, and the type on the right. However, % is not a valid LeftSide; all type expressions must be enclosed in parentheses.
The following expressions are equivalent to the interpreter:
foo % (short red Foo) and LOOPHOLE[foo, short red Foo]
(p % (
LONG POINTER TO Object))↑ and LOOPHOLE[p, LONG POINTER TO Object]↑
The first pair will loophole the type of the variable foo to be a short red Foo and display its value. The second pair will loophole p to be a LONG POINTER TO Object and dereference it.
A number may be loopholed into PROCEDURE, SIGNAL, or an ERROR. If it is valid, the debugger will display the procedure (or signal’s) name, module and global frame. If a signal/error is the same as the uncaught signal that trapped to the debugger, the debugger will also display the parameters.
Subscripting
There are two types of interval notation acceptable to the interpreter; the closed, open, and half open interval notation accepted by the compiler and a shorthand version that uses !. The notation [a . . b] means start at index a and end at index b. The notation [a ! b] means start at index a and end at index (a+b̄1).
The following expressions all display the octal contents of memory locations 4 through 7:
MEMORY[4 . . 7]
MEMORY[4 . . 8)
MEMORY(3 . . 7]
MEMORY(3 . . 8)
MEMORY[4 ! 4]
Note that the interval notation is only valid for display purposes, and therefore is not allowed as a LeftSide or inside other expressions.
Explicit Qualification
To improve the performance of the interpreter, the $ notation has been introduced to distinguish between qualification in the current context and explicit qualification. The character $ indicates that the name on the left is a module name, in which to look up the identifier or TYPE on the right. If a module cannot be found, it uses the name as a file (usually a definitions file). A valid octal frame address is also acceptable as the left argument of $.
For example, FSP$TheHeap means look in the module FSP to find the value of the variable TheHeap. In dealing with variant records, be sure to specify the variant part of the record before the record name itself (ie., foo % (short red FooDefs$Foo), not foo % (FooDefs$short red Foo)).
Type Expressions
The notation "@type" may be used as shorthand to construct a POINTER TO type. This notation is used for constructing types in LOOPHOLEs (ie., @foo will give you the type POINTER TO foo). There is no shorthand to construct LONG POINTER TO type.
Radix conversion
The notation "expression?" will print the value of the expression in several formats, including octal and decimal. Radix conversion between octal and decimal can be forced using the loophole construct; for example, exp%(CARDINAL) will force octal output and exp%(INTEGER) will force decimal.
Arithmetic
Target typing is applied to arithmetic expressions. In complex expressions atoms which change the target type must occur first. For example:
(POINTER + offset)↑ -- correct(offset + POINTER)↑-- error message
LONG[400B] * 400B-- 200000B400B * LONG[400B]-- overflow
Sample Expressions
Here are some sample expressions which combine several of the rules into useful combinations:
If you were interested in seeing which procedure is associated with the third keyword of the menu belonging to a particular window called myWindow, you would type:
myWindow.menu.array[3].proc
which might produce the following output:
CreateWindow (PROCEDURE in WEWindows, G: 120134B).
The basic arithmetic operations are provided by the interpreter (with the same precedence rules as followed by the Mesa compiler).
3+4 MOD 2 ; (3+4) MOD 2
would produce the following output:
3
1
.
A typical sequence of expressions one might use to initialize a record containing a pointer to an array of Foos and display some of them would be:
rec.array ← FSP$AllocateHeapNode[n*SIZE[FooDefs$Foo]];
InitArray[rec.array]; rec.array[first..last]
.
The following command would display rec in octal:
Octal Read: @rec, n: SIZE[Rec].
Grammar
A copy of the Debug Interpreter grammar is in an appendix at the end of this document.