Tracein is a facility for very low level tracing/stepping, i.e. to show you everything that takes place within a particular piece of code. (TRACEIN fn {T} loc1 loc2 ...) [NLAMBDA NOSPREAD] Tracein steps or traces everything that happens in a piece of code. The first argument is the name of the function in which that code is to be found. It can also be a list of the form (fn test) where test will be evaluated to decide whether to actually trace. The default condition is T. (Note: the condition NIL is also treated as T - if you want never to break try (NOT T).) If fn is followed by T, the code will always be traced (as if you always typed T to the first prompt described below). The other arguments are editor location specifications. (TRACEIN FN) is like (BREAKIN FN) - it allows you to find the desired location in the editor. When you type OK the current expression is the answer. (TRACEIN fn loc1) does a (BREAKIN fn (AROUND loc1) ). Since TRACEIN works by calling BREAKIN, it can be undone by calling UNBREAK. When the stepper enters an expression it prints the function and prompts with the string "->". The acceptable responses are P (rettyprint the form you are about to eval), B (reak), C (ontinue to step), E (val the form with no more questions or tracing) and T (race everything in the form without asking). After the expression has been evaluated, it prints the value and prompts with the string "<-". The acceptable responses are P (rettyprint the value), B (reak), E (valuate the rest of the broken form without printing or asking) and C (ontinue stepping with the next form). Note that it only makes sense to tracein expressions that will be evaluated. You will get into trouble if you attempt to trace a clause of a COND, e.g. ((ATOM X) NIL), because it will be interpreted as call to the function (ATOM X). Also, it is the DWIMIFY'd version of your code that will be traced. Thus you may see PROG executing where you typed FOR. Note that a break condition of (NOT T) is useful for avoiding sections of code. E.g. if the code is (F (G (H))), you can see F and H but not G by doing (TRACEIN F H) and (TRACEIN ( (NOT T)) G). (WATCH form) [NLAMBDA SPREAD] Watch is the stepper/tracer used by TRACEIN. It is controlled by a free variable StepAction (initially NIL meaning step). Other possible values are T (meaning trace) and EVAL meaning no more printing or questions. Watch is a handy function to insert by hand in strategic places in your code. However, unlike TRACEIN, this method of tracing will not be undone by UNBREAK. Watch rebinds the free variable INDENT# to determine how far to indent the output. It also rebinds PRINTLEVEL when it shows the results of a computation to WATCHPLEVEL. This gives you a way to control the amount of detail you see. Notice that TRACEIN traces every subexpression that it EXPECTS to eventually be evaluated. It doesn't expect the arguments of NLAMBDAs to be evaluated, but sometimes they are. Users can tell TRACEIN what will be evaluated by adding an EVL-FIX property to functions that TRACEIN does not understand. (Maybe some masterscope expert can figure out how to use the masterscope templates to get most of the effect of EVL-FIX properties described below.) The system functions are supposed to be already understood, but if that understanding is wrong (or the user wants to change it for any other reason) the same tactic will work. The EVL-FIX property is a pattern to be applied to the tail of a function call. A pattern element of T means that the corresponding argument will be evaluated (and thus ought to be traced). NIL means that it will not. Thus the pattern for SETQ is (NIL T). If a pattern element is itself a list, then that argument is not to be traced, but it is expected to be a list which will in turn be matched with the pattern element to determine whether its elements will be traced. In addition, the special pattern element TAIL allows the pattern element after it to be applied to as many arguments as necessary to exhaust the list. For example, the pattern for COND is (TAIL (TAIL T)). The pattern for SELECTQ is (T TAIL (NIL TAIL T) T). If the CAR of a pattern is TEST, the next element is an expression which is evaluated. If the result is not NIL it will be traced. Also, as a special case, if a pattern element is an atom other than T or NIL, it is expected to be a function which will be applied to the corresponding argument, and if the result is not NIL then the argument will be traced. If the CAR of a pattern is EVAL, the next element is evaluated, and what it returns is used as the pattern. In such code, the free variable EXP is the function call that the resulting pattern is supposed to describe. In addition, the variable NOEMBED may be set to T to indicate that the function call itself is not to be traced. This feature is not normally needed, but LAMBDA is an example where it is. Implementation TRACEIN itself simply calls BREAKIN. If a break occurs (as determined by the break condition), the code that is evaluated (instead of BRKEXP) is a new version of BRKEXP in which the forms to be evaluated are embedded in calls to WATCH (the stepper/tracer). This form is computed the first time it is needed, and is stored in CLISPARRAY. Thus the WATCHified version will automatically go away (and have to be recomputed) if you ever change the expression. (Detail: before WATCHification, the expression is DWIMified. WATCHification of an expression which already has a CLISP translation stores the WATCHified version of the CLISP translation as the CLISP translation of the CLISP translation of the original form. Thus, when the break condition is false, the original CLISP translation is used. When the expression is changed, the CLISP translation goes away, and so the WATCHification (as well as the DWIMification) is redone.) DonC (Don Cohen) @ ISIF