perm filename BAIL.DOC[DOC,AIL]4 blob sn#145764 filedate 1975-02-17 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00006 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002				BAIL -- A DEBUGGER for SAIL
C00004 00003				I. Compile-time action
C00010 00004				II. Run-time action
C00019 00005				III.  Resources Used
C00021 00006				IV. Current Status
C00023 ENDMK
C⊗;
			BAIL -- A DEBUGGER for SAIL



			John F. Reiser
			Computer Science Department
			Stanford University

			February 17, 1975








	BAIL is a debugging aid for SAIL programs.  At compile time, BAIL
generates a file which contains symbol table, program counter, and text
file information.  At execution time BAIL uses this information to interpret
debugging requests.  In many respects BAIL is like DDT or RAID, except that
BAIL is oriented towards SAIL and knows about SAIL data types, primitive
operations, procedure implementation, and stack structure.  In addition, 
BAIL can display the text from the source or listing file which corresponds
to the program counter at a given point in the program.











		Contents

	    I.	Compile-time action
	   II.	Run-time action	       
	  III.	Use of resources
	   IV.	Current status
			I. Compile-time action

	The principal result of activating BAIL at compile-time is the
generation of a file of information about the source program for use by 
the run-time interpreter.  This file has the same name as the .REL file
produced by the compilation, except that the extension is .SM1.  If 
requested, BAIL will also generate some additional code for SIMPLE
procedures to make them more palatable to the run-time interpreter.

	The action of BAIL at compile time is governed by the value of 
the /B switch passed to the compiler.  If the value of this switch is 
zero (the default if no value is specified) then BAIL is completely
inactive.  Otherwise, the low-order bits determine the actions
which BAIL performs.  [The value of the /B switch is interpreted as octal.]

	bit	action

	 1	If this bit is on, then the .SM1 file will contain the 
		program counter to source/listing text directory.

	 2	If this bit is on, then the .SM1 file will contain symbol
		information for all SAIL symbols encountered in the source.
		If this bit is off, then information is kept only for 
		procedures, parameters, blocks, and internals; i.e., non-
		internal local variables are not recorded.

	 4	If this bit is on, then SIMPLE procedures will get 
		procedure descriptors, and one additional instruction
		(a JFCL 0, which is the fastest machine no-op instruction)
		is inserted at the beginning of SIMPLE procedures.  Except
		for these two changes, all properties of SIMPLE procedures
		remain the same as before.  The procedure descriptor is
		necessary if the procedure is to be called interpretively
		or if the procedure is to be TRACEd.

	'10	If this bit is on, then BAIL will not be automatically
		loaded and initialized, although all other actions
		requested are performed.  This is primarily intended to
		make it easier to debug new versions of BAIL without
		interfering with SYS:BAIL.REL.

	'20	If this bit is on, then a request to load SYS:BAIPDn.REL 
		is generated.  This file contains procedure descriptors
		for most of the SAIL predeclared runtime routines, making
		it possible to call them from BAIL.  The procedure 
		descriptors and their symbols occupy about 6K.

The B switch must occur on the binary term, not the listing or source term.
Thus:
	.R SAIL			or	.COM PROG(27B,)
	*PROG/27B←PROG


	The program counter to source/listing index is kept in terms of 
coordinates.  The coordinate counter is zeroed at the beginning of the
compilation and is incremented by one for each BEGIN, ELSE, and semicolon
seen by the parser, provided at least one word of code has been compiled
since the previous coordinate was defined.  Note that COMMENTs are seen
only by the scanner, not the parser, and that DEFINEs and many declarations
merely define symbols and do not cause instructions to be generated.  For
each coordinate the directory contains the coordinate number, the value of 
the program counter, and a file pointer to the appropriate place.  The 
appropriate place is the source file unless a listing file is being
produced and the CREF switch is off, in which case it is the listing file.
[The listing file produced for CREF is nearly unreadable.]  On a non-CREF
listing, the program counter is replaced by the coordinate number if bit 1
of the /B switch is on.

	The symbol table information consists of the block structure and
the name, access information, and type for each symbol.

	If a BEGIN-END pair has declarations (i.e., is a true block and not
just a compound statement) but does not have a name, then BAIL will invent
one.  The name is of the form  Bnnnn  where nnnn is the decimal value of
the current coordinate.
			II. Run-time action

	The BAIL run-time interpreter is itself a SAIL program which
resides on the system disk area.  It is loaded automatically whenever
any .REL file was compiled with the /B switch.  The necessary initialization
of BAIL is also taken care of automatically.

	The initialization generates a .BAI file of information collected
from the .SM1 files produced by separate compilations (if any).  The .SM1
files correspond to .REL files, and the .BAI file corresponds to the .DMP
or .SAV file.  Like RPG or CCL, BAIL will try to bypass much of the
initialization and use an existing .BAI file if appropriate.  During
initialization BAIL displays the names of the .SM1 files it is processing.
For each .SM1 file which contains program counter/text index information,
BAIL displays the names of the text files and determines whether the text
files are accessable.

	The interpreter is activated by explicit call, previously inserted
breakpoints, or the SAIL error handler.  For an explicit call, say
EXTERNAL PROCEDURE BAIL; ... BAIL;.  From the error handler, respond B. 
Breakpoints will be described later in this section.

	Debugging Requests.  When BAIL is entered it displays the text of
the current statement (if available), its block structure, and a portion
of the dynamic scope.  BAIL then prints the debugging recursion level
followed by a colon, and awaits a debugging request.  A debugging request
is essentially a SAIL expression followed by a semicolon, except that
IF-THEN-ELSE and CASE expressions are not allowed and certain natural
extensions to the expression syntax are allowed.  The expression is
evaluated as if it had appeared in the source file at the place indicated.
The resulting value is then displayed.  For example, the request
VAR1,3+VAR2;  will print the values of VAR1 and 3+VAR2.  The expression
!!GO  (or  __GO , since ! and _ are equivalent characters to both the
compiler and the debugger) causes an immediate exit from the current
instantiation of BAIL.

	Breakpoints.  Breakpoints are handled by evaluating a call to one
of four procedures defined inside BAIL.

	procedure		description

TRACE("proc name")		Prints the procedure name at each entry and
				exit, the parameters at entry, and the
				value RETURNed (if any) at exit.

UNTRACE("proc name")		Discontinues tracing of the procedure.

BREAK("location","condition",	Plants a breakpoint (a call to BAIL) at
 "action",mpc)			location.  The action at a breakpoint is
				IF EVAL(condition) AND (mpc←mpc-1) LEQ 0
				THEN EVAL(action); EVAL(TTY:);

UNBREAK("location")		Remove a breakpoint.


	Specification of procedure and location names:  Since the procedure
or location may not be in the scope of declaration at the time a breakpoint
is planted, the syntax of a location is
	location := label | procedure | blockname delim location
where delim is any non-identifier character (e.g., altmode, period,
,virgule,space,...).  The last blockname should be the block in which the
label or procedure is delared.  The complete search algorithm is:  Search
the blocks in memory-location order of BEGINs until a block is found which
has the first blockname as its name.  If there is a second blockname,
continue the search of the blocks in memory-location order, beginning with
the block which immediately follows the block which matched the first
blockname.  Continue until all blocknames have been matched.  This yields
some block in the program.  Construct the block structure ancestry of that
block.  The label or procedure must then be declared within the scope of one
of the blocks of that ancestry.

	Examining variables not in the current lexical scope:  The procedure
SETLEX(n) changes the lexical scope to the scope of the n-th entry in the
dynamic scope list.  SETLEX(0) is the scope of the breakpoint; SETLEX(1) is
the scope of the most recent procedure call in the dynamic scope; etc.

	BAIL and DDT: If BAIL is initialized in a core image which does not
have DDT or RAID, then things will be set up so that the monitor command
DDT gets you into BAIL in the right way.  That is, BAIL will be your DDT.
To enter BAIL from DDT, use

	PUSHI P,<address which BAIL should take as the program counter>$X
	JRST BAIL$X

For example, if .JBOPC contains the program counter,

	PUSH P,.JBOPC$X
	JRST BAIL$X


WARNING: Since BAIL is itself a SAIL procedure, entering BAIL from the 
error handler or DDT after a push-down overflow or a string garbage
collection error will get you into trouble.


	BAIL and SIMPLE procedures:  SIMPLE procedures cause headaches for 
BAIL because they do not keep a display pointer.  [Indeed, the compiler
gets lost in the following example, and does not complain:

	BEGIN "LOST"
	PROCEDURE A(INTEGER I); BEGIN "A"
		SIMPLE PROCEDURE B; OUTSTR("THE VALUE OF I IS " & CVS(I));
		PROCEDURE C(INTEGER J); B;
	C(2);
	END "A";

	A(1);
	END "LOST";							]

BAIL tries valiantly to do the right thing, but occasionally it also gets
lost.  BAIL will try to warn you if it can.  In general, looking at value
string parameters of SIMPLE procedures does not work.
			III.  Resources Used

A.  Compile-time

    1.	One channel.  This means that REQUIREd source files may only be
	nested to a depth of about 9.

    2.	Memory.  Upto 11*(maximum lexical nesting depth) more words of
	memory may be required compared with previous compilations.

    3.	CPU time.  Approximately 0.3 seconds per page of dense text.

B.  Run-time

    1.	Channels.  Three during initialization, two thereafter.  Channels
	are obtained via GETCHAN.

    2.	BAIL uses 8 of the privileged breaktables, obtaining them by GETBREAK.

    3.	REQUIRE 64 STRING!PDL.  Necessary if the debugging recursion
	level will exceed 3 or 4.

    4.	Memory.  (9K +((# of coordinates+127) DIV 128) + (2*# of blocks) +
	(5*# of symbols)) words.

    5.	CPU time.

	a.  Initialization.  Typically 4 seconds for a 30 page program.

	b.  Debugging requests.  0.07 seconds per simple request.
	    DDT response time.

C.  Disk space

    1.  The .SM1 file for a /7B compilation is typically one-fourth the
	size of	the corresponding .REL file.

    2.	The .BAI file for a group of /7B compilations is typically
	one-third the total size of the corresponding .REL files.
			IV. Current Status


Top priority

 1. The state of the world is determined by the values of the accumulators
    and the value of the SAIL varaible !SKIP!.


Medium priority

 1. The LEAP operations union, intersection, and membership are not
    implemented.

 2. Records and references are not recognized.

 3. Stepping by statement and ability to place breakpoints at arbitrary
    coordinates.

 4. PROPS is read-only.


As time permits

 1. Functional arguments are not handled correctly.

 2. The run-time interpreter recognizes only the first 15 characters of
    identifier names; the rest are discarded without comment.  The
    characters which are legal in identifiers are

	ABCDEFGHIJKLMNOPQRSTUVWXYZ
	abcdefghijklmnopqrstuvwxyz
	0123456789!_αβπλ∂⊂⊃∀∃→~#$\|

    Notable for its absence: period.

 3. Contexts are not recognized.

 4. The run-time interpreter will not recognize macros.