{Begin Chapter Masterscope}
{Title Masterscope}
{Text

{Begin Note}
Edited extensively 6/14/83 by jds.
Edited Wed, 20 Jul 83 10:39 PDT by Sannella
{End Note}

{Tag MasterScope}


{note Masterscope was designed and implemented by L. M. Masinter.}


Masterscope is an interactive program for analyzing and cross referencing user programs.  It contains facilities for analyzing user functions to determine what other functions are called, how and where variables are bound, set, or referenced, as well as which functions use particular record declarations.  Masterscope is able to analyze definitions directly from a file as well as in-core definitions.


Masterscope maintains a database of the results of the analyses it performs.  Via a simple command language, the user may interrogate the database, call the editor on those expressions in functions that were analyzed which use variables or functions in a particular way, or display the tree structure of function calls among any set of functions.


Masterscope is interfaced with the editor and file package so that when a function is edited or a new definition loaded in, Masterscope knows that it must re-analyze that function.



The following sample session illustrates some of these facilities.


{Begin LispCode}
←. ANALYZE FUNCTIONS ON RECORD                    {it [1]}
...............................                   {it [2]}
NIL
←. WHO CALLS RECFIELDLOOK                         {it [3]}
(RECFIELDLOOK ACCESSDEF ACCESSDEF2 EDITREC)
←. EDIT WHERE ANY CALL RECFIELDLOOK               {it [4]}
RECFIELDLOOK :
(RECFIELDLOOK (CDR Y) FIELD)
tty:
*OK  
ACCESSDEF :
(RECFIELDLOOK DECLST FIELD VAR1)
*OK  
(RECFIELDLOOK USERRECLST FIELD)
*N VAR1
*OK
ACCESSDEF2 :
(RECFIELDLOOK (RECORD.SUBDECS TRAN) FIELD)
tty:
(RECFIELDLOOK (RECORD.SUBDECS TRAN) FIELD)
*N (CAR TAIL]
*OK  
EDITREC :
(RECFIELDLOOK USERRECLST (CAR EDITRECX))
*OK 
NIL
←. WHO CALLS ERROR                                {it [5]}
..
(EDITREC)
←. SHOW PATHS TO RECFIELDLOOK FROM ACCESSDEF      {it [6]}
(inverted tree)

1. RECFIELDLOOK RECFIELDLOOK
2.             ACCESSDEF
3.             ACCESSDEF2 ACCESSDEF2
4.                        ACCESSDEF
5.                        RECORDCHAIN ACCESSDEF
NIL
←. WHO CALLS WHO IN /FNS                          {it [7]}
RECORDSTATEMENT --  /RPLNODE
RECORDECL1 --       /NCONC, /RPLACD, /RPLNODE
RECREDECLARE1 --    /PUTHASH
UNCLISPTRAN --      /PUTHASH, /RPLNODE2
RECORDWORD --       /RPLACA
RECORD1 --          /RPLACA, /SETTOPVAL
EDITREC --          /SETTOPVAL
{End LispCode}



{it [1]}   The user directs that the functions on file {lisp RECORD} be analyzed.  The leading period and space specify that this line is a Masterscope command.{foot
The user may also call Masterscope directly by typing {lisp (MASTERSCOPE)}.  Masterscope prints a greeting and prompts with "{lisp ←. }".  Within the top-level executive of Masterscope, the user may issue Masterscope commands, programmer's assistant commands, (e.g., {pacom REDO}, {pacom FIX}), or run programs.  The user can exit from the Masterscope executive by typing {lisp OK}.{index OK (Masterscope Command)}  The function {lisp .}{index . (in Masterscope)} is defined as a nlambda nospread function which interprets its argument as a Masterscope command, executes the command and returns.
}{comment endfootnote}


{it [2]}   Masterscope prints a {lisp .}{index . (printed by Masterscope)} whenever it (re)analyzes a function, to let the user know what it is happening.{foot
The feedback when Masterscope analyzes a function is controlled by the flag {var MSPRINTFLG}{index MSPRINTFLG Var}: if {var MSPRINTFLG} is the atom "{lisp .}", Masterscope will print out a period.  (If an error in the function is detected, "{lisp ?}" is printed instead.)  If {var MSPRINTFLG} is a number {arg N}, Masterscope will print the name of the function it is analyzing every {arg N}th function.  If {var MSPRINTFLG} is {lisp NIL}, Masterscope won't print anything.  Initial setting is "{lisp .}".  Note that the function name is printed when Masterscope starts analyzing, and the comma is printed when it finishes.
}{comment endfootnote}


{it [3]}   The user asks which functions call {lisp RECFIELDLOOK}.  Masterscope responds with the list.


{it [4]}   The user asks to edit the expressions where the function {lisp RECFIELDLOOK} is called.  Masterscope calls {fn EDITF} on the functions it had analyzed that call {lisp RECFIELDLOOK}, directing the editor to the appropriate expressions.  The user then edits some of those expressions.{foot
In this example, the teletype editor is used.  In Interlisp-D, if Dedit is enabled as the primary editor, it would be called to edit the appropriate functions (see {PageRef Tag Dedit}).
}{comment endfootnote}



{it [5]}   Next the user asks which functions call {fn ERROR}.  Since some of the functions in the database have been changed, Masterscope re-analyzes the changed definitions (and prints out {lisp .}'s for each function it analyzes).  Masterscope responds that {fn EDITREC} is the only analyzed function that calls {fn ERROR}.


{it [6]}   The user asks to see a map of the ways in which {lisp RECFIELDLOOK} is called from {lisp ACCESSDEF}.
A tree structure of the calls is displayed.


{it [7]}   The user then asks to see which functions call which functions in the list {lisp /FNS}.  Masterscope responds with a structured printout of these relations.





{Begin note}
Masterscope "idioms" from talk with lmm:

. WHO USING X FREE IS NOT ON PATH FROM A

. WHO ON MYFILE CALLS ANY NOT @ GETD

. WHO ON MYFILE IS NOT ON PATH FROM ANY IN TOPFNS

. EDIT WHERE ANY ON MYFILE CALLS X - (IF (EQ (## 1) 'X)(GETD)(TTY:]
{End note}




Below is a summary of the Masterscope commands, similar to what would be printed out by the {lisp HELP} command ({PageRef (Masterscope Command) HELP}).  Optional elements are shown in brackets {lisp []}; alternatives are shown in braces {bracket} separated with vertical bars {lisp |} or are listed on separate lines; words in angle brackets {lisp <>} are "meta-objects"; other lower-case words are "noise words" and may be omitted.

{Tag MasterscopeSummary}


{Begin LispCode}
*------------------------------------------------------------------*
 a <command> is:
 
   [RE]ANALYZE <functions>
   ERASE <functions>
   show PATHS <pathoptions>
   <set> {bracket <relation> | IS | ARE} <set>
   EDIT where <functions> [<relation> <set>] [ - <edit commands>]
   SHOW where <functions> <relation> <set>
   CHECK <files>
   FOR <variable> <set> <iterative statement tail>
-------------------------------------------------------------------
 a <set> is (at least one of):
 a determiner   + a type            + a specification
 
  THE           FUNCTIONS           [']{bracket atom | list}
  ANY           VARIABLES           @ <predicate>
  WHICH         PROPERTY NAMES      IN <expression>
  WHO           RECORDS             <relation>ING <set>
                FIELDS              <relation>ED {bracket BY | IN} <set>
                FILES               THAT <relation> <set>
                I.S.OPRS            LIKE <edit-pattern>
                                    ON <files>
                                    ON PATH <pathoptions>
                FIELDS OF <records>
                <blockword> {bracket ON <files> | OF <functions>}
  <functions>, <files>, etc. are <set>s whose type is implied.
-------------------------------------------------------------------
 a <relation> is a verb and optional modifier:
  verbs:           modifiers (anywhere after the verb):
   CALL            {bracket SOMEHOW | FOR EFFECT | FOR VALUE |
                                      DIRECTLY | INDIRECTLY}
   USE             AS a {bracket RECORD | PROPERTY | record FIELD} name
   USE             AS a CLISP word
   USE             {bracket FREELY | LOCALLY}
   SET             {bracket FREELY | LOCALLY}
   SMASH           {bracket FREELY | LOCALLY}
   TEST            {bracket FREELY | LOCALLY}
   REFERENCE       {bracket FREELY | LOCALLY}
   DECLARE         AS a {bracket LOCALVAR | SPECVAR}
   BIND
   FETCH
   REPLACE      *--------------------------------------------------
   CREATE       | <blockword>:  ENTRIES, GLOBALVARS, FREEVARS,
   CONTAIN      |  SPECVARS, LOCALFREEVARS, BLKFNS or BLOCKFNS
-------------------------------------------------------------------
  <pathoptions>:          | abbreviations & synonyms:
                          |
    FROM <functions>      | FNS = FUNCTIONS  PROPS = PROPERTIES
    TO <functions>        | VARS = VARIABLES
    AVOIDING <functions>  | (& singular FN, VARIABLE, etc)
    NOTRACE <functions>   | FREE = FREELY    LOCAL = LOCALLY
    SEPARATE <functions>  | AMONG = AVOIDING NOT
    LINELENGTH <number>   |
-------------------------------------------------------------------
   <sets> may be joined by AND or OR or preceded by NOT.
   Any command can be followed by OUTPUT <filename>.
*------------------------------------------------------------------*
{End LispCode}




{Include MSLang}



{Include MSorg}



{Begin Note}
Date: 27 Feb 1981 14:01 PST
From: KAPLAN at PARC-MAXC
Subject: CONSTANTS

...

Masterscope is now also aware of constants, in the sense that if the current value of a variable is changed and that value is a constant value according to COMPILE.TIME.CONSTANTS, then the need-unsave warning will be given for all functions that use that variable freely.
{End Note}


}{End Chapter Masterscope}