-- PrintTV.mesa
-- Russ Atkinson, September 1, 1982 8:00 pm
DIRECTORY
Rope USING [ROPE],
RTBasic USING [nullType, TV, Type],
WorldVM USING [Address, World];
PrintTV: CEDAR DEFINITIONS
= BEGIN OPEN Rope, RTBasic, WorldVM;
PutProc: TYPE = PROC [data: REF, c: CHAR];
PutClosure: TYPE = RECORD [proc: PutProc, data: REF ← NIL];
NullPutClosure: PutClosure = [NIL, NIL];
-- note: the only error that will always terminate printing is ABORTED
Print: PROC
[tv: TV, put: PutClosure, depth: INT ← 4, width: INT ← 32, verbose: BOOL ← FALSE];
-- print the TV
-- if verbose, then print extra information as available
PrintType: PROC
[type: Type, put: PutClosure, depth: INT ← 4, width: INT ← 32, verbose: BOOL ← FALSE];
-- print the type
-- if verbose, then print extra information as available
PrintArguments: PROC
[tv: TV, put: PutClosure,
depth: INT ← 4, width: INT ← 32, breakBetweenItems: BOOL ← FALSE];
-- print the arguments to the given local frame
-- the depth and width args apply to the individual printing
-- an error msg is printed if this is not a local frame
-- breakBetweenItems causes a line break between arguments
PrintResults: PROC
[tv: TV, put: PutClosure,
depth: INT ← 4, width: INT ← 32, breakBetweenItems: BOOL ← FALSE];
-- print the results for the given local frame
-- the depth and width args apply to the individual printing
-- an error msg is printed if this is not a local frame
-- breakBetweenItems causes a line break between arguments
PrintVariables: PROC
[tv: TV, put: PutClosure,
depth: INT ← 4, width: INT ← 32,
all, breakBetweenItems: BOOL ← TRUE];
-- print the results for the given local frame
-- the depth and width args apply to the individual printing
-- an error msg is printed if this is not a local frame
-- if all = TRUE, then all variables in the frame are printed
-- breakBetweenItems causes a line break between arguments
PrintRef: PROC
[ref: REF READONLY ANY, put: PutClosure,
depth: INT ← 4, width: INT ← 32];
-- print the given ref in the local world
PrintPointer: UNSAFE PROC
[world: World, addr: Address, type: Type,
put: PutClosure, depth: INT ← 4, width: INT ← 32];
-- print the given long pointer as a pointer in the given world to the given type
Intercept: PROC
[type: Type, proc: Interceptor ← NIL, data: REF ← NIL, canHandleRemote: BOOL ← FALSE];
-- intercepts printing for the given type
-- proc will be called when PrintTV.Print tries to print the given type
-- (proc = NIL removes the print proc for the type)
-- data will be supplied when proc is called (faking a closure)
-- type = 0 => ERROR InvalidInterceptor
-- IF canHandleRemote THEN interceptor will be called for remote TVs as well as local
Interceptor: TYPE = PROC
[tv: TV, data: REF, put: PutClosure, depth: NAT, width: NAT]
RETURNS [useOld: BOOL ← FALSE];
-- the type of user's print proc
-- tv: TV is the thing to print
-- data: REF is the user's data given to Intercept
-- put: ... is the output routine for characters
-- depth and width are passed through from PrintTV.Print
GetInterceptor: PROC
[type: Type, deReferenced: BOOL ← FALSE]
RETURNS [proc: Interceptor, data: REF, enabled: BOOL, canHandleRemote: BOOL];
-- proc # NIL => print proc provided
-- enabled => print proc is enabled
-- deReferenced => what you really mean is REF type.
SetEnabled: PROC [type: Type, deReferenced: BOOL, enabled: BOOL ← TRUE];
-- sets the enabled flag for the type
-- no effect if no interceptor for that type
NextInterceptor: PROC
[after: Type ← nullType]
RETURNS [type:Type, proc: Interceptor, data: REF, enabled: BOOL];
-- provides a stateless enumerator for print interceptors
InvalidInterceptor: ERROR;
-- error raised by Intercept if bad arguments are given
Mother: PROC [inner: PROC] RETURNS [ROPE]
-- mother catches signals by inner and returns a descriptive message
-- ABORTED is resignaled, NIL is returned if no errors occurred
-- this proc is similar to BBSafety.Mother
END.