{Begin SubSec EDITA}
{Title EDITA}
{Text

{note EDITA was written by W. Teitelman, and modified by D. C. Lewis.}

{it
Note:  EDITA is a LispUsers package contained on the file {lisp EDITA.COM}.  That portion of EDITA relating to compiled code may not be available in implementations of Interlisp other than Interlisp-10.  EDITA also has a {prop FILEDEF} property so that the user can simply call {fn EDITA} and the file will be automatically loaded.
}



{index *BEGIN* EDITA}
{index *BEGIN* editing arrays}
{index *BEGIN* editing compiled code}

EDITA is an editor for arrays.
However, its most frequent application is in editing compiled functions (which are also arrays in Interlisp-10), and a great deal of effort in implementing EDITA, and most of its special features, are in this area.  For example, EDITA knows the format and conventions of Interlisp-10 compiled code, and so, in addition to decoding instructions a la {index DDT}DDT (one of the oldest debugging systems still around), EDITA can fill in the appropriate COREVALS, symbolic names for index registers, references to literals, linked function calls, etc.  The following output shows a sequence of instructions in a compiled function first as they would be printed by DDT, and second by EDITA.



{Begin Table sequence of instructions}

{VSKIP 0}

{COLUMN}	{COLUMN}

{First {lisp 466716/  PUSH 16,LISP&KNIL}}
						{Next {lisp 3/   PUSH PP,KNIL}}
{First {lisp 466717/  PUSH 16,LISP&KNIL}}
						{Next {lisp 4/   PUSH PP,KNIL}}
{First {lisp 466720/  HRRZ 1,-12(16)}}	{Next {lisp 5/   HRRZ 1,-10(PP)}}
{First {lisp 466721/  CAME 1,LISP&KNIL}}
						{Next {lisp 6/   CAME 1,KNIL}}
{First {lisp 466722/  JRST 466724}}	{Next {lisp 7/   JRST 9}{foot
Note that EDITA prints the addresses of cells contained {it in} the function relative to the origin of the function.
}{comment endfootnote}
}
{First {lisp 466723/  HRRZ 1,@467575}}	{Next {lisp 8/   HRRZ 1,@'BRKFILE}}
{First {lisp 466724/  PUSH 16,1}}		{Next {lisp 9/   PUSH PP,1}}
{First {lisp 466725/  LISP&IOFIL,,467576}}
						{Next {lisp 10/  PBIND 'BRKZ}}
{First {lisp 466726/  -3,,-3}}		{Next {lisp 11/  -524291}}
{First {lisp 466727/  HRRZ 1,-14(16)}}	{Next {lisp 12/  HRRZ 1,-12(PP)}}
{First {lisp 466730/  CAMN 1,467601}}	{Next {lisp 13/  CAMN 1,'OK}}
{First {lisp 466731/  JRST 466734}}	{Next {lisp 14/  JRST 17}}
{First {lisp 466732/  CAME 1,467602}}	{Next {lisp 15/  CAME 1,'STOP}}
{First {lisp 466733/  JRST 466740}}	{Next {lisp 16/  JRST 21}}
{First {lisp 466734/  PUSH 16,467603}}	{Next {lisp 17/  PUSH PP,'BREAK1}}
{First {lisp 466735/  PUSH 16,467604}}	{Next {lisp 18/  PUSH PP,'(ERROR!)}}
{First {lisp 466736/  LISP&FILEN,,467605}}
						{Next {lisp 19/  CCALL 2,'RETEVAL}}
{First {lisp 466737/  JRST 467561}}	{Next {lisp 20/  JRST 422}}
{First {lisp 466740/  CAME 1,467606}}	{Next {lisp 21/  CAME 1,'GO}}
{First {lisp 466741/  JRST 466754}}	{Next {lisp 22/  JRST 33}}
{First {lisp 466742/  HRRZ 1,@-12(16)}}
						{Next {lisp 23/  HRRZ 1,@-10(PP)}}
{First {lisp 466743/  PUSH 16,1}}		{Next {lisp 24/  PUSH PP,1}}

{End Table sequence of instructions}



Therefore, rather than presenting EDITA as an array editor with some extensions for editing compiled code, we prefer to consider it as a facility for editing compiled code, and point out that it can also be used for editing arbitrary arrays.


{Begin SubSec Overview}
{Title Overview}
{Text


EDITA is envoked by calling the function {fn EDITA}:

{FnDef {Name EDITA} {Args FN COMS}
{Text
Envokes EDITA to edit the function {arg FN}.  To the user, EDITA looks very much like DDT with Interlisp-10 extensions.  If {arg COMS} is given, it should be a list of commands for EDITA.  These are then executed exactly as though they had been typed.  EDITA can be exited with the command {lisp OK}.
}}

Individual registers or cells in the function may be examined by typing their address followed by a slash, e.g.

{lispcode 6/  HRRZ 1,-10(PP)}


{index / (EDITA command)}The slash is really a command to EDITA to open the indicated register.{foot
EDITA also converts absolute addresses of cells within the function to relative address on input.
Thus, if the definition of {lisp FOO} begins at {lisp 85660}, typing {lisp 6/} is {it exactly} the same as typing {lisp 85666/}.
}{comment endfootnote}
Only one register at a time can be open, and only open registers can be changed.  To change the contents of a register, the user first opens it, types the new contents, and then closes the register with a {index carriage-return (EDITA command)}carriage-return,{foot
Since carriage-return has a special meaning, EDITA indicates the balancing of parentheses by typing a space.
}{comment endfootnote}
e.g.

{lispcode 7/  CAME 1,'↑    CAMN 1,'↑{CRSYMBOL}}


If the user closes a register without specifying the new contents, the contents are left unchanged.  Similarly, if an error occurs or the user types {index control-E (typed to EDITA)}control-E, the open register, if any, is closed without being changed.

}{End SubSec Overview}



{Begin SubSec Input Protocol}
{Title Input Protocol}
{Text


EDITA processes all inputs not recognized as commands in the same way.
If the input is the name of an instruction (i.e., an atom with a numeric {index OPD Prop}{prop OPD} property), the corresponding number is added to the input value being assembled,{foot
The input value is initially 0.
}{comment endfootnote}
and a flag is set which specifies that the input context is that of an instruction.


The general form of a machine instruction{index machine instructions} is 
{lisp ({arg OPCODE} {arg AC} , @ {arg ADDRESS} ({arg INDEX}))}{index @ (EDITA command)}{index , (EDITA command)} as described on {PageRef Tag LAP}.  Therefore, in instruction context, EDITA evaluates all atoms (if the atom has a {index COREVAL Prop}{prop COREVAL} property, the value of the {lisp COREVAL} is used), and then if the atom corresponds to an {arg AC},{foot
i.e., if a "{lisp ,}" has not been seen, {it and} the value of the atom is less
than 16, {it and} the low 18 bits of the input value are all zero.
}{comment endfootnote}
shifts it left 23 bits and adds it to the input value, otherwise adds it directly to the input value, but performs the arithmetic in the low 18 bits.{foot
If the absolute value of the atom is greater than {lisp 1000000Q}, full word arithmetic is used.  For example, the indirect bit is handled by simply binding {lisp @} to {lisp 20000000Q}.
}{comment endfootnote}
Lists are interpreted as specifying index registers, and the value of {fn CAR} of the list (again {lisp COREVAL}s are permitted) is shifted left 18 bits.
Examples:

{lispcode
PUSH PP, KNIL
HRRZ 1,-10(PP)
CAME 1, 'GO
JRST 33 ORG}

EDITA cannot in general know whether an address field in an instruction that is typed in is relative or absolute.  Therefore, the user must add {lisp ORG}, the origin of the function, to the address field himself.  Note that EDITA would {it print} this instruction, {lisp JRST 53 ORG}, as {lisp JRST 53.}


The user can also specify the address of a literal via the {lisp '}{index ' (EDITA command)} command, see {PageRef (EDITA command) '}.
For example, if the literal {lisp " UNBROKEN"} is in cell 85672, {lisp HRRZ 1,'" UNBROKEN"} is equivalent to {lisp HRRZ 1, 85672}.


When the input context is {it not} that of an instruction, i.e., no {index OPD Prop}{prop OPD} has been seen, all inputs are evaluated (the value of an atom with a {index COREVAL Prop}{prop COREVAL} property is
the {lisp COREVAL}.)
Then numeric values are simply added to the previous input value;
non-numeric values {it become} the input value.{foot
Presumably there is only one input in this case.
}{comment endfootnote}


The only exception to the entire procedure occurs when a register is open that is in the pointer region of the function, i.e., literal table.
In this case, atomic inputs are {it not} evaluated.
For example, the user can change the literal {lisp FOO} to {lisp FIE} by simply opening that register and then typing {lisp FIE} followed by carriage-return, e.g.


{lispcode 'FOO/   FOO     FIE{CRSYMBOL}}

Note that this is equivalent to

{lispcode 'FOO/   FOO     (QUOTE FIE){CRsymbol}}


}{End SubSec Input Protocol}



{Begin SubSec EDITA Commands and Variables}
{Title EDITA Commands and Variables}
{Text


{Begin LabeledList EDITA Commands and Variables}

{Label {lisp {CRsymbol}} (carriage-return)}
{Item
{index *PRIMARY* carriage-return (EDITA command)}If a register is open and an input was typed, store the input in the register and close it.{foot
If the register is in the unboxed region of the function, the
unboxed value is stored in the register.
}{comment endfootnote}

If a register is open and nothing was typed,
close the register without changing it.

If a register is not open and input was typed, type its
value.
}


{Label {lisp ORG}}
{Item
{index ORG Var}Has the value of the address of the first instruction in the function.
i.e., {fn LOC} of {fn GETD} of the function.
}


{Label {lisp /}}
{Item
{index *PRIMARY* / (EDITA command)}Opens the register specified by the low 18 bits of the quantity to the left of the {lisp /}, and types its contents.
If nothing has been typed, it uses the last thing typed by EDITA, e.g.,

{lispcode 35/  JRST 53   /   CAME 1,'RETURN   /   RETURN}

If a register was open, {lisp /} closes it without changing its contents.

After a / command, EDITA returns to that state of no input having been typed.
}


{Label tab (control-I)}
{Item
{index tab (EDITA command)}Same as carriage-return, followed by the address
of the quantity to the left of the tab, e.g.,

{lispcode
35/   JRST 53 <tab>
53/   CAME 1,'RETURN}

Note that if a register was open and input was typed, tab will change the open
register before closing it, e.g.,

{lispcode
35/   JRST 53   JRST 54 TAB
54/   JRST 70   {CRSYMBOL}
35/   JRST 54}
}


{Label {lisp .} (period)}
{Item
{index . Var}Has the value of the address of the current
(last) register examined.
}


{Label line-feed}
{Item
{index line-feed (EDITA command)}Same as carriage-return
followed by {lisp (ADD1 .)/} i.e.
closes any open register and opens the {it next} register.
}


{Label {lisp ↑}}
{Item
{index ↑ (EDITA command)}Same as carriage-return followed by {lisp (SUB1 .)/}
}


{Label {lisp $Q} (<esc>Q)}
{Item
{index $Q (<esc>Q) (EDITA command)}Has as its value the last quantity typed by EDITA e.g.

{lispcode
35/  JRST 53   $Q 1{CRSYMBOL}
./   JRST 54}
}


{Label {lisp LITS}}
{Item
{index LITS Var}Has as value the (relative) address of the
first literal.
}


{Label {lisp BOXED}}
{Item
{index BOXED Var}Same as {lisp LITS}
}


{Label {lisp $} (dollar)}
{Item
{index $ (dollar) Var}Has as value the relative address of the
last literal in the function.
}


{Label {lisp =}}
{Item
{index = (EDITA command)}Sets {fn RADIX} ({PageRef Fn RADIX}) to -8 and types the quantity to the left of the {lisp =} sign, i.e., if anything has been typed, types the input value, otherwise, types {lisp $Q}, e.g.

{lispcode
35/   JRST 54 =254000241541Q
JRST 54=254000000066Q}


Following {lisp =}, {fn RADIX} is restored and EDITA returns
to the no input state.
}


{Label {lisp OK}}
{Item
{index OK (EDITA command)}Exits EDITA.
}


{Label {lisp ?}}
{Item
{index ? (EDITA command)}Returns to "no input" state.
{lisp ?} is a "weak" control-E, i.e., it negates
any input typed, but does not close any registers.
}


{Label {lisp {arg ADDRESS{sub 1}}, {arg ADDRESS{sub 2}}/}}
{Item
Prints the contents of registers {arg ADDRESS{sub 1}} through {arg ADDRESS{sub 2}}.  {lisp .} is set to {arg ADDRESS{sub 2}} after the completion.

Output goes to {index FILE Var}{lisp FILE}, initially set to {lisp T}.  The user can also set {lisp FILE} (while in EDITA) to the name of a disc file to redirect the output.  (The user is responsible for opening and closing {lisp FILE}.)  Note that {lisp FILE} only affects output for the {lisp {arg ADDRESS{sub 1}}, {arg ADDRESS{sub 2}}/} command.
}


{Label {lisp '{arg X}}}
{Item
{index *PRIMARY* ' (EDITA command)}Corresponds to the {lisp '} in LAP.  The next expression is read, and if it is a small number, the appropriate offset is added to it.  Otherwise, the literal table is searched for {arg X}, and the value of {lisp '{arg X}} is the (absolute) address of that cell.
An error is generated if the literal is not found, i.e., {lisp '} cannot be used to
{it create} literals.
}


{Label {lisp :{arg ATOM}}}
{Item
{index : (EDITA command)}Defines {arg ATOM} to an address:  (1)  the value of {lisp $Q} if a register is open,  (2)  the input if any input was typed, otherwise  (3)  the value of "{lisp .}" (Only the low 18 bits are used and converted to a relative address whenever possible).  For example:

{lispcode
35/   JRST 54    :FOO{CRSYMBOL}
:FIE{CRSYMBOL}
FIE/  JRST FOO .=35}
}


{UnIndented
EDITA keeps its symbol tables on two free variables, {index USERSYMS Var}{var USERSYMS} and {index SYMLST Var}{var SYMLST}.  {var USERSYMS} is a list of elements of the form {lisp ({arg NAME} . {arg VALUE})} and is used for {it encoding} input,
i.e., all variables on {var USERSYMS} are bound to their corresponding values during evaluation of any expression inside EDITA.
{var SYMLST} is a list of elements of the form {lisp ({arg VALUE} . {arg NAME})} and is used for {it decoding} addresses.
{var USERSYMS} is initially {lisp NIL}, while {var SYMLST} is set to a list of all the {lisp COREVALS}.
Since the {lisp :} command adds the appropriate information to both these two lists, new definitions will remain in effect even if the user exits from EDITA and then reenters it later.


Note that the user can effectively define symbols without using the {lisp :} command by appropriately binding {index USERSYMS Var}{var USERSYMS} and/or {index SYMLST Var}{var SYMLST} before calling EDITA.
Also, he can thus use different symbol tables for different applications.
}


{Label {lisp $W} (<esc>W)}
{Item
{index *PRIMARY* $W (<esc>W) (EDITA command)}Search command.
}


{UnIndented
Searching consists of comparing the object of the search with the contents of each register, and printing those that match, e.g.,

{lispcode
HRRZ @ $W{CRSYMBOL}
8/   HRRZ 1,@'BRKFILE
23/  HRRZ 1,@-10(PP)
28/ HRRZ 1,@-12(PP)}


The {lisp $W} command can be used to search either the unboxed portion of a function, i.e., instructions, or the pointer region, i.e., literals, depending on whether or not the object of the search is a number.
If any input was typed before the {lisp $W}, it will be the object of the search,
otherwise the next expression is read and used as the object.{foot
Note that inputs typed before the {lisp $W} will have been processed according to the input protocol, i.e., evaluated; inputs typed after the {lisp $W} will not.
Therefore, the latter form is usually used to specify searching the literals, e.g., {lisp $W FOO} is equivalent to {lisp (QUOTE FOO) $W.}
}{comment endfootnote}
The user can specify a starting point for the search by typing an address followed by a "{lisp ,}" before calling {lisp $W}, e.g., {lisp 1, JRST $W}.
If no starting point is specified, the search will begin at 0 if the object is a number, otherwise at {lisp LITS}, the address of the first literal.{foot
Thus the only way the user can search the pointer region for a number is to specify the starting point via "{lisp ,}".
}{comment endfootnote}
After the search is completed, "{lisp .}" is set to the address of the last register that matched.

{index $W (<esc>W) (EDITA command)}If the search is operating in the unboxed portion of the function, only those fields (i.e., {arg INSTRUCTION}, {arg AC}, {arg INDIRECT}, {arg INDEX}, and {arg ADDRESS}) of the object that contain one bits are compared.{foot
Alternately, the user can specify his own mask by setting the variable {index MASK Var}{var MASK} (while in EDITA), to the
appropriate bit pattern.
}{comment endfootnote}
For example, {lisp HRRZ @ $W} will find all instances of {lisp HRRZ} indirect, regardless of {arg AC}, {arg INDEX}, and {arg ADDRESS} fields.
Similarly, {lisp 'PRINT $W} will find all instructions that reference the literal {lisp PRINT}.{foot
The user may need to establish instruction context for input without giving a specific instruction.
For example, suppose the user wants to find all instructions with {arg AC}=1 and {arg INDEX}={lisp PP}.
In this case, the user can give {lisp &} as a pseudo-instruction, e.g., type {lisp & 1, (PP)}.
}{comment endfootnote}


If the search is operating in the pointer region, a "match" is as defined in the editor.  For example, {lisp $W (&)} will find all registers that contain a list consisting of a single expression.
}


{Label {lisp $C} (<esc>C)}
{Item
{index $C (<esc>C) (EDITA command)}Like {lisp $W} except only prints the first match, then prints the number of matches when the search finishes.
}


{End LabeledList EDITA Commands and Variables}


}{End SubSec EDITA Commands and Variables}



{Begin SubSec Editing Arrays}
{Title Editing Arrays}
{Text

{fn EDITA} is called to edit a function by giving it the name of the function.
{fn EDITA} can also be called to edit an array by giving it the array as its first argument,{foot
the array itself, {it not} a variable whose value is an array, e.g., {lisp (EDITA FOO)}, not {lisp (EDITA 'FOO)}.
}{comment endfootnote}
in which case the following differences are to be noted:


1.  decoding - The contents of registers in the unboxed
region are boxed and printed as numbers, i.e., they are
never interpreted as instructions, as when editing a function.

2.  addressing convention - Whereas 0 corresponds to the first
instruction of a function, the first element of an array by
convention is element number 1.

3.  input protocols - If a register is open, lists are evaluated, atoms
are not evaluated (except for {lisp $Q} which is always evaluated).
If no register is open, all inputs are evaluated, and if the value is a number,
it is added to the "input value".

4.  left half - If the left half of an element in the pointer region of an array
is not all 0's or {lisp NIL}, it is printed followed by a "{lisp ;}",{index ; (EDITA command)} e.g.

{lispcode
10/   (A B) ; T}

Similarly, if a register is closed, either its left half, right half, or both halves can be changed, depending on the presence or absence, and position of the "{lisp ;}" e.g.

{lispcode
10/  (A B) ; T    B;{CRSYMBOL}         {it [changes left]}
./   B ; T        NIL{CRSYMBOL}         {it [changes right]}
./   B ; NIL      A ; C{CRSYMBOL}      {it [changes both]}
./   A ; C}


If "{lisp ;}" is used in the unboxed portion of an array, an error will be generated.


The {lisp $W} command will look at both halves of elements in the pointer region, and match if either half matches.
Note that {lisp $W A ; B} is not allowed.{index $W (<esc>W) (EDITA command)}


}{End SubSec Editing Arrays}



{index *END* editing arrays}
{index *END* EDITA}
{index *END* editing compiled code}

}{End SubSec EDITA}