1
0
mirror of synced 2026-01-13 15:37:38 +00:00

47 lines
76 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

An Extensible Structured Data Editor for Interlisp-D
Lisp environments are populated by a variety of complex linked data structures, particularly linguistic structures (such as programs written in Lisp and other languages). These are often designed with visual representations (e.g. the pretty-printed form of Lisp code). Through such features as read macros and print definitions, the data structures may be converted to or from a textual representation. In many cases, the only convenient way to edit the structure may be to edit the textual representation and then re-interpret it. This approach suffers from several difficulties:
ÿÿïfÿ ÿÿwriting the structure out and reading it back in will generally create an entirely new structure; this may be aÿ ÿÿproblem if the structure is shared or part of a larger stÿructure
ÿÿïfÿ the requirement that enough information be written out to reconstruct the data when it is read back may conflict with the desire that the presentation be convenient to understand and change
ÿÿïfÿ if the text editor is to provide any assistance (syntax checking, semantic checking, etc.) it must be integrated with the Lisp environment, and continually translating structures to and from their textual representation
ÿÿïfÿ no allowance is made for nontextual graphic presentations
SEdit provides a different approach. Data structures are edited directly, with visual presentations provided as a means of communication. Like WSIWYG text editors, the editing window contains a continuously updated presentation of the data structure, and editing operations are input in terms of this presentation. Presentation and editing rules are defined for each data type, and a kernel program uses these rules to perform the editing.
A set of such rules have been written to configure the editor as a tool for editing Interlisp programs. Interlisp code is pretty-printed in the window, and editing operations use a simple "point and type" user interface. This provides a more convenient way of editing Interlisp than previously existing tools, and furthermore will allow the simple construction of editors for other languages implemented in the Interlisp environment (Prolog, CommonLisp, 3-Lisp, Loops, etc.).
A Sample Session
Before discussing the structure and implementation of SEdit, we will try to give a feel for what it does by a brief description of some simple editing. Of course, it is a little hard to convey the flavour of as interactive a process as editing with just a few words and pictures. This discussion assumes some familiarity with the uniform editing interface which many Interlisp-D programs (and in fact most Xerox software) supports, since that was the model for SEdit's interface. The basic principles are that
ÿÿïfÿ there can be a current insertion point, usually indicated by some sort of caret, at which inserted material appears
ÿÿïfÿ there can be a current selection, usually indicated by underlining or other highlighting, which indicates the material to be affected by a following command (commands may change the selected material, change some aspect of it (such as font or formatting), delete it, etc.)
ÿÿïfÿ the point and selection are usually placed by positioning the mouse and pressing a button; the left or middle button places the point near the cursor and selects the indicated material, while the right button extends a previously made selection to include the indicated material
ÿÿïfÿ material may be selected while holding down a modifier key; instead of becoming the current selection, an action is performed as soon as the key is released. The standard modifiers are Copy, which inserts a copy of the selected material at a previously chosen insertion point; Delete, which deletes the selected material; and Move, which copies the selected material and then deletes it
To SEdit an Interlisp function after SEdit has been loaded, use the usual (DF function). This creates an edit window for the function. Unlike the older display editor (DEdit), DF will return immediately, since the editing is done in a separate process. The function body will be pretty-printed in the window:
`Q©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿŸÿùÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`|Ÿÿ‰?ÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'üùÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ñçà<C3A7>~  xpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`Ì™ÿ92dÏ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ü'Ì™ÿ92dÌ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ'Ì™ÿ92dÉ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'Ì™ÿ92dÉ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ð``œ9 ÌpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÀÀÀÀÀÀ@ÀŒwÏÁÀŒvlc€Á ölc€Á
ž÷ÌfÀÁ
¶lfÀÁ ¶lgÀÁ Û¶ll`À<>ØÙ7ÏÌ`À€À@ÀÀÀÀÀÀ @
8 à
ÀT @
D°"aÀ8±£@
±Ä@ ¡„H
ÀTRdÀ8P$@< à€<C3A0>ÀR$@ùQäO"!ÀR$@R"€"!ÀRdÀDR"€"!ÀQ£@8áøà‡ÇÀÀÀÀÀÀÀÀ ÀÇ<10>ñÀÀ <10> Àß <20> (ÀÌ <20>â ÀÌ <20> ÀÌ <20> ÀÌ <20> ÀÌùñÀ€>ÀÀ` ÀÀÀÀÀÀÀÀß|°À³fÈÀ¿fˆÀ°fˆÀ³fˆÀÙžfˆÀÀÀÀÀÀÀ@À  Dp<00>ÁDà@À  Dˆ"D<>ÀÀÌóÀ DˆXpáÀ"D@<05>Àm` D`"d Dð@AÀíÇà D"DyDˆ@AÀ v Dˆ"D‰"Dˆ@AÀm6` Dˆ"D‰"Dˆ@AÀÍãÀ>8pDxáÀ€8ñðBÀÀ@ÀÀÀÀÀ@ A€À<00>Á<8ùóç<C3B3>|!€À"<10>H"@B!€ÀXpáÀ"<10>H"@`AÀ"d "ñãÇ<C3A3> x<01><00>À"Dy"<10> @À"D‰"<10>ˆ"@À"D‰"<10>H"@ÀDxáÀ€<8<>äO|Â!€À!€À@ A€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€
Since SEdit knows that this is Interlisp code, it uses some formatting rules specific to Lisp as well as its general rules for formatting lists, atoms, and strings. Formatting rules specify visual presentations as the positioning of text strings (in any font) and arbitrary bitmaps.
SEdit allows operations both on complete Lisp objects (such as lists and atoms) and on parts of objects, such as the individual characters in an atom's name. To do this conveniently, it uses the convention that the left mouse button is used to point to parts of structures, while the middle mouse button always points to whole Lisp structures. Thus, left-clicking the Q in LEQ selects that character, but middle-clicking there will select the whole atom (this convention matches TEdit's character/word selection convention). Furthermore, the same convention applies to insertion; a left click between the E and Q will allow inserting more characters, but a middle click will allow inserting a new structure (after the LEQ, since the mouse was closer to the end of the atom than the beginning). SEdit indicates the type of insertion expected by changing the caret, to '@ÀÀààðð<x<xx<x<ð' for a substructure and to '@ÀÀààðð?ø?øüüÿþ' for a structure. Thus, left-clicking the right side of the Q in the above window produces:
`Q©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿŸÿùÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`|Ÿÿ‰?ÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'üùÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ñçà<C3A7>~  xpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`Ì™ÿ92dÏ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ü'Ì™ÿ92dÌ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ'Ì™ÿ92dÉ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'Ì™ÿ92dÉ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ð``œ9 ÌpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÀÀÀÀÀÀ@ÀŒwÏÁÀŒvlc€Á ölc€Á
ž÷ÌfÀÁ
¶lfÀÁ ¶lgÀÁ Û¶ll`À<>ØÙ7ÏÌ`À€À@ÀÀÀÀÀÀ @
8 à
ÀT @
D°"aÀ8±£@
±Ä@ ¡„H
ÀTRdÀ8P$@< à€<C3A0>ÀR$@ùQäO"!ÀR$@R"€"!ÀRdÀDR"€"!ÀQ£@8áøà‡ÇÀÀÀÀÀÀÀÀ ÀÇ<10>ñÀÀ <10> Àß <20> (ÀÌ <20>â ÀÌ <20> ÀÌ <20> ÀÌ <20>(ÀÌùñÜ€>ÀœÀv ÀæÀãÀÀÀÀÀÀß|°À³fÈÀ¿fˆÀ°fˆÀ³fˆÀÙžfˆÀÀÀÀÀÀÀ@À  Dp<00>ÁDà@À  Dˆ"D<>ÀÀÌóÀ DˆXpáÀ"D@<05>Àm` D`"d Dð@AÀíÇà D"DyDˆ@AÀ v Dˆ"D‰"Dˆ@AÀm6` Dˆ"D‰"Dˆ@AÀÍãÀ>8pDxáÀ€8ñðBÀÀ@ÀÀÀÀÀ@ A€À<00>Á<8ùóç<C3B3>|!€À"<10>H"@B!€ÀXpáÀ"<10>H"@`AÀ"d "ñãÇ<C3A3> x<01><00>À"Dy"<10> @À"D‰"<10>ˆ"@À"D‰"<10>H"@ÀDxáÀ€<8<>äO|Â!€À!€À@ A€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€
and any characters now typed would be appended to the atom LEQ. On the other hand, middle-clicking in the same place produces:
`Q©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿŸÿùÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`|Ÿÿ‰?ÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'üùÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ñçà<C3A7>~  xpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`Ì™ÿ92dÏ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ü'Ì™ÿ92dÌ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ'Ì™ÿ92dÉ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'Ì™ÿ92dÉ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ð``œ9 ÌpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÀÀÀÀÀÀ@ÀŒwÏÁÀŒvlc€Á ölc€Á
ž÷ÌfÀÁ
¶lfÀÁ ¶lgÀÁ Û¶ll`À<>ØÙ7ÏÌ`À€À@ÀÀÀÀÀÀ @
8 à
ÀT @
D°"aÀ8±£@
±Ä@ ¡„H
ÀTRdÀ8P$@< à€<C3A0>ÀR$@ùQäO"!ÀR$@R"€"!ÀRdÀDR"€"!ÀQ£@8áøà‡ÇÀÀÀÀÀÀÀÀ ÀÇ<10>ñÀÀ <10> Àß <20> (ÀÌ <20>â ÀÌ <20> ÀÌ <20> ÀÌ <20>!ÀÌùñÈ€>Àƒ€À ÀÿÿçÀÀÿÿïàÀÀÀÀÀÀß|°À³fÈÀ¿fˆÀ°fˆÀ³fˆÀÙžfˆÀÀÀÀÀÀÀ@À  Dp<00>ÁDà@À  Dˆ"D<>ÀÀÌóÀ DˆXpáÀ"D@<05>Àm` D`"d Dð@AÀíÇà D"DyDˆ@AÀ v Dˆ"D‰"Dˆ@AÀm6` Dˆ"D‰"Dˆ@AÀÍãÀ>8pDxáÀ€8ñðBÀÀ@ÀÀÀÀÀ@ A€À<00>Á<8ùóç<C3B3>|!€À"<10>H"@B!€ÀXpáÀ"<10>H"@`AÀ"d "ñãÇ<C3A3> x<01><00>À"Dy"<10> @À"D‰"<10>ˆ"@À"D‰"<10>H"@ÀDxáÀ€<8<>äO|Â!€À!€À@ A€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€
and if characters were inserted they would form a new atom.
Enclosing structures are selected by multiple clicks. In the previous example, if the middle button were clicked twice, the list (LEQ ...) would be selected; if it were clicked thrice, the (if ...) would be selected, etc. Sequences of structures or substructures are selected by extending the current selection with the right mouse button. If the atom LEQ has been selected, right-clicking the 1 would select the sequence of three structures LEQ, n, and 1 (this is not the same as selecting the list which contains these structures). Similarly, the onacc in the middle of fibonacci could be selected by left-clicking at one end of the sequence and right-clicking at the other end.
Some characters activate SEdit commands. For instance, typing a left parenthesis inserts an empty list at the current insertion point and positions the point inside it. Typing a right parenthesis positions the point just after the list immediately enclosing the current point. Typing a blank when inserting within an atom splits the atom at the point (unless the point is at one end of the atom) and switches to structure insertion. This allows Lisp list structures to be typed in as usual. For instance if we continue the above example by typing "(a b " the window will now appear like this:
`Q©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿŸÿùÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`|Ÿÿ‰?ÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'üùÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ñçà<C3A7>~  xpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`Ì™ÿ92dÏ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ü'Ì™ÿ92dÌ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ'Ì™ÿ92dÉ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'Ì™ÿ92dÉ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ð``œ9 ÌpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÀÀÀÀÀÀ@ÀŒwÏÁÀŒvlc€Á ölc€Á
ž÷ÌfÀÁ
¶lfÀÁ ¶lgÀÁ Û¶ll`À<>ØÙ7ÏÌ`À€À@ÀÀÀÀÀÀ @
8 à
ÀT @
D°"aÀ8±£@
±Ä@ ¡„H
ÀTRdÀ8P$@< à€<C3A0>ÀR$@ùQäO"!ÀR$@R"€"!ÀRdÀDR"€"!ÀQ£@8áøà‡ÇÀÀÀÀÀÀÀÀ@ÀÇ<10>ñÀ@ À <10> @ Àß <20> XÀ
ÀÌ <20>â d ÀÌ <20> D ÀÌ <20> D ÀÌ <20> e ÀÌùñÀ[  À À`ÀÀÀàÀÀÀÀÀÀß|°À³fÈÀ¿fˆÀ°fˆÀ³fˆÀÙžfˆÀÀÀÀÀÀÀ@À  Dp<00>ÁDà@À  Dˆ"D<>ÀÀÌóÀ DˆXpáÀ"D@<05>Àm` D`"d Dð@AÀíÇà D"DyDˆ@AÀ v Dˆ"D‰"Dˆ@AÀm6` Dˆ"D‰"Dˆ@AÀÍãÀ>8pDxáÀ€8ñðBÀÀ@ÀÀÀÀÀ@ A€À<00>Á<8ùóç<C3B3>|!€À"<10>H"@B!€ÀXpáÀ"<10>H"@`AÀ"d "ñãÇ<C3A3> x<01><00>À"Dy"<10> @À"D‰"<10>ˆ"@À"D‰"<10>H"@ÀDxáÀ€<8<>äO|Â!€À!€À@ A€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€
(Note that the matching right parenthesis appears as soon as the left parenthesis is typed; this is an immediate consequence of having the window always be a pretty-printed presentation of the underlying list structure. Double quotes work the same way for strings.)
Modified selections allow the easy rearrangement of existing structures. For instance, to switch the order of the two arguments to PLUS, simply
a) middle-click after PLUS (sets the insertion point)
b) hold down the Move key (we are going to move part of the structure to the current insertion point)
c) middle-click on the second fibonacci twice (selects the whole function call)
d) release the Move key (to indicate the selection is completed)
Just before the Move key is released, the window looks like this:
`Q©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿŸÿùÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`|Ÿÿ‰?ÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'üùÿ??ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ñçà<C3A7>~  xpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ø`Ì™ÿ92dÏ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ü'Ì™ÿ92dÌ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ'Ì™ÿ92dÉ3çÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ó'Ì™ÿ92dÉ3&Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ð``œ9 ÌpÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÀÀÀÀÀÀ@ÀŒwÏÁÀŒvlc€Á ölc€Á
ž÷ÌfÀÁ
¶lfÀÁ ¶lgÀÁ Û¶ll`À<>ØÙ7ÏÌ`À€À@ÀÀÀÀÀÀ @
8 à
ÀT @
D°"aÀ8±£@
±Ä@ ¡„H
ÀTRdÀ8P$@< à€<C3A0>ÀR$@ùQäO"!ÀR$@R"€"!ÀRdÀDR"€"!ÀQ£@8áøà‡ÇÀÀÀÀÀÀÀÀ@ÀÇ<10>ñÀ@ À <10> @ Àß <20> XÀ
ÀÌ <20>â d ÀÌ <20> D ÀÌ <20> D ÀÌ <20> d ÀÌùñÀX  À À`@ÀÀÀÀÀÀÀÀß|°À³fÈÀ¿fˆÀ°fˆÀ³fˆÀÙžfˆÀÀÀÀÀÀÀ@À  Dp<00>ÁDà@À  Dˆ"D<>ÀÀÌóÀ DˆXpáÀ"D@<05>Àm` D`"d Dð@AÀíÇà D"DyDˆ@AÀ v Dˆ"D‰"Dˆ@AÀm6` DˆA"D‰"Dˆ@AÀÍãÀ>8pàDxáÀ€8ñðBÀà€Àð@ÀðÀýUUUUUUUUUUUUUUUUUUUUUUUU@ÀÀ@À@ A€À<00>Á<8ùóç<C3B3>|H!€À"<10>H"@B!€ÀXpáÀ"<10>H"@`ADÀ "d "ñãÇ<C3A3> x<01><00>À"Dy"<10> @DÀ "D‰"<10>ˆ"@À"D‰"<10>H"@DÀDxáÀ€<8<>äO|Â!€ÀH!€À@ A€À@À
ªªªªªªªªªªªªªªªªªªªªªªªª€À ÀÀÀÀÀÀàÀÀ
ÀÀÀÀÀÀ`À`À0À0ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€
The selection is highlighted by a dotted outline to indicate that this is a Move selection (Copy selections have a dotted underline, pending-replace selections have a solid outline, and Delete selections are inverted). As soon as the change is made, the window is updated to show the resulting structure (SEdit determines what changes to the presentation result from the editing, and repaints as little of the presentation as possible).
An Overview of the Control Structure
The operations demonstrated above are actually performed by the cooperation of three separate pieces of code: the SEdit kernel, the SEdit user interface, and a set of methods defining the datatypes to be edited. By factoring the control this way, SEdit can be customized to edit new datatypes or provide different commands without having to modify or understand the complexities of the kernel (this is fortunate, since the kernel is quite complicated). The kernel invokes the datatype methods at appropriate times, manages the global sequencing of operations, and handles the optimization and caching necessary to update the screen efficiently. The datatype methods fall into three classes:
ÿÿïfÿ methods for effecting and responding to changes in the structure being edited
ÿÿïfÿ methods for positioning the point and selection appropriately
ÿÿïfÿ methods for generating the visual presentation of the structure
The user interface translates mouse and keyboard events into appropriate calls on the SEdit kernel operations. It is not as modular as I would like; the keyboard event interpreter is table driven and readily extensible, but the mouse event interpreter is not extensible at present.
Each instance of SEdit has a context, which includes the structure being edited and the window in which the editing is being done. Editing operations are performed by calling kernel procedures and passing the context. The context is monitor locked, so operations may be invoked from several processes. Normally, each context has an associated keyboard process which reads keyboard commands and performs them. No editing state is maintained by the keyboard process; it can be deleted and recreated as convenient (but SEdit ensures that there is never more than one keyboard process per context).
SEdit is installed by calling the function (EDITMODE 'SEDIT), whereupon it becomes the system display editor and will be used whenever the user asks to display edit a structure (through edit commands, Masterscope searches, inspectors, browsers, or whatever). The context remains active until the edit window is closed (although the keyboard process disappears while the window is shrunk).
An Overview of the Data Structures
The SEdit user is aware of two data structures: the structure being edited, and the window in which it is presented. Internally, SEdit maintains two additional data structures: the tree, which is a representation of the structure being edited, and the linear form, which is a representation of the visual presentation appearing in the window. The tree provides a common representation for the underlying structures. This allows SEdit to implement a small number of simple editing operations uniformly described as tree mutations, while the type-specific methods map these into the actual changes required. It also caches various bits of information computed by SEdit. The linear form is a sequence of strings, atoms, and bitmaps to be displayed, intermixed with horizontal and vertical positioning information.
These four data structures are all representations of the same data. The constraints between them are maintained as follows:
((SKETCH "figure from {PHYLUM}<MIKEDIXON>SEDIT>INTRO.TEDIT;3" VERSION 3 PRIRANGE (13 . 0)
SKETCHCONTEXT ((ROUND 1 BLACK) (GACHA 10 (MEDIUM REGULAR REGULAR)) (CENTER BASELINE) (CURVE 18.0
8) NIL NIL (CENTER CENTER) (NIL NIL NIL) T NIL NIL 1.0 NIL)) ((.072 60.0 (PRI 3)) (TEXTBOX (
280.0 280.0 120.0 72.0) ("Linear
" "Form") 1.0 (CENTER CENTER) (MODERN 14 (MEDIUM REGULAR REGULAR)) ((320.0 316.0 40 14) (323.5
302.0 33 14)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL))) ((0.0 60.0 (PRI 10)) (WIRE ((280.0 .
312.0) (160.0 . 312.0)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL 1.0 NIL (NIL ((160.0 .
312.0) (167 . 315) (167 . 309))))) ((0.0 60.0 (PRI 9)) (WIRE ((160.0 . 320.0) (280.0 . 320.0
)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL 1.0 NIL (NIL ((280.0 . 320.0) (273 . 317) (
273 . 323))))) ((.05 13.0 (PRI 12)) (TEXT (216.0 . 336.0) ("type methods") 1.0 (CENTER
BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((184.0 332.5 64.0 13.0)) BLACK)) ((0.0 24.0 (
PRI 7)) (WIRE ((336.0 . 232.0) (336.0 . 280.0)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL
1.0 NIL (NIL ((336.0 . 280.0) (339 . 273) (333 . 273))))) ((0.0 24.0 (PRI 8)) (WIRE ((344.0
. 280.0) (344.0 . 232.0)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL 1.0 NIL (NIL ((344.0
. 232.0) (341 . 239) (347 . 239))))) ((.072 60.0 (PRI 3)) (TEXTBOX (40.0 280.0 120.0 72.0)
("Tree") 1.0 (CENTER CENTER) (MODERN 14 (MEDIUM REGULAR REGULAR)) ((85.5 309.0 29 14)) BLACK
(ROUND 1 BLACK) NIL (NIL NIL NIL))) ((.05 13.0 (PRI 12)) (TEXT (152.0 . 256.0) ("type methods"
) 1.0 (CENTER BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((120.0 252.5 64.0 13.0)) BLACK))
((.05 13.0 (PRI 13)) (TEXT (376.0 . 256.0) ("kernel") 1.0 (CENTER BASELINE) (MODERN 10 (
MEDIUM REGULAR REGULAR)) ((360.5 252.5 31.0 13.0)) BLACK)) ((0.0 24.0 (PRI 8)) (WIRE ((104.0
. 280.0) (104.0 . 232.0)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL 1.0 NIL (NIL ((104.0
. 232.0) (101 . 239) (107 . 239))))) ((0.0 24.0 (PRI 7)) (WIRE ((96.0 . 232.0) (96.0 .
280.0)) (ROUND 1 BLACK) (NIL (SOLID 23.0 8.0)) NIL 1.0 NIL (NIL ((96.0 . 280.0) (99 . 273)
(93 . 273))))) ((.072 60.0 (PRI 4)) (TEXTBOX (40.0 160.0 120.0 72.0) ("Structure
" "being
" "edited") 1.0 (CENTER CENTER) (MODERN 14 (MEDIUM REGULAR REGULAR)) ((70.5 203.0 59 14) (81.0
189.0 38 14) (78.5 175.0 43 14)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL))) ((.072 60.0 (PRI 4
)) (TEXTBOX (280.0 160.0 120.0 72.0) ("Presentation
" "in Window") 1.0 (CENTER CENTER) (MODERN 14 (MEDIUM REGULAR REGULAR)) ((299.5 196.0 81 14) (
304.5 182.0 71 14)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL))))
(31.01167 134.3839 394.2912 227.4189)
1.476746
8.0
As an example, consider editing the list structure (if (NULL a) then (QUOTE Done)). The underlying structure is composed of cons cells and atoms:
((SKETCH "figure from {PHYLUM}<MIKEDIXON>SEDIT>INTRO.TEDIT;3" VERSION 3 PRIRANGE (39 . 0)
SKETCHCONTEXT ((ROUND 1 BLACK) (GACHA 10 (MEDIUM REGULAR REGULAR)) (CENTER BASELINE) (CURVE 18.0
8) NIL NIL (CENTER CENTER) (NIL NIL NIL) T NIL NIL 1.0 NIL)) ((0.0 20.0 (PRI 39)) (WIRE ((
32.0 . 352.0) (32.0 . 312.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((
32.0 . 312.0) (29 . 322) (35 . 322))))) ((0.0 16.0 (PRI 31)) (WIRE ((48.0 . 368.0) (48.0 .
336.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL)) ((0.0 20.0 (PRI 32)) (WIRE ((64.0 . 352.0) (
104.0 . 352.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((104.0 . 352.0) (
94 . 349) (94 . 355))))) ((.032 32.0 (PRI 29)) (BOX (16.0 336.0 64.0 32.0) (ROUND 1 BLACK)
NIL 1.0 (NIL NIL NIL))) ((.032 32.0 (PRI 29)) (BOX (104.0 336.0 64.0 32.0) (ROUND 1 BLACK)
NIL 1.0 (NIL NIL NIL))) ((0.0 40.0 (PRI 38)) (WIRE ((120.0 . 352.0) (120.0 . 272.0)) (ROUND
1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((120.0 . 272.0) (117 . 282) (123 . 282)))
)) ((0.0 16.0 (PRI 31)) (WIRE ((136.0 . 368.0) (136.0 . 336.0)) (ROUND 1 BLACK) NIL NIL 1.0
NIL NIL)) ((0.0 20.0 (PRI 32)) (WIRE ((152.0 . 352.0) (192.0 . 352.0)) (ROUND 1 BLACK) (NIL
(LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((192.0 . 352.0) (182 . 349) (182 . 355))))) ((.024 24.0
(PRI 35)) (TEXTBOX (16.0 288.0 48.0 24.0) ("if") 1.0 (CENTER CENTER) (TERMINAL 10 (MEDIUM
REGULAR REGULAR)) ((34.0 293.5 12 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL))) ((.032 32.0 (
PRI 29)) (BOX (192.0 336.0 64.0 32.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((0.0 20.0 (
PRI 39)) (WIRE ((208.0 . 352.0) (208.0 . 312.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL
1.0 NIL (NIL ((208.0 . 312.0) (205 . 322) (211 . 322))))) ((0.0 16.0 (PRI 31)) (WIRE ((
224.0 . 368.0) (224.0 . 336.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL)) ((.024 24.0 (PRI 35)) (
TEXTBOX (192.0 288.0 48.0 24.0) ("then") 1.0 (CENTER CENTER) (TERMINAL 10 (MEDIUM REGULAR
REGULAR)) ((204.0 293.5 24 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL))) ((0.0 20.0 (PRI 32))
(WIRE ((240.0 . 352.0) (280.0 . 352.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL
(NIL ((280.0 . 352.0) (270 . 349) (270 . 355))))) ((0.0 20.0 (PRI 39)) (WIRE ((120.0 .
256.0) (120.0 . 216.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((120.0 .
216.0) (117 . 226) (123 . 226))))) ((0.0 20.0 (PRI 32)) (WIRE ((152.0 . 256.0) (192.0 .
256.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((192.0 . 256.0) (182 . 253)
(182 . 259))))) ((0.0 20.0 (PRI 39)) (WIRE ((208.0 . 256.0) (208.0 . 216.0)) (ROUND 1 BLACK
) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((208.0 . 216.0) (205 . 226) (211 . 226))))) ((
0.0 16.0 (PRI 31)) (WIRE ((136.0 . 272.0) (136.0 . 240.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL
NIL)) ((.032 32.0 (PRI 29)) (BOX (104.0 240.0 64.0 32.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL
NIL))) ((0.0 16.0 (PRI 31)) (WIRE ((224.0 . 272.0) (224.0 . 240.0)) (ROUND 1 BLACK) NIL NIL
1.0 NIL NIL)) ((0.0 16.0 (PRI 33)) (WIRE ((224.0 . 272.0) (256.0 . 240.0)) (ROUND 1 BLACK)
NIL NIL 1.0 NIL NIL)) ((.032 32.0 (PRI 29)) (BOX (192.0 240.0 64.0 32.0) (ROUND 1 BLACK) NIL
1.0 (NIL NIL NIL))) ((.032 32.0 (PRI 29)) (BOX (280.0 280.0 64.0 32.0) (ROUND 1 BLACK) NIL
1.0 (NIL NIL NIL))) ((0.0 20.0 (PRI 39)) (WIRE ((296.0 . 296.0) (296.0 . 256.0)) (ROUND 1
BLACK) (NIL (LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((296.0 . 256.0) (293 . 266) (299 . 266)))))
((0.0 16.0 (PRI 31)) (WIRE ((312.0 . 312.0) (312.0 . 280.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL
NIL)) ((.032 32.0 (PRI 29)) (BOX (280.0 336.0 64.0 32.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL
NIL))) ((0.0 20.0 (PRI 39)) (WIRE ((296.0 . 352.0) (296.0 . 312.0)) (ROUND 1 BLACK) (NIL (
LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((296.0 . 312.0) (293 . 322) (299 . 322))))) ((0.0 16.0 (
PRI 31)) (WIRE ((312.0 . 368.0) (312.0 . 336.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL)) ((0.0
16.0 (PRI 33)) (WIRE ((312.0 . 368.0) (344.0 . 336.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL))
((.024 24.0 (PRI 35)) (TEXTBOX (104.0 192.0 48.0 24.0) ("NULL") 1.0 (CENTER CENTER) (
TERMINAL 10 (MEDIUM REGULAR REGULAR)) ((116.0 197.5 24 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL
NIL))) ((.024 24.0 (PRI 35)) (TEXTBOX (192.0 192.0 48.0 24.0) ("a") 1.0 (CENTER CENTER) (
TERMINAL 10 (MEDIUM REGULAR REGULAR)) ((213.0 197.5 6 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL NIL
))) ((.024 24.0 (PRI 35)) (TEXTBOX (280.0 232.0 48.0 24.0) ("QUOTE") 1.0 (CENTER CENTER) (
TERMINAL 10 (MEDIUM REGULAR REGULAR)) ((289.0 237.5 30 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL
NIL))) ((.024 24.0 (PRI 35)) (TEXTBOX (368.0 232.0 48.0 24.0) ("Done") 1.0 (CENTER CENTER)
(TERMINAL 10 (MEDIUM REGULAR REGULAR)) ((380.0 237.5 24 13)) BLACK (ROUND 1 BLACK) NIL (NIL NIL
NIL))) ((0.0 20.0 (PRI 32)) (WIRE ((328.0 . 296.0) (368.0 . 296.0)) (ROUND 1 BLACK) (NIL (
LINE 18.0 10.0)) NIL 1.0 NIL (NIL ((368.0 . 296.0) (358 . 293) (358 . 299))))) ((0.0 20.0 (
PRI 39)) (WIRE ((384.0 . 296.0) (384.0 . 256.0)) (ROUND 1 BLACK) (NIL (LINE 18.0 10.0)) NIL
1.0 NIL (NIL ((384.0 . 256.0) (381 . 266) (387 . 266))))) ((0.0 16.0 (PRI 31)) (WIRE ((
400.0 . 312.0) (400.0 . 280.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL)) ((0.0 16.0 (PRI 33)) (
WIRE ((400.0 . 312.0) (432.0 . 280.0)) (ROUND 1 BLACK) NIL NIL 1.0 NIL NIL)) ((.032 32.0 (PRI
29)) (BOX (368.0 280.0 64.0 32.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))))
(14.5 189.95 421.95 182.7)
1.45
8.0
SEdit's tree will look like this:
((SKETCH "figure from {PHYLUM}<MIKEDIXON>SEDIT>INTRO.TEDIT;3" VERSION 3 PRIRANGE (59 . 0)
SKETCHCONTEXT ((ROUND 1 BLACK) (GACHA 10 (MEDIUM REGULAR REGULAR)) (CENTER BASELINE) (CURVE 18.0
8) NIL NIL (CENTER CENTER) (NIL NIL NIL) T NIL NIL 1.0 NIL)) ((0.0 76.0 (PRI 44)) (WIRE ((
232.0 . 360.0) (80.0 . 336.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0)) NIL 1.0 NIL (NIL ((
80.0 . 336.0) ((84 . 337) (87 . 340)) ((84 . 336) (88 . 335)))))) ((.04 52.0 (PRI 36)) (BOX
(24.0 296.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 12.0 (PRI 37)) (TEXT
(32.0 . 320.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((32.0 317.0
26.0 12.0)) BLACK)) ((.05 13.0 (PRI 39)) (TEXT (64.0 . 320.0) ("litatom") 1.0 (LEFT BASELINE
) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((64.0 316.5 35.0 13.0)) BLACK)) ((.05 12.0 (PRI 51))
(TEXT (144.0 . 320.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((
144.0 317.0 26.0 12.0)) BLACK)) ((.05 13.0 (PRI 55)) (TEXT (176.0 . 320.0) ("form") 1.0 (
LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((176.0 316.5 23.0 13.0)) BLACK)) ((0.0
24.0 (PRI 58)) (WIRE ((240.0 . 360.0) (192.0 . 336.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0
)) NIL 1.0 NIL (NIL ((192.0 . 336.0) ((195 . 338) (198 . 342)) ((196 . 337) (200 . 337))))))
((.04 52.0 (PRI 36)) (BOX (192.0 360.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL)))
((.05 12.0 (PRI 38)) (TEXT (200.0 . 368.0) ("structure:") 1.0 (LEFT BASELINE) (MODERN 10 (
BOLD REGULAR REGULAR)) ((200.0 365.0 46.0 12.0)) BLACK)) ((.05 12.0 (PRI 37)) (TEXT (200.0 .
384.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((200.0 381.0 26.0
12.0)) BLACK)) ((.05 12.0 (PRI 38)) (TEXT (32.0 . 304.0) ("structure:") 1.0 (LEFT BASELINE)
(MODERN 10 (BOLD REGULAR REGULAR)) ((32.0 301.0 46.0 12.0)) BLACK)) ((.05 13.0 (PRI 40)) (
TEXT (88.0 . 304.0) ("if") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((88.0
300.5 7.0 13.0)) BLACK)) ((.05 12.0 (PRI 53)) (TEXT (144.0 . 304.0) ("structure:") 1.0 (
LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((144.0 301.0 46.0 12.0)) BLACK)) ((.05 13.0
(PRI 57)) (TEXT (200.0 . 304.0) ("(NULL a)") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR
REGULAR)) ((200.0 300.5 38.0 13.0)) BLACK)) ((.04 52.0 (PRI 49)) (BOX (136.0 296.0 104.0
40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 39)) (TEXT (232.0 . 384.0) (
"CLisp") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((232.0 380.5 24.0 13.0))
BLACK)) ((.04 52.0 (PRI 48)) (BOX (248.0 296.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL
NIL))) ((.05 12.0 (PRI 52)) (TEXT (256.0 . 304.0) ("structure:") 1.0 (LEFT BASELINE) (
MODERN 10 (BOLD REGULAR REGULAR)) ((256.0 301.0 46.0 12.0)) BLACK)) ((.05 12.0 (PRI 50)) (
TEXT (256.0 . 320.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((256.0
317.0 26.0 12.0)) BLACK)) ((.05 13.0 (PRI 54)) (TEXT (288.0 . 320.0) ("litatom") 1.0 (LEFT
BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((288.0 316.5 35.0 13.0)) BLACK)) ((0.0 24.0
(PRI 59)) (WIRE ((248.0 . 360.0) (296.0 . 336.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0)) NIL
1.0 NIL (NIL ((296.0 . 336.0) ((292 . 337) (288 . 337)) ((293 . 338) (290 . 342)))))) ((0.0
76.0 (PRI 43)) (WIRE ((256.0 . 360.0) (408.0 . 336.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0
8.0)) NIL 1.0 NIL (NIL ((408.0 . 336.0) ((404 . 336) (400 . 335)) ((404 . 337) (401 . 340)))))
) ((.05 13.0 (PRI 40)) (TEXT (256.0 . 368.0) ("(if ...)") 1.0 (LEFT BASELINE) (MODERN 10 (
MEDIUM REGULAR REGULAR)) ((256.0 364.5 24.0 13.0)) BLACK)) ((.05 12.0 (PRI 37)) (TEXT (368.0
. 256.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((368.0 253.0 26.0
12.0)) BLACK)) ((.04 52.0 (PRI 36)) (BOX (360.0 296.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0
(NIL NIL NIL))) ((.05 13.0 (PRI 56)) (TEXT (312.0 . 304.0) ("then") 1.0 (LEFT BASELINE) (
MODERN 10 (MEDIUM REGULAR REGULAR)) ((312.0 300.5 22.0 13.0)) BLACK)) ((.05 12.0 (PRI 38)) (
TEXT (368.0 . 304.0) ("structure:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((
368.0 301.0 46.0 12.0)) BLACK)) ((.05 12.0 (PRI 37)) (TEXT (368.0 . 320.0) ("type:") 1.0 (
LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((368.0 317.0 26.0 12.0)) BLACK)) ((.05 12.0
(PRI 38)) (TEXT (368.0 . 240.0) ("structure:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR
REGULAR)) ((368.0 237.0 46.0 12.0)) BLACK)) ((.05 13.0 (PRI 40)) (TEXT (424.0 . 240.0) (
"Done") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((424.0 236.5 25.0 13.0))
BLACK)) ((.05 13.0 (PRI 39)) (TEXT (400.0 . 256.0) ("litatom") 1.0 (LEFT BASELINE) (MODERN
10 (MEDIUM REGULAR REGULAR)) ((400.0 252.5 35.0 13.0)) BLACK)) ((.04 52.0 (PRI 36)) (BOX (
360.0 232.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((0.0 12.0 (PRI 47)) (WIRE
((416.0 . 296.0) (416.0 . 272.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0)) NIL 1.0 NIL (NIL (
(416.0 . 272.0) ((415 . 276) (414 . 280)) ((417 . 276) (418 . 280)))))) ((.05 13.0 (PRI 40))
(TEXT (424.0 . 304.0) ("'Done") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((
424.0 300.5 28.0 13.0)) BLACK)) ((.05 13.0 (PRI 39)) (TEXT (400.0 . 320.0) ("quote") 1.0 (
LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((400.0 316.5 28.0 13.0)) BLACK)) ((.04
52.0 (PRI 48)) (BOX (192.0 232.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.04
52.0 (PRI 49)) (BOX (80.0 232.0 104.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05
12.0 (PRI 50)) (TEXT (200.0 . 256.0) ("type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR
REGULAR)) ((200.0 253.0 26.0 12.0)) BLACK)) ((.05 12.0 (PRI 51)) (TEXT (88.0 . 256.0) (
"type:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((88.0 253.0 26.0 12.0)) BLACK
)) ((.05 12.0 (PRI 52)) (TEXT (200.0 . 240.0) ("structure:") 1.0 (LEFT BASELINE) (MODERN 10
(BOLD REGULAR REGULAR)) ((200.0 237.0 46.0 12.0)) BLACK)) ((.05 12.0 (PRI 53)) (TEXT (88.0
. 240.0) ("structure:") 1.0 (LEFT BASELINE) (MODERN 10 (BOLD REGULAR REGULAR)) ((88.0 237.0
46.0 12.0)) BLACK)) ((.05 13.0 (PRI 54)) (TEXT (232.0 . 256.0) ("litatom") 1.0 (LEFT
BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((232.0 252.5 35.0 13.0)) BLACK)) ((.05 13.0 (
PRI 55)) (TEXT (120.0 . 256.0) ("litatom") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR
REGULAR)) ((120.0 252.5 35.0 13.0)) BLACK)) ((.05 13.0 (PRI 56)) (TEXT (256.0 . 240.0) ("a"
) 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((256.0 236.5 6.0 13.0)) BLACK)) (
(.05 13.0 (PRI 57)) (TEXT (144.0 . 240.0) ("NULL") 1.0 (LEFT BASELINE) (MODERN 10 (MEDIUM
REGULAR REGULAR)) ((144.0 236.5 24.0 13.0)) BLACK)) ((0.0 24.0 (PRI 58)) (WIRE ((184.0 .
296.0) (136.0 . 272.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0)) NIL 1.0 NIL (NIL ((136.0 .
272.0) ((139 . 274) (142 . 278)) ((140 . 273) (144 . 273)))))) ((0.0 24.0 (PRI 59)) (WIRE ((
192.0 . 296.0) (240.0 . 272.0)) (ROUND 1 BLACK) (NIL (CURVE 18.0 8.0)) NIL 1.0 NIL (NIL ((
240.0 . 272.0) ((236 . 273) (232 . 273)) ((237 . 274) (234 . 278)))))))
(-1.0 215.0 498.0 194.0)
1.0
8.0
Note that each node in the tree has a type, indicating the type of the structure, and a field containing the structure itself. Note also that the types need not correspond directly with Interlisp's type structure: in this example, many cons cells are grouped together as one node in the tree, and may be marked as type list, CLisp (a class of special form), form, quote, binding, etc. depending on the components of the structure and its position in the surrounding structure. Thus, the list (QUOTE Done) is classified as type quote above (and has one subnode), but would have been type binding (with two subnodes) had it appeared in a list as the second element of a form identified as a LET or PROG.
The linear form will be something like:
((SKETCH NIL VERSION 3 PRIRANGE (22 . 0) SKETCHCONTEXT ((ROUND 1 BLACK) (GACHA 10 (MEDIUM REGULAR
REGULAR)) (CENTER BASELINE) (CURVE 18.0 8) NIL NIL (CENTER CENTER) (NIL NIL NIL) T NIL NIL 1.0
NIL)) ((.05 13.0 (PRI 14)) (TEXT (32.0 . 368.0) ("%"(%", default font") 1.0 (LEFT CENTER) (
MODERN 10 (MEDIUM REGULAR REGULAR)) ((32.0 361.5 77.0 13.0)) BLACK)) ((.05 13.0 (PRI 12)) (
TEXT (56.0 . 352.0) ("%"if%", keyword font") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR
REGULAR)) ((56.0 345.5 87.0 13.0)) BLACK)) ((.016 52.0 (PRI 15)) (BOX (48.0 344.0 104.0
16.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 13)) (TEXT (32.0 . 336.0) (
"skip 7 points") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((32.0 329.5 58.0 13.0
)) BLACK)) ((.05 13.0 (PRI 14)) (TEXT (56.0 . 320.0) ("%"(%", default font") 1.0 (LEFT CENTER
) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((56.0 313.5 77.0 13.0)) BLACK)) ((.05 13.0 (PRI 14))
(TEXT (80.0 . 304.0) ("%"NULL%", default font") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR
REGULAR)) ((80.0 297.5 98.0 13.0)) BLACK)) ((.016 56.0 (PRI 16)) (BOX (72.0 296.0 112.0
16.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 13)) (TEXT (56.0 . 288.0) (
"skip 7 points") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((56.0 281.5 58.0 13.0
)) BLACK)) ((.05 13.0 (PRI 14)) (TEXT (80.0 . 272.0) ("%"a%", default font") 1.0 (LEFT CENTER
) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((80.0 265.5 80.0 13.0)) BLACK)) ((.016 48.0 (PRI 17))
(BOX (72.0 264.0 96.0 16.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 13))
(TEXT (32.0 . 240.0) ("new line, indent 20 points") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM
REGULAR REGULAR)) ((32.0 233.5 121.0 13.0)) BLACK)) ((.08 72.0 (PRI 21)) (BOX (48.0 248.0
144.0 80.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 14)) (TEXT (56.0 . 256.0
) ("%")%", default font") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((56.0 249.5
77.0 13.0)) BLACK)) ((.05 13.0 (PRI 13)) (TEXT (32.0 . 208.0) ("skip 7 points") 1.0 (LEFT
CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((32.0 201.5 58.0 13.0)) BLACK)) ((.016 60.0 (
PRI 18)) (BOX (48.0 216.0 120.0 16.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (
PRI 12)) (TEXT (56.0 . 224.0) ("%"then%", keyword font") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM
REGULAR REGULAR)) ((56.0 217.5 102.0 13.0)) BLACK)) ((.04 72.0 (PRI 20)) (BOX (48.0 160.0
144.0 40.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 12)) (TEXT (80.0 . 176.0
) ("%"Done%", default font") 1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((80.0
169.5 99.0 13.0)) BLACK)) ((.016 56.0 (PRI 19)) (BOX (72.0 168.0 112.0 16.0) (ROUND 1 BLACK
) NIL 1.0 (NIL NIL NIL))) ((.05 13.0 (PRI 12)) (TEXT (56.0 . 192.0) ("%"'%", default font")
1.0 (LEFT CENTER) (MODERN 10 (MEDIUM REGULAR REGULAR)) ((56.0 185.5 77.0 13.0)) BLACK)) ((.05
13.0 (PRI 14)) (TEXT (32.0 . 152.0) ("%")%", default font") 1.0 (LEFT CENTER) (MODERN 10 (
MEDIUM REGULAR REGULAR)) ((32.0 145.5 77.0 13.0)) BLACK)) ((.176 116.0 (PRI 22)) (BOX (24.0
144.0 176.0 232.0) (ROUND 1 BLACK) NIL 1.0 (NIL NIL NIL))))
(23.0 143.0 178.0 234.0)
1.0
8.0
Note that although the linear form is a sequence (hence its name), it reflects the structure of the tree from which it was generated. Finally, the window will show some or all of the presentation described by the linear form:
9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀ @À#B$H À 0C$H ÀC|ƒ$H8ÀC0¤HÀC0¤H<ÀC0dHDÀC0dHDÀ#0B#<23>Ÿ< À @ À @ÀÀÀÀÀ À`‡€À `„@À|yðGÀ ˜H™"À ˜H>À ˜H À ˜H"Àfy˜ÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
SEdit has two other important data structures. The context was mentioned before; it includes the data structures mentioned above, information such as the current selection and current insertion point, and all the other little bits of state SEdit needs to keep track of what is going on. The environment contains all of the customization information which controls SEdit's behaviour: the tables which drive the generation of the tree from the original data structure, the table for interpreting keyboard events, parameters such as default spacing and fonts, etc. At present, there is just one environment defined ÿÿï% the one which configures SEdit sÿpecifically for editing Interlisp code, but by creating new environments the user could have SEdit contexts for editing Prolog, CommonLoops, etc., all coexisting.
(Actually, there is a second environment defined, which tricks SEdit into pretty-printing Interlisp code into a TEdit document (to produce the listings later in this document), but it hardly qualifies as an edit environment.)
Documentation
The rest of the documentation for SEdit is in five sections:
ÿÿïfÿ a more detailed account of how to use SEdit to edit Interlisp code
ÿÿïfÿ a description of how SEdit is configured for editing a new type
ÿÿïfÿ a detailed description of SEdit's internals
ÿÿïfÿ an annotated listing of the code which implements the basic Interlisp types
ÿÿïfÿ an annotated listing of SEdit's kernel
The first of these is independent of the others, but the second should be read before attempting to understand any of the following sections. If you are planning to extend SEdit to edit your own language (or change the way it currently edits one), you should also look at the third of these ÿÿï%ÿ a few good examples are sure to convey what the specifications missed.
Other Comments
The formatting and incremental reformatting algorithms, the incremental window update algorithms, and the various data structures were all developed by the author, so there are no references for them. Although there are several extensible prettyprinters for Lisp environments (notably Waters' GPRINT), some do not allow a sufficiently general class of presentations, most only deal with formatting lines of fixed width characters, and none deal with the (crucial) problem of incremental reformatting.
At present, SEdit is usable but far from polished. There is still room for improvement in the screen updating, and many rather desirable commands are still missing (notably undo and redo). Extra formatting rules for CommonLoops are a high priority, as is completing the interface to other Interlisp tools (e.g. the file package). Finally, the author hates the name SEdit, and promises three free features of their choice to the first person who comes up with one he likes better.(LIST ((PAGE NIL (PAPERSIZE NIL) (0 0 612 792) ((TEXT NIL NIL (72 72 468 648) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC - -)) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC - -)) (162 24 288 36) NIL) (TEXT NIL NIL (72 72 468 648) NIL))) (PAGE NIL (PAPERSIZE Letter FOLIOINFO (ARABIC - -)) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO (ARABIC - -)) (162 24 288 36) NIL) (TEXT NIL NIL (72 72 468 648) NIL))))))ÔT.*¼*(Ô
(Ô.*¼
*(Ô(Ô
CLASSICCLASSIC
TERMINAL
CLASSICCLASSIC CLASSIC
4Iãu
Áß=$ÞNñ¾Y,9Já BMOBJ.GETFN3CLASSIC
rçj( BMOBJ.GETFN3( BMOBJ.GETFN3> BMOBJ.GETFN3CLASSIC
;B BMOBJ.GETFN3CLASSIC
<4<00>'/
R d)( BMOBJ.GETFN3CLASSIC
  Q ).. BMOBJ.GETFN3CLASSIC
L Z÷%·QAC4+J"¸C (~ + SKIO.GETFN.2CLASSIC
3A' SKIO.GETFN.2CLASSIC
"< SKIO.GETFN.2CLASSIC
As 7_(
 SKIO.GETFN.2CLASSIC
㜠BMOBJ.GETFN3CLASSIC
& 8G¥¼=FC/O*$J&Ê®' 4&zº