One of the main uses of a debugger is examining the values of variables. In some Lisp environments it is easy to provide access to variables by starting a new read-eval-print loop. The Scheme report does not include eval, however, so a different strategy must be used. In Psd this problem is solved by inserting an access procedure each time new variable bindings are made. This procedure performs the mapping between symbols and actual program variables. Figure 2 shows a let form and the code that Psd generates for it.
The procedure psd-val is passed to the debugger command loop psd-debug. Using it the command loop gets access to variables in the current lexical environment of the debugged program. The scope rules come ``for free'', because the name psd-val in the body of psd-val refers to the lexical environment surrounding the let form.
Assignments to local variables are made using the same mechanism. A setter procedure psd-set! is inserted each time local variables are defined, and it is also passed to psd-debug.
Access to global variables is provided using the same idea. Every instrumented Scheme file includes definitions for procedures similar to psd-val and psd-set!. When the file is loaded, the procedures are added to a global access procedure list. The global definitions of psd-val and psd-set! call the access procedures one by one until either the access succeeds or there are no more access procedures.
The Psd runtime support includes access to all the essential procedures (the report distinguishes between essential procedures that a conforming implementation must provide, and non-essential procedures that are not required) described in the Revised Report. The debugger command loop includes a simple evaluator that can evaluate calls of the procedures that are visible to it. The lack of a bound? predicate or some other portable way of finding out whether an identifier is bound prevents access to the non-essential names in the report.