337 lines
146 KiB
Plaintext
337 lines
146 KiB
Plaintext
1
|
||
|
||
Interlisp-D Reference Manual
|
||
1
|
||
|
||
Interlisp-D Reference Manual
|
||
13. INTERLISP EXECUTIVE
|
||
1
|
||
|
||
13. INTERLISP EXECUTIVE
|
||
1
|
||
|
||
|
||
|
||
13. INTERLISP EXECUTIVE
|
||
6
|
||
|
||
With any interactive computer language, you interact with the system through an "executive", which interprets and executes typed-in commands. In most implementations of Lisp, the executive is a simple "read-eval-print" loop, which repeatedly reads a Lisp expression, evaluates it, and prints out the value of the expression. Interlisp has an executive which allows a much greater range of inputs, other than just regular Interlisp expressions.
|
||
In particular, the Interlisp executive implements a facility known as the "programmer's assistant" (or "p.a."). The central idea of the programmer's assistant is that you are addressing an active intermediary, namely your assistant. Normally, the assistant is invisible, and simply carries out your requests. However, the assistant remembers what you have done, so you can give commands to repeat a particular operation or sequence of operations, with possible modifications, or to undo the effect of specified operations. Like DWIM, the programmer's assistant embodies an approach to system design whose ultimate goal is to construct an environment that "cooperates" with you in the development of your programs, and frees you to concentrate more fully on the conceptual difficulties and creative aspects of the problem at hand.
|
||
The programmer's assistant facility features the use of memory structures called "history lists." A history list is a list of the information associated with each of the individual "events" that have occurred in the system, where each event corresponds to one user input. Associated with each event on the history list is the input and its value, plus other optional information such as side-effects, formatting information, etc.
|
||
The following dialogue, taken from an actual session at the terminal, contains illustrative examples and gives the flavor of the programmer's assistant facility in Interlisp. The number before each prompt is the "event number" (see page X.XX).
|
||
12¬(SETQ FOO 5)
|
||
5
|
||
13¬(SETQ FOO 10)
|
||
(FOO reset)
|
||
10
|
||
The p.a. notices that the user has reset the value of FOO and informs the user.
|
||
14¬UNDO
|
||
SETQ undone.
|
||
15¬FOOcr
|
||
5
|
||
This is the first example of direct communication with the p.a. The user has said to UNDO the previous input to the executive.
|
||
.
|
||
.
|
||
.
|
||
25¬SET(LST1 (A B C))
|
||
(A B C)
|
||
26¬(SETQ LST2 '(D E F))
|
||
(D E F)
|
||
27¬(FOR X IN LST1 DO (REMPROP X 'MYPROP]
|
||
NIL
|
||
The user asked to remove the property MYPROP from the atoms A, B, and C. Now lets assume that is not what he wanted to do, but rather use the elements of LST2.
|
||
28¬UNDO FOR
|
||
FOR undone.
|
||
First he undoes the REMPROP, by undoing the iterative statement. Notice the UNDO accepted an "argument," although in this case UNDO by itself would be sufficient.
|
||
29¬USE LST2 FOR LST1 IN 27
|
||
NIL
|
||
The user just instructed to go back to event number 27 and substitute LST2 for LST1 and then reexecute the expression. The user could have also specified -2 instead of 27 to specify a relative address.
|
||
.
|
||
.
|
||
.
|
||
47¬(PUTHASH 'FOO (MKSTRING 'FOO) MYHASHARRAY)
|
||
"FOO"
|
||
If MKSTRING was a computationally expensive function (which it is not), then the user might be cacheing its value for later use.
|
||
48¬USE FIE FUM FOE FOR FOO IN MKSTRING
|
||
"FIE"
|
||
"FUM"
|
||
"FOE"
|
||
The user now decides he would like to redo the PUTHASH several times with different values. He specifies the event by "IN MKSTRING" rather than PUTHASH.
|
||
49¬?? USE
|
||
|
||
48. USE FIE FUM FOE FOR FOO IN MKSTRING
|
||
¬(PUTHASH (QUOTE FIE) (MKSTRING (QUOTE FIE)) MYHASHARRAY)
|
||
"FIE"
|
||
¬(PUTHASH (QUOTE FUM) (MKSTRING (QUOTE FUM)) MYHASHARRAY)
|
||
"FUM"
|
||
¬(PUTHASH (QUOTE FOE) (MKSTRING (QUOTE FOE)) MYHASHARRAY)
|
||
"FOE"
|
||
Here we see the user ask the p.a. (using the ?? command) what it has on its history list for the last input to the executive. Since the event corresponds to a programmer's assistant command that evaluates several forms, these forms are saved as the input, although the user's actual input, the p.a. command, is also saved in order to clarify the printout of that event.
|
||
As stated earlier, the most common interaction with the programmer's assistant occurs at the top level read-eval-print loop, or in a break, where the user types in expressions for evaluation, and sees the values printed out. In this mode, the assistant acts much like a standard Lisp executive, except that before attempting to evaluate an input, the assistant first stores it in a new entry on the history list. Thus if the operation is aborted or causes an error, the input is still saved and available for modification and/or reexecution. The assistant also notes new functions and variables to be added to its spelling lists to enable future corrections. Then the assistant executes the computation (i.e., evaluates the form or applies the function to its arguments), saves the value in the entry on the history list corresponding to the input, and prints the result, followed by a prompt character to indicate it is again ready for input.
|
||
If the input typed by the user is recognized as a p.a. command, the assistant takes special action. Commands such as UNDO and ?? are immediately performed. Commands that involved reexecution of previous inputs, such as REDO and USE, are achieved by computing the corresponding input expression(s) and then unreading them. The effect of this unreading operation is to cause the assistant's input routine, LISPXREAD, to act exactly as though these expressions were typed in by the user. These expressions are processed exactly as though they had been typed, except that they are not saved on new and separate entries on the history list, but associated with the history command that generated them.
|
||
Input Formats
|
||
1
|
||
|
||
The Interlisp-D executive accepts inputs in the following formats:
|
||
EVALV-format input If the user types a single litatom, followed by a carriage-return, the value of the litatom is returned. For example, if the value of the variable FOO is the list (A B C):
|
||
¬FOOcr
|
||
(A B C)
|
||
EVAL-format input If the user types a regular Interlisp expression, beginning with a left parenthesis or square bracket and terminated by a matching right parenthesis or square bracket, the form is simply passed to EVAL for evaluation. A right bracket matches any number of left parentheses, back to the last left bracket or the entire expression. Notice that it is not necessary to type a carriage return at the end of such a form; Interlisp will supply one automatically. If a carriage-return is typed before the final matching right parenthesis or bracket, it is treated as a space, and input continues. The following examples are all interpreted the same:
|
||
¬(PLUS 1 (TIMES 2 3))
|
||
7
|
||
¬(PLUS 1 (TIMES 2 3]
|
||
7
|
||
¬(PLUS 1 (TIMEScr
|
||
2 3]
|
||
7
|
||
APPLY-format input Often, the user, typing at the keyboard, calls functions with constant argument values, which would have to be quoted if the user typed it in "EVAL-format." For convience, if the user types a litatom immediately followed by a list form, the litatom is APPLYed to the elements within the list, unevaluated. The input is terminated by the matching right parenthesis or bracket. For example, LOAD(FOO) is equivalent to typing (LOAD 'FOO), and GETPROP(X COLOR) is equivalent to (GETPROP 'X 'COLOR).
|
||
APPLY-format input is useful in some situations, but note that it may produce unexpected results when an nlambda function is called that explicitly evaluates its arguments (see Chapter 10). For example, typing SETQ(FOO BAR) will set FOO to the value of BAR, not to the litatom BAR itself.
|
||
Other input Sometimes, a user does not want to terminate the input when a closing parenthesis is typed. For example, some programmer's assistant commands take several arguments, some of which can be lists. If the user types a sequence of litatoms and lists beginning with a litatom and a space (to
|
||
distinguish it from APPLY-format), terminated by a carriage return or an extra right parenthesis or bracket, the Interlisp-D executive interprets it differently depending on the number of expressions typed.
|
||
If only one expression is typed (a litatom), it is interpreted as an EVALV-format input, and the value of the litatom is returned:
|
||
¬FOO<space>cr
|
||
(A B C)
|
||
If exactly two expressions are typed, it is interpreted as APPLY-format input:
|
||
¬LIST (A B)cr
|
||
(A B)
|
||
If three or more expressions are typed, it is interpreted as EVAL-format input. To warn the user, the full expression is printed out before it is executed. For example:
|
||
¬PLUS (TIMES 2 3) 1cr
|
||
= (PLUS (TIMES 2 3) 1)
|
||
7
|
||
Note: If LISPXREADFN (see the Programmer's Assistant Functiions section below) is set to READ (rather than the default, TTYINREAD), then whenever one of the elements typed is a list and the list is terminated by a right parenthesis or bracket, Interlisp will type a carriage-return and "..." to indicate that further input will be accepted. The user can type further expressions or terminate the whole expression by a carriage-return.
|
||
Programmer's Assistant Commands
|
||
1
|
||
|
||
The programmer's assistant recognizes a number of commands, which usually refer to past events on the history list. These commands are treated specially; for example, they may not be put on the history list.
|
||
Note: If you define a function by the same name as a p.a. command, a warning message is printed to remind you that the p.a. command interpretation will take precedence for type-in.
|
||
All programmer's assistant commands use the same conventions and syntax for indicating which event or events on the history list the command refers to, even though different commands may be concerned with different aspects of the corresponding event(s), e.g., side-effects, value, input, etc. Therefore, before discussing the various p.a. commands, the following section describes the types of event specifications currently implemented.
|
||
Event Specification
|
||
An event address identifies one event on the history list. It consists of a sequence of "commands" for moving an imaginary cursor up or down the history list, much in the manner of the arguments to the @ break command (see Chapter 14). The event identified is the one "under" the imaginary cursor when there are no more commands. (If any command fails, an error is generated and the history command is aborted.) For example, the event address 42 refers to the event with event number 42, 42 FOO refers to the first event (searching back from event 42) whose input contains the word FOO, and 42 FOO -1 refers to the event preceeding that event. Usually, an event address will contain only one or two commands.
|
||
Most of the event address commands perform searches for events which satisfy some condition. Unless the ¬ command is given (see below), this search always goes backwards through the history list, from the most recent event specified to the oldest. Each search skips the current event. For example, if FOO refers to event N, FOO FIE will refer to some event before event N, even if there is a FIE in event N.
|
||
The event address commands are interpreted as follows:
|
||
N (an integer) If N is the first command in an event address, refers to the event with event number N. Otherwise, refers to the event N events forward (in direction of increasing event number). If N is negative, it always refers to the event -N events backwards.
|
||
For example, -1 refers to the previous event, 42 refers to event number 42 (if the first command in an event address), and 42 3 refers to the event with event number 45.
|
||
¬LITATOM Specifies the last event with an APPLY-format input whose function matches LITATOM.
|
||
Note: There must not be a space between ¬ and LITATOM.
|
||
¬ Specifies that the next search is to go forward instead of backward. If given as the first event address command, the next search begins with last (oldest) event on the history list.
|
||
F Specifies that the next object in the event address is to be searched for, regardless of what it is. For example, F -2 looks for an event containing -2.
|
||
= Specifies that the next object (presumably a pattern) is to be matched against the values of events, instead of the inputs.
|
||
\ Specifies the event last located.
|
||
SUCHTHAT PRED Specifies an event for which the function PRED returns true. PRED should be a function of two arguments, the input portion of the event, and the event itself. See the Format and Use of the History List section below for a discussion of the format of events on the history list.
|
||
PAT Any other event address command specifies an event whose input contains an expression that matches PAT as described in Chapter 16.
|
||
The matching is performed by the function HISTORYMATCH (see the Programmer's Assistant Functions section below), which is initially defined to call EDITFINDP but can be advised or redefined for specialized applications.
|
||
Symbols used below of the form EventAddressi refer to event addresses, described above. Since an event address may contain multiple words, the event address is parsed by searching for the words which delimit it. For example, in FROM EventAddress1 THRU EventAddress2, the symbol EventAddress1 corresponds to all words between FROM and THRU in the event specification, and EventAddress2 to all words from THRU to the end of the event specification.
|
||
FROM EventAddress1 THRU EventAddress2
|
||
EventAddress1 THRU EventAddress2
|
||
Specifies the sequence of events from the event with address EventAddress1 through the event with address EventAddress2. For example, FROM 47 THRU 49 specifies events 47, 48, and 49. EventAddress1 can be more recent than EventAddress2. For example, FROM 49 THRU 47 specifies events 49, 48, and 47 (note reversal of order).
|
||
FROM EventAddress1 TO EventAddress2
|
||
EventAddress1 TO EventAddress2
|
||
Same as THRU but does not include event EventAddress2.
|
||
FROM EventAddress1 Same as FROM EventAddress1 THRU -1. For example, if the current event is number 53, then FROM 49 specifies events 49, 50, 51, and 52.
|
||
THRU EventAddress2 Same as FROM -1 THRU EventAddress2. For example, if the current event is number 53, then THRU 49 specifies events 52, 51, 50, and 49 (note reversal of order).
|
||
TO EventAddress2 Same as FROM -1 TO EventAddress2.
|
||
ALL EventAddress1 Specifies all events satisfying EventAddress1. For example, ALL LOAD, ALL SUCHTHAT FOO.
|
||
empty If nothing is specified, it is the same as specifying -1.
|
||
Note: In the special case that the last event was an UNDO, it is the same as specifying -2. For example, if you type (NCONC FOO FIE), you can then type UNDO, followed by USE NCONC1.
|
||
EventSpec1 AND EventSpec2 AND ... AND EventSpecN
|
||
Each of the EventSpeci is an event specification. The lists of events are concatenated. For example, FROM 30 THRU 32 AND 35 THRU 37 is the same as 30 AND 31 AND 32 AND 35 AND 36 AND 37.
|
||
@ LITATOM If LITATOM is the name of a command defined via the NAME command (see the Commands section below), specifies the event(s) defining LITATOM.
|
||
@@ EventSpec EventSpec is an event specification interpreted as above, but with respect to the archived history list (see the ARCHIVE command, in the Commands section below).
|
||
If no events can be found that satisfy the event specification, spelling correction on each word in the event specification is performed using LISPXFINDSPLST as the spelling list. For example, REDO 3 THRUU 6 will work correctly. If the event specification still fails to specify any events after spelling correction, an error is generated.
|
||
Commands
|
||
All programmer's assistant commands can be input as list forms, or as lines (see the Preogrammer's Assistant Functions section below). For example, typing REDO 5cr and (REDO 5) are equivalent.
|
||
EventSpec is used to denote an event specification. Unless specified otherwise, omitting EventSpec is the same as specifying EventSpec=-1. For example, REDO and REDO -1 are the same.
|
||
REDO EventSpec [Prog. Asst. Command]
|
||
Redoes the event or events specified by EventSpec. For example, REDO FROM -3 redoes the last three events.
|
||
REDO EventSpec N TIMES [Prog. Asst. Command]
|
||
Redoes the event or events specified by EventSpec N times. For example, REDO 10 TIMES redoes the last event ten times.
|
||
REDO EventSpec WHILE FORM [Prog. Asst. Command]
|
||
Redoes the specified events as long as the value of FORM is true. FORM is evaluated before each iteration so if its initial value is NIL, nothing will happen.
|
||
REDO EventSpec UNTIL FORM [Prog. Asst. Command]
|
||
Same as REDO EventSpec WHILE (NOT FORM).
|
||
REPEAT EventSpec [Prog. Asst. Command]
|
||
Same as REDO EventSpec WHILE T. The event(s) are repeated until an error occurs, or the user types Control-E or Control-D.
|
||
REPEAT EventSpec WHILE FORM [Prog. Asst. Command]
|
||
REPEAT EventSpec UNTIL FORM [Prog. Asst. Command]
|
||
Same as REDO.
|
||
For all history commands that perform multiple repetitions, the variable REDOCNT is initialized to 0 and incremented each iteration. If the event terminates gracefully, i.e., is not aborted by an error or Control-D, the number of iterations is printed.
|
||
RETRY EventSpec [Prog. Asst. Command]
|
||
Similar to REDO except sets HELPCLOCK (see Chapter 14) so that any errors that occur while executing EventSpec will cause breaks.
|
||
USE EXPRS FOR ARGS IN EventSpec [Prog. Asst. Command]
|
||
Substitutes EXPRS for ARGS in EventSpec, and redoes the result. Substitution is done by ESUBST (see Chapter 16), and is carried out as described below. EXPRS and ARGS can include non-atomic members.
|
||
For example, USE LOG (MINUS X) FOR ANTILOG X IN -2 AND -1 will substitute LOG for every occurrence of ANTILOG in the previous two events, and substitute (MINUS X) for every occurrence of X, and reexecute them. Note that these substitutions do not change the information saved about these events on the history list.
|
||
Any expression to be substituted can be preceded by a !, meaning that the expression is to be substituted as a segment, e.g., LIST(A B C) followed by USE ! (X Y Z) FOR B will produce LIST(A X Y Z C), and USE ! NIL FOR B will produce LIST(A C).
|
||
If IN EventSpec is omitted, the first member of ARGS is used for EventSpec. For example, USE PUTD FOR @UTD is equivalent to USE PUTD FOR @UTD IN F @UTD. The F is inserted to handle correctly the case where the first member of ARGS could be interpreted as an event address command.
|
||
USE EXPRS IN EventSpec [Prog. Asst. Command]
|
||
If ARGS are omitted, and the event referred to was itself a USE command, the arguments and expression substituted into are the same as for the indicated USE command. In effect, this USE command is thus a continuation of the previous USE command. For example, following USE X FOR Y IN 50, typing USE Z IN -1 is equivalent to USE Z FOR Y IN 50.
|
||
If ARGS are omitted and the event referred to was not a USE command, substitution is for the "operator" in that command. For example ARGLIST(FF) followed by USE CALLS IN -1 is equivalent to USE CALLS FOR ARGLIST IN -1.
|
||
If IN EventSpec is omitted, it is the same as specifying IN -1.
|
||
USE EXPRS1 FOR ARGS1 AND ... AND EXPRSN FOR ARGSN IN EventSpec [Prog. Asst. Command]
|
||
More general form of USE command. See description of the substitution algorithm below.
|
||
Note: The USE command is parsed by a small finite state parser to distinguish the expressions and arguments. For example, USE FOR FOR AND AND AND FOR FOR will be parsed correctly.
|
||
Every USE command involves three pieces of information: the expressions to be substituted, the arguments to be substituted for, and an event specification, which defines the input expression in which the substitution takes place. If the USE command has the same number of expressions as arguments, the substitution procedure is straightforward. For example, USE X Y FOR U V means substitute X for U and Y for V, and is equivalent to USE X FOR U AND Y FOR V.
|
||
However, the USE command also permits distributive substitutions, for substituting several expressions for the same argument. For example, USE A B C FOR X means first substitute A for X then substitute B for X (in a new copy of the expression), then substitute C for X. The effect is the same as three separate USE commands. Similarly, USE A B C FOR D AND X Y Z FOR W is equivalent to USE A FOR D AND X FOR W, followed by USE B FOR D AND Y FOR W, followed by USE C FOR D AND Z FOR W. USE A B C FOR D AND X FOR Y also corresponds to three substitutions, the first with A for D and X for Y, the second with B for D, and X for Y, and the third with C for D, and again X for Y. However, USE A B C FOR D AND X Y FOR Z is ambiguous and will cause an error.
|
||
Essentially, the USE command operates by proceeding from left to right handling each "AND" separately. Whenever the number of expressions exceeds the number of expressions available, multiple USE expressions are generated. Thus USE A B C D FOR E F means substitute A for E at the same time as substituting B for F, then in another copy of the indicated expression, substitute C for E and D for F. This is also equivalent to USE A C FOR E AND B D FOR F.
|
||
Note: Parsing the USE command gets more complicated when one of the arguments and one of the expressions are the same, e.g., USE X Y FOR Y X, or USE X FOR Y AND Y FOR X. This situation is noticed when parsing the command, and handled correctly.
|
||
... VARS [Prog. Asst. Command]
|
||
Similar to USE except substitutes for the (first) operand.
|
||
For example, EXPRP(FOO) followed by ... FIE FUM is equivalent to USE FIE FUM FOR FOO.
|
||
In the following discussion, $ is used to represent the character "escape," since this is how this character is echoed.
|
||
$ X FOR Y IN EventSpec [Prog. Asst. Command]
|
||
$ (escape) is a special form of the USE command for conveniently specifying character substitutions in litatoms or strings. In addition, it has a number of useful properties in connection with events that involve errors (see below).
|
||
Equivalent to USE $X$ FOR $Y$ IN EventSpec, which will do a character substitution of the characters in X for the characters in Y.
|
||
For example, if you type MOVD(FOO FOOSAVE T), you can then type $ FIE FOR FOO IN MOVD to perform MOVD(FIE FIESAVE T). USE FIE FOR FOO would perform MOVD(FIE FOOSAVE T).
|
||
$ Y X IN EventSpec [Prog. Asst. Command]
|
||
$ Y TO X IN EventSpec [Prog. Asst. Command]
|
||
$ Y = X IN EventSpec [Prog. Asst. Command]
|
||
$ Y -> X IN EventSpec [Prog. Asst. Command]
|
||
Abbreviated forms of the $ (escape) command: the same as $ X FOR Y IN EventSpec, which changes Ys to Xs.
|
||
$ does event location the same as the USE command, i.e., if IN EventSpec is not specified, $ searches for Y. However, unlike USE, $ can only be used to specify one substitution at a time. After $ finds the event, it looks to see if an error was involved in that event, and if the indicated character substitution can be performed in the object of the error message, called the offender. If so, $ assumes the substitution refers to the offender, performs the indicated character substitution in the offender only, and then substitutes the result for the original offender throughout the event. For example, suppose the user types (PRETTYDEF FOOFNS 'FOO FOOOVARS) causing a U.B.A. FOOOVARS error message. The user can now type $ OO O, which will change FOOOVARS to FOOVARS, but not change FOOFNS or FOO.
|
||
If an error did occur in the specified event, you can also omit specifying the object of the substitution, Y, in which case the offender itself is used. Thus, you could have corrected the above example by simply typing $ FOOVARS. Since ESUBST is used for performing the substitution (see Chapter 16), $ can be used in X to refer to the characters in Y. For example, if you type LOAD(PRSTRUC PROP), causing the error FILE NOT FOUND PRSTRUC, you can request the file to be loaded from LISP's directory by simply typing $ <LISP>$. This is equivalent to performing (R PRSTRUC <LISP>$) on the event, and therefore replaces PRSTRUC by <LISP>PRSTRUC.
|
||
$ never searches for an error. Thus, if you type LOAD(PRSTRUC PROP) causing a FILE NOT FOUND error, type CLOSEALL(), and then type $ <LISP>$, LISPX will complain that there is no error in CLOSEALL(). In this case, you would have to type $ <LISP>$ IN LOAD, or $ PRS <LISP>PRS (which would cause a search for PRS).
|
||
$ operates on input, not on programs. If you type FOO(), and within the call to FOO gets a U.D.F. CONDD error, you cannot repair this by $ COND. LISPX will type CONDD NOT FOUND IN FOO().
|
||
FIX EventSpec [Prog. Asst. Command]
|
||
Invokes the default program editor (Dedit or the teletype editor) on a copy of the input(s) for EventSpec. Whenever the user exits via OK, the result is unread and reexecuted exactly as with REDO.
|
||
FIX is provided for those cases when the modifications to the input(s) are not simple substitutions of the type that can be specified by USE. For example, if the default editor is the teletype editor, then:
|
||
¬(DEFINEQ FOO (LAMBDA (X) (FIXSPELL SPELLINGS2 X 70]
|
||
INCORRECT DEFINING FORM
|
||
FOO
|
||
¬FIX
|
||
EDIT
|
||
*P
|
||
(DEFINEQ FOO (LAMBDA & &))
|
||
*(LI 2)
|
||
*P
|
||
(DEFINEQ (FOO &))
|
||
*OK
|
||
(FOO)
|
||
¬
|
||
You can also specify the edit command(s) to LISPX, by typing - followed by the command(s) after the event specification, e.g., FIX - (LI 2). In this case, the editor will not type EDIT, or wait for an OK after executing the commands.
|
||
FIX calls the editor on the "input sequence" of an event, adjusting the editor so it is initially editing the expression typed. However, the entire input sequence is being edited, so it is possible to give editor commands that examine this structure further. For more information on the format of an event's input, see the Format and Use of the History List section below.
|
||
?? EventSpec [Prog. Asst. Command]
|
||
Prints the specified events from the history list. If EventSpec is omitted, ?? prints the entire history list, beginning with most recent events. Otherwise ?? prints only those events specified in EventSpec (in the order specified). For example, ?? -1, ?? 10 THRU 15, etc.
|
||
For each event specified, ?? prints the event number, the prompt, the input line(s), and the value(s). If the event input was a p.a. command that "unread" some other input lines, the p.a. command is printed without a preceding prompt, to show that they are not stored as the input, and the input lines are printed with prompts.
|
||
Events are initially stored on the history list with their value field equal to the character "bell" (Control-G). Thefore, if an operation fails to complete for any reason, e.g., causes an error, is aborted, etc., ?? will print a bell as its "value".
|
||
?? commands are not entered on the history list, and so do not affect relative event numbers. In other words, an event specification of -1 typed following a ?? command will refer to the event immediately preceding the ?? command.
|
||
?? is implemented via the function PRINTHISTORY (see the Programmer's Assistant Functions section below) which can also be called directly by the user. Printing is performed via the function SHOWPRIN2 (see Chapter 25), so that if the value of SYSPRETTYFLG=T, events will be prettyprinted.
|
||
UNDO EventSpec [Prog. Asst. Command]
|
||
Undoes the side effects of the specified events. For each event undone, UNDO prints a message: RPLACA undone, REDO undone etc. If nothing is undone because nothing was saved, UNDO types nothing saved. If nothing was undone because the events were already undone, UNDO types already undone.
|
||
If EventSpec is not given, UNDO searches back for the last event that contained side effects, was not undone, and itself was not an UNDO command. Note that the user can undo UNDO commands themselves by specifying the corresponding event address, e.g., UNDO -7 or UNDO UNDO.
|
||
To restore all pointers correctly, you should UNDO events in the reverse order from which they were executed. For example, to undo all the side effects of the last five events, perform UNDO THRU -5, not UNDO FROM -5. Undoing out of order may have unforseen effects if the operations are dependent. For example, if you performed (NCONC1 FOO FIE), followed by (NCONC1 FOO FUM), and then undoes the (NCONC1 FOO FIE), he will also have undone the (NCONC1 FOO FUM). If he then undoes the (NCONC1 FOO FUM), he will cause the FIE to reappear, by virtue of restoring FOO to its state before the execution of (NCONC1 FOO FUM). For more details, see the Undoing section below.
|
||
UNDO EventSpec : X1 ... XN [Prog. Asst. Command]
|
||
Each Xi is a pattern that is matched to a message printed by DWIM in the event(s) specified by EventSpec. The side effects of the corresponding DWIM corrections, and only those side effects, are undone.
|
||
For example, if DWIM printed the message PRINTT [IN FOO] -> PRINT, then UNDO : PRINTT or UNDO : PRINT would undo the correction.
|
||
Some portions of the messages printed by DWIM are strings, e.g., the message FOO UNSAVED is printed by printing FOO and then " UNSAVED". Therefore, if the user types UNDO : UNSAVED, the DWIM correction will not be found. He should instead type UNDO : FOO or UNDO : $UNSAVED$ (<esc>UNSAVED<esc>, see R command in editor, page X.XX).
|
||
NAME LITATOM EventSpec [Prog. Asst. Command]
|
||
Saves the event(s) (including side effects) specified by EventSpec on the property list of LITATOM (under the property HISTORY). For example, NAME FOO 10 THRU 15. NAME commands are undoable.
|
||
Events saved on a litatom can be retrieved with the event specification @ LITATOM. For example, ?? @ FOO, REDO @ FOO, etc.
|
||
Commands defined by NAME can also be typed in directly as though they were built-in commands, e.g., FOOcr is equivalent to REDO @ FOO. However, if FOO is the name of a variable, it would be evaluated, i.e., FOOcr would return the value of FOO.
|
||
Commands defined by NAME can also be defined to take arguments:
|
||
NAME LITATOM (ARG1 ... ARGN) : EventSpec [Prog. Asst. Command]
|
||
NAME LITATOM ARG1 ... ARGN : EventSpec [Prog. Asst. Command]
|
||
The arguments ARGi are interpreted the same as the arguments for a USE command. When LITATOM is invoked, the argument values are substituted for ARG1 ... ARGN using the same substitution algorithm as for USE.
|
||
NAME FOO EventSpec is equivalent to NAME FOO : EventSpec. In either case, if FOO is invoked with arguments, an error is generated.
|
||
For example, following the event (PUTD 'FOO (COPY (GETPROP 'FIE 'EXPR))), the user types NAME MOVE FOO FIE : PUTD. Then typing MOVE TEST1 TEST2 would cause (PUTD 'TEST1 (COPY (GETPROP 'TEST2 'EXPR))) to be executed, i.e., would be equivalent to typing USE TEST1 TEST2 FOR FOO FIE IN MOVE. Typing MOVE A B C D would cause two PUTD's to be executed. Note that !'s and $'s can also be employed the same as with USE. For example, if following
|
||
¬PREPINDEX(<MANUAL>14LISP.XGP)
|
||
¬FIXFILE(<MANUAL>14LISP.XGPIDX)
|
||
the user performed NAME FOO $14$ : -2 AND -1, then FOO $15$ would perform the indicated two operations with 14 replaced by 15.
|
||
RETRIEVE LITATOM [Prog. Asst. Command]
|
||
Retrieves and reenters on the history list the events named by LITATOM. Causes an error if LITATOM was not named by a NAME command.
|
||
For example, if the user performs NAME FOO 10 THRU 15, and at some time later types RETRIEVE FOO, six new events will be recorded on the history list (whether or not the corresponding events have been forgotten yet). Note that RETRIEVE does not reexecute the events, it simply retrieves them. The user can then REDO, UNDO, FIX, etc. any or all of these events. Note that the user can combine the effects of a RETRIEVE and a subsequent history command in a single operation, e.g., REDO FOO is equivalent to RETRIEVE FOO, followed by an appropriate REDO. Actually, REDO FOO is better than RETRIEVE followed by REDO since in the latter case, the corresponding events would be entered on the history list twice, once for the RETRIEVE and once for the REDO. Note that UNDO FOO and ?? FOO are permitted.
|
||
BEFORE LITATOM [Prog. Asst. Command]
|
||
Undoes the effects of the events named by LITATOM.
|
||
AFTER LITATOM [Prog. Asst. Command]
|
||
Undoes a BEFORE LITATOM.
|
||
BEFORE and AFTER provide a convenient way of flipping back and forth between two states, namely the state before a specified event or events were executed, and that state after execution. For example, if the user has a complex data structure which he wants to be able to interrogate before and after certain modifications, he can execute the modifications, name the corresponding events with the NAME command, and then can turn these modifications off and on via BEFORE or AFTER commands. Both BEFORE and AFTER are no-ops if the LITATOM was already in the corresponding state; both generate errors if LITATOM was not named by a NAME command.
|
||
The alternative to BEFORE and AFTER for repeated switching back and forth involves typing UNDO, UNDO of the UNDO, UNDO of that etc. At each stage, the user would have to locate the correct event to undo, and furthermore would run the risk of that event being "forgotten" if he did not switch at least once per time-slice.
|
||
Note: Since UNDO, NAME, RETRIEVE, BEFORE, and AFTER are recorded as inputs they can be referenced by REDO, USE, etc. in the normal way. However, the user must again remember that the context in which the command is reexecuted is different than the original context. For example, if the user types NAME FOO DEFINEQ THRU COMPILE, then types ... FIE, the input that will be reread will be NAME FIE DEFINEQ THRU COMPILE as was intended, but both DEFINEQ and COMPILE, will refer to the most recent event containing those atoms, namely the event consisting of NAME FOO DEFINEQ THRU COMPILE.
|
||
ARCHIVE EventSpec [Prog. Asst. Command]
|
||
Records the events specified by EventSpec on a permanent "archived" history list, ARCHIVELST (page X.XX). This history list can be referenced by preceding a standard event specification with @@ (see page X.XX). For example, ?? @@ prints the archived history list, REDO @@ -1 will recover the corresponding event from the archived history list and redo it, etc.
|
||
The user can also provide for automatic archiving of selected events by appropriately defining ARCHIVEFN (page X.XX), or by putting the history list property *ARCHIVE*, with value T, on the event (page X.XX). Events that are referenced by history commands are automatically marked for archiving in this fashion.
|
||
FORGET EventSpec [Prog. Asst. Command]
|
||
Permanently erases the record of the side effects for the events specified by EventSpec. If EventSpec is omitted, forgets side effects for entire history list.
|
||
FORGET is provided for users with space problems. For example, if the user has just performed SETs, RPLACAs, RPLACDs, PUTD, REMPROPs, etc. to release storage, the old pointers would not be garbage collected until the corresponding events age sufficiently to drop off the end of the history list and be forgotten. FORGET can be used to force immediate forgetting (of the side-effects only). FORGET is not undoable (obviously).
|
||
REMEMBER EventSpec [Prog. Asst. Command]
|
||
Instructs the file package to "remember" the events specified by EventSpec. These events will be marked as changed objects of file package type EXPRESSIONS, which can be written out via the file package command P. For example, after the user types:
|
||
¬MOVD?(DELFILE /DELFILE)
|
||
DELFILE
|
||
¬REMEMBER -1
|
||
(MOVD? (QUOTE DELFILE) (QUOTE /DELFILE))
|
||
¬
|
||
If the user calls FILES?, MAKEFILES, or CLEANUP, the command (P (MOVD? (QUOTE DELFILE) (QUOTE /DELFILE))) will be constructed by the file package and added to the filecoms indicated by the user, unless the user has already explicitly added the corresponding expression to some P command himself.
|
||
Note that "remembering" an event like (PUTPROP 'FOO 'CLISPTYPE EXPRESSION) will not result in a (PROP CLISPTYPE FOO) command, because this will save the current (at the time of the MAKEFILE) value for the CLISPTYPE property, which may or may not be EXPRESSION. Thus, even if there is a PROP command which saves the CLISPTYPE property for FOO in some FILECOMS, remembering this event will still require a (P (PUTPROP 'FOO 'CLISPTYPE EXPRESSION)) command to appear.
|
||
PL LITATOM [Prog. Asst. Command]
|
||
"Print Property List." Prints out the property list of LITATOM in a nice format, with PRINTLEVEL reset to (2 . 3). For example,
|
||
¬PL +
|
||
CLISPTYPE: 12
|
||
ACCESSFNS: (PLUS IPLUS FPLUS)
|
||
PL is implemented via the function PRINTPROPS.
|
||
PB LITATOM [Prog. Asst. Command]
|
||
"Print Bindings." Prints the value of LITATOM with PRINTLEVEL reset to (2 . 3). If LITATOM is not bound, does not attempt spelling correction or generate an error. PB is implemented via the function PRINTBINDINGS.
|
||
PB is also a break command (see Chapter 14). As a break command, it ascends the stack and, for each frame in which LITATOM is bound, prints the frame name and value of LITATOM. If typed in to the programmer's assistant when not at the top level, e.g. in the editor, etc., PB will also ascend the stack as it does with a break. However, as a programmer's assistant command, it is primarily used to examine the top level value of a variable that may or may not be bound, or to examine a variable whose value is a large list.
|
||
; FORM [Prog. Asst. Command]
|
||
Allows you to type a line of text without having the programmer's assistant process it. Useful when linked to other users, or to annotate a dribble file (see Chapter 30).
|
||
SHH FORM [Prog. Asst. Command]
|
||
Allows you to evaluate an expression without having the programmer's assistant process it or record it on a history list. Useful when you want to bypass a programmer's assistant command or to keep the evaluation off the history list.
|
||
TYPE-AHEAD [Prog. Asst. Command]
|
||
A command that allows you to type-ahead an indefinite number of inputs.
|
||
The assistant responds to TYPE-AHEAD with a prompt character of >. The user can now type in an indefinite number of lines of input, under ERRORSET protection. The input lines are saved and unread when the user exits the type-ahead loop with the command $GO (escape-GO). While in the type-ahead loop, ?? can be used to print the type-ahead, FIX to edit the type-ahead, and $Q (escape-Q) to erase the last input (may be used repeatedly). The TYPE-AHEAD command may be aborted by $STOP (escape-STOP); Control-E simply aborts the current line of input.
|
||
For example:
|
||
¬TYPE-AHEAD
|
||
>SYSOUT(TEM)
|
||
>MAKEFILE(EDIT)
|
||
>BRECOMPILE((EDIT WEDIT))
|
||
>F
|
||
>$Q
|
||
\\F
|
||
>$Q
|
||
\\BRECOMPILE
|
||
>LOAD(WEDIT PROP)
|
||
>BRECOMPILE((EDIT WEDIT))
|
||
>F
|
||
>MAKEFILE(BREAK)
|
||
>LISTFILES(EDIT BREAK)
|
||
>SYSOUT(CURRENT)
|
||
>LOGOUT]
|
||
>??
|
||
>SYSOUT(TEM)
|
||
>MAKEFILE(EDIT)
|
||
>LOAD(WEDIT PROP)
|
||
>BRECOMPILE((EDIT WEDIT))
|
||
>F
|
||
>MAKEFILE(BREAK)
|
||
>LISTFILES(EDIT BREAK)
|
||
>SYSOUT(CURRENT)
|
||
>LOGOUT]
|
||
>FIX
|
||
EDIT
|
||
*(R BRECOMPILE BCOMPL)
|
||
*P
|
||
((LOGOUT) (SYSOUT &) (LISTFILES &) (MAKEFILE &) (F) (BCOMPL &)
|
||
(LOAD &) (MAKEFILE &) (SYSOUT &))
|
||
*(DELETE LOAD)
|
||
*OK
|
||
>$GO
|
||
Type-ahead can be addressed to the compiler, since it uses LISPXREAD for input. Type-ahead can also be directed to the editor, but type-ahead to the editor and to LISPX cannot be intermixed.
|
||
The following are some useful functions and variables:
|
||
(VALUEOF LINE) [NLambda NoSpread Function]
|
||
An nlambda function for obtaining the value of a particular event, e.g., (VALUEOF -1), (VALUEOF _FOO -2). The value of an event consisting of several operations is a list of the values for each of the individual operations.
|
||
Note: The value field of a history entry is initialized to bell (Control-G). Thus a value of bell indicates that the corresponding operation did not complete, i.e., was aborted or caused an error (or else it returned bell).
|
||
Note: Although the input for VALUEOF is entered on the history list before VALUEOF is called, (VALUEOF -1) still refers to the value of the expression immediately before the VALUEOF input, because VALUEOF effectively backs the history list up one entry when it retrieves the specified event. Similarly, (VALUEOF FOO) will find the first event before this one that contains a FOO.
|
||
IT (IT% (Variable) NIL NIL NIL 15) [Variable]
|
||
The value of the variable IT is always the value of the last event executed, i.e. (VALUEOF -1). For example,
|
||
¬(SQRT 2)
|
||
1.414214
|
||
¬(SQRT IT)
|
||
1.189207
|
||
If the last event was a multiple event, e.g. REDO -3 THRU -1, IT is set to value of the last of these events. Following a ?? command, IT is set to value of the last event printed. In other words, in all cases, IT is set to the last value printed on the terminal.
|
||
P.A. Commands Applied to P.A. Commands
|
||
Programmer's assistant commands that unread expressions, such as REDO, USE, etc. do not appear in the input portion of events, although they are stored elsewhere in the event. They do not interfere with or affect the searching operations of event specifications. As a result, p.a. commands themselves cannot be recovered for execution in the normal way. For example, if you type USE A B C FOR D, followqed by USE E FOR D, you will not produce the effect of USE A B C FOR E, but instead will simply cause E to be substituted for D in the last event containing a D. To produce the desired effect, you should type USE D FOR E IN USE. The appearance of the word REDO, USE or FIX in an event address specifies a search for the corresponding programmer's assistant command. It also specifies that the text of the programmer's assistant command itself be treated as though it were the input. However, remember that the context in which a history command is reexecuted is that of the current history, not the original context. For example, if you type USE FOO FOR FIE IN -1, and then later type REDO USE, the -1 will refer to the event before the REDO, not before the USE.
|
||
The one exception to the statement that programmer's assistant commands "do not interfere with or affect the searching operations of event specifications" occurs when a p.a. command fails to produce any input. For example, suppose you type USE LOG FOR ANTILOG AND ANTILOG FOR LOGG, mispelling the second LOG. This will cause an error, LOGG ?. Since the USE command did not produce any input, the user can repair it by typing USE LOG FOR LOGG, without having to specify IN USE. This latter USE command will invoke a search for LOGG, which will find the bad USE command. The programmer's assistant then performs the indicated substitution, and unreads USE LOG FOR ANTILOG AND ANTILOG FOR LOG. In turn, this USE command invokes a search for ANTILOG, which, because it was not typed in but reread, ignores the bad USE command which was found by the earlier search for LOGG, and which is still on the history list. In other words, p.a. commands that fail to produce input are visible to searches arising from event specifications typed in by the user, but not to secondary event specifications.
|
||
In addition, if the most recent event is a history command which failed to produce input, a secondary event specification will effectively back up the history list one event so that relative event numbers for that event specification will not count the bad p.a. command. For example, suppose the user types USE LOG FOR ANTILOG AND ANTILOG FOR LOGG IN -2 AND -1, and after the p.a. types LOGG ?, the user types USE LOG FOR LOGG. He thus causes the command USE LOG FOR ANTILOG AND ANTILOG FOR LOG IN -2 AND -1 to be constructed and unread. In the normal case, -1 would refer to the last event, i.e., the "bad" USE command, and -2 to the event before it. However, in this case, -1 refers to the event before the bad USE command, and the -2 to the event before that. In short, the caveat above that "the user must remember that the context in which a history command is reexecuted is that of the current history, not the original context" does not apply if the correction is performed immediately.
|
||
Changing The Programmer's Assistant
|
||
1
|
||
ÿÿ |