perm filename EDITOR.F79[206,LSP] blob sn#476798 filedate 1979-09-24 generic text, type C, neo UTF8
C00001 00001
C00004 00003	.ss(commands,  LISP Editor commands.)
C00015 00004	.ss(editorex,Example session with the LISP Editor.)
C00018 00005	.bb Constructing a program using the editor.
C00021 ENDMK

	The  LISP Editor was written by R.P.Gabriel and T.Finin.
It is a structural editor that runs in the MACLISP interpreter.
The editor is useful for modifying programs already defined,
for constructing a program from scratch, or for editing other
expressions, or properties.   The editor assumes that the
expressions it is dealing with are hierarchical list structures,
e. g. lists whose elements are either atoms or other lists.
The editor knows about a top level expression and a current 
expression (CE) which is a subexpression of the top level expression.
Initially they are the same.  (Proceed at your own
risk if you try to edit a random S-expression.)
Among the possible operations are: 
change the CE, add, or delete elements of the CE,
move parentheses in and out to change the subexpression
structure, or change the CE by moving up, down or sideways
within the toplevel expression.  It is also possible to move around
in the expression by searching a match to a pattern.

	The documentation that follows is largley taken from the
online documentation of the LISP editor at the 
Stanford University AI Lab.
.ss(commands,  LISP Editor commands.)

.cb Invoking the Editor

	There are various ways to invoke the editor corresponding to
different ways of forming the top level expression to be edited.

.begin indent 0,4 turnon "∂"

1).  ∂(4)(EDIT  FOO)  edit  the in-core function "FOO" .  The top level
expression becomes (DEFUN FOO <bvars> <body>), if the EXPR
property of FOO is (LAMBDA <bvars> <body>).

2). ∂(4)(EDIT1 <exp>) will make <exp> the toplevel editable expression. 

3).  ∂(4)(EDIT2 <var>) will  make (PROG2 (SETQ <var> <current value of var>) T) 
the toplevel while (EDIT2 (GET <var> <indicator>)) will make it:
(DEFPROP <var> <value> <indicator>).


.cb |How to Look at the Current Expression (CE)|

.begin  turnon "∂"
.indent 0,8

P∂(n)        prints  the  CE  using  the  current print depth 
(sublist cutoff) and print length (length cutoff)

PP∂(n)       pretty-prints the entire CE

PS∂(n)       pretty-prints the CE using the print depth cutoff

W∂(n)        prints the "window" surrounding the CE. Thus if
window size is 2, it prints the 2 preceeding and 2 following
tokens around the CE, where "token" means expression or 

(WINDOW n)∂(n)     changes the window size to n.

(PL n)∂(n)   changes the print length to n (initially 5)

(PD n)∂(n)   changes the print depth to n (initially 2)

.cb Changing the CE
.begin  turnon "∂"
.indent 0,8

(CR E1...En)∂(n) changes the  CE  to  E1...En  (i.e. splices  in E1...En, 
and makes the CE E1.

(n E1...En)∂(n)  n>0, changes the n-th  element  of  the  CE  to  E1...En

(n E1...En)∂(n)  n<0 changes the n-th element of the CE from the end to E1...En

(n)∂(n)          n>0 deletes the n-th element of the CE

(n)∂(n)          n<0, deletes the n-th element from the end

RI∂(n)           moves the right parenthesis in one expression

RO∂(n)           moves the right parenthesis out one expression

LI∂(n)           similar to RI

LO∂(n)           similar to RO

DELETE∂(n)       deletes the CE  (if  the  CE  is  the  toplevel expression, 
the Editor assumes that the user wants to edit a different function and requests:

  (function name <file specifications>):

Valid responses are:
.begin nofill indent 4,4

1)  FOO - loads FOO from core
4)  NEW - gives a fresh top-level expression
5)  cntrl-G - quits back to the Editor command decoder
6)  UNDO - <see below>.

[Note: the Editor is designed to be able to get definitions from files,
but the current editor is incompatible with NEWIO in the current version

.cb  Moving around within the Expression
.begin  turnon "∂" nofill

n∂(n)n>0 makes the new CE the n-th element of the CE
n∂(n)n<0, makes the new CE the n-th element from the end  of the CE
↑∂(n)makes the CE the immediate parent of the CE
TOP∂(n)makes the CE the toplevel expression
NX∂(n)makes the CE the next one after the CE
BK∂(n)makes the CE the one before the CE

.cb Adding Expressions
.begin  turnon "∂" nofill

(A n E1...En)∂(n) puts E1...En after the n-th element of the CE
(B n E1...En)∂(n) puts E1...En before the n-th element of the CE
(AI E1...En)∂(n)  puts E1...En after the CE and makes E1 the new CE
(BI E1...En)∂(n)  puts E1...En before the CE and  makes  E1  the new CE
(R exp1 exp2)∂(n) replaces all occurrences of exp1 with exp2  in the CE, viewed as a list, 
         ∂(n)  returns nil? if no occurrences found
(TR exp1 exp2)∂(n)replaces all occurrences of exp1 with exp2  in the CE, viewed as a tree

.cb |Finding Expressions (i.e. changing the CE)|
.begin  turnon "∂" nofill

(F pat)∂(n) finds the next occurrence of  pat,  searching  in print order
(BF pat)∂(n)finds the next occurrence of  pat,  searching  in inverse print order
(F pat T)∂(n)finds the next occurrence of pat but looks at the topmost  elements  
	 ∂(n)of the CE first (useful for getting to PROG tags)
(BF pat T)∂(n) similar to above 
(F pat n)∂(n)  finds the n-th occurrence of pat
(BF pat n)∂(n) similar to above
F∂(n)          finds the next  occurrence  of  the  last  search pattern
BF∂(n)         similar to above

	Pat, as used above, can contain any of the following:
.cb  Patterns
.begin nofill turnon "∂"

Element of pat    ∂(n) What it matches
------- -- ---    ∂(n) ---- -- -------

atom              ∂(n) atoms EQ to it
list              ∂(n) calls matcher recursively
?                 ∂(n) any   atom   or   single   list (i.e. an s-expression)
?X                ∂(n) any  element;   binds   ?X   to whatever it matched
*                 ∂(n) any non-empty string of elements
*X                ∂(n) matches as *, but binds *X to the list of elements it matched
=?X               ∂(n) whatever ?X matched last time
=*X               ∂(n) whatever *X matched last time
(RESTRICT  ?   P1...Pn)  ∂(n)any  element  satisfying  the predicates P1,...,Pn
(RESTRICT ?X P1...Pn) ∂(n)similar to above but  binds  ?X to what it matched.

[Note: (A ?X IS A ?X) matches (a word is  a  word)  but not (a word is a sentence). 
 Simlarly for (*X is a *X).]

.cb Invoking the Matcher
.begin nofill turnon "∂"

(MATCH pat)∂(n)attempts to match pat against the CE
(MATCH pat var1 ... varn)
		∂(n) attempts to match pat against the CE while retaining the 
		∂(n)  values of the variables var1,..., varn. 
		∂(n)  (E.g. (MATCH (* *A *B ?A) *A ?A).
MATCH∂(n)attempts to match the last pat against the CE. Like F and BF above.
REMATCH∂(n)attempts to get the next match of pat against the CE. 
 			∂(n) Usually this only makes sense if pat contains some * variables.
(REMATCH var1 ... varn)
		∂(n)   rematches but will retain var1,...,varn.

.cb Hairy Matching Uses
.begin nofill turnon "∂"

(PR pat)∂(n)replaces the CE with the  instantiation  of pat  
	∂(n)(substitutes the values of ?-variables and *-variables)
(PA n P1...Pn)∂(n)   similar to (A n E1...En)
(PB n P1...Pn)∂(n)   similar to (B n E1...En)
(PAI P1...Pn)∂(n)    similar to (AI E1...En)
(PRA exp1 pat)∂(n)   similar to (R exp1 exp2)
(TPRA exp1 pat)∂(n)  similar to (TR exp1 exp2)

.cb Exiting and Etc.
.begin nofill turnon "∂"

REMEMBER∂(n)puts the  toplevel  expression under the "draft" property
	∂(n)(preserves  DEFUN  format  and comments)
OK∂(n)REMEMBER's  and   EVAL's   the toplevel expression
  ∂(n)(i.e. defines the function  as well as remembers it)
EXIT                exits the Editor (to the LISP toplevel)

.cb None of the above.

Any other command is handed to LISP to be EVAL'ed.

.next page
.ss(editorex,Example session with the LISP Editor.)

	Here are some things you can do using the LISP Editor.
The user types in lower case, LISP replys in upper case, ";;;"
flags a user comment, ";" a LISP comment.
← is the editor prompt.  It begins a command line.  Several commands
may appear on a line.  The editor processes them sequentially.
Refer to the above documentation if you don't remember what the commands
are supposed to do.
# is used to denote structure not shown when printing the skeleton of 
an S-expression.

.bb Modifying an existing program
.begin "edit session 1"
.select 6

;;; Modify APPEND to test for atoms in general not just NIL.
;;; Assume that APPEND has been DEFUNed already.

(edit append)
;loading EDIT.110 

← pp
;Loading GRINDEF 425 
    (COND ((NULL U) V) (T (CONS (CAR U) (APPEND (CDR U) V)))))

← (f null)  (cr atom) p
← ↑  p
← ↑  p
((ATOM U) V) 
← bk  p
← ↑  p
(COND (# V) (T #)) 
← bk  p
(U V) 
← (1 x)  p
(X V) 
← nx  p
(COND (# V) (T #)) 
← (r u x) pp
← top  p
← (r append appx) pp
    (COND ((ATOM X) V) (T (CONS (CAR X) (APPX (CDR X) V)))))
← ok 

;;;Any expression not recognized as an edit command will be EVALed
← (appx 'a ())
← (appx '(a . b) '(c))
(A C) 
← (appx '(a  b . c) 'c)
(A B . C) 

;;; Some alternate ways to invoke the Editor
← (setq u '(a b c d))
(A B C D) 
← (edit1 u) p
(A B C D) 
← (edit2 u) pp
(PROG2 (SETQ U '(A B C D)) T)
.end "edit session 1"
.next page
.bb Constructing a program using the editor.
.begin "edit session 2"
.select 6

;;; Construct the program SUBST (see section I.)

← (edit2 (get subst expr)) pp		;;; First define the empty program
← (3 (lambda (x y z) (cond ()())) ) p	;;; Replace by a skeleton
← 3  p
← 3  2  (b 1 (atom z) ())   p		;;; Partially fill in first clause
((ATOM Z) NIL) 				;;; of the conditional.
← 2  (cr (cond ()()))  p		;;; The skeleton of the value part
← (2 ((eq y z) x)) p			
(COND (# X) NIL) 
← (a 2 t z) p
(COND (# X) T Z NIL) 
← 5  lo  lo  p
(T Z) 
← ↑  ↑  pp
((ATOM Z) (COND ((EQ Y Z) X) (T Z)))
← nx  p					;;; Go to second clause.
← (cr (t (cons (subst) (subst)))) p	;;; Partially fill in 2nd clause
(T (CONS # #)) 
← 2  (a 2 x y (car x)) 2  ro  ro  ro  pp  ;;; Fill in arguments once
← 4  (2 z)  p				;;; correct the mistake
(CAR Z) 
← nx
nil?  					;;; there is no next expression
← ↑ nx p
← (a 1 x y (cdr z))  p			;;; Fill in arguments again
← ↑ pp
← top  pp				;;; Now to view our work
     (LAMBDA (X Y Z) 
             (COND ((ATOM Z) (COND ((EQ Y Z) X) (T Z)))
                   (T (CONS (SUBST X Y (CAR Z)) (SUBST X Y (CDR Z))))))
← ok				;;; make this the official definition

;;; Try it out
← (subst ''(a . b) 'x  '(cons (car x) (cdr x)))
(CONS (CAR (QUOTE (A . B))) (CDR (QUOTE (A . B)))) 
← (eval (subst ''(a . b) 'x  '(cons (car x) (cdr x))))
(A . B) 
.end "edit session 2"