Commit | Line | Data |
---|---|---|
1c9c8e44 C |
1 | ." $Header: /na/franz/doc/RCS/ch13.n,v 1.1 83/01/31 07:08:37 jkf Exp $ |
2 | .Lc The\ CMU\ User\ Toplevel\ and\ the\ File\ Package 13 | |
3 | .ch 2 Introduction | |
4 | This documentation was written by Don Cohen, and the functions described below | |
5 | were imported from PDP-10 CMULisp. | |
6 | .sp 1v | |
7 | \fINon CMU users note:\fP this is not the default top level for your Lisp | |
8 | system. In order to start up this top level, you should type | |
9 | \fI(load\ 'cmuenv)\fP. | |
10 | ||
11 | .sh 2 User\ Command\ Input\ Top\ Level 13 | |
12 | ||
13 | The top-level is the function that reads what you type, evaluates it | |
14 | and prints the result. The \fInewlisp\fP top-level was inspired by the | |
15 | CMULisp top-level (which was inspired by interlisp) but is much | |
16 | simpler. The top-level is a function (of zero arguments) that can be | |
17 | called by your program. If you prefer another top-level, just redefine | |
18 | the top-level function and type "(reset)" to start running it. The | |
19 | current top-level simply calls the functions tlread, tleval and tlprint | |
20 | to read, evaluate and print. These are supposed to be replaceable by | |
21 | the user. The only one that would make sense to replace is tlprint, | |
22 | which currently uses a function that refuses to go below a certain | |
23 | level and prints "...]" when it finds itself printing a circular list. | |
24 | One might want to prettyprint the results instead. The current | |
25 | top-level numbers the lines that you type to it, and remembers the last | |
26 | n "events" (where n can be set but is defaulted to 25). One can refer | |
27 | to these events in the following "top-level commands": | |
28 | .Eb | |
29 | \fITOPLEVEL COMMAND SUMMARY\fP | |
30 | ||
31 | ?? prints events - both the input and the result. If you just type | |
32 | "??" you will see all of the recorded events. "?? 3" will show | |
33 | only event 3, and "?? 3 6" will show events 3 through 6. | |
34 | ||
35 | redo pretends that you typed the same thing that was typed before. If | |
36 | you type "redo 3" event number 3 is redone. "redo -3" redoes the | |
37 | thing 3 events ago. "redo" is the same as "redo -1". | |
38 | ||
39 | ed calls the editor and then does whatever the editor returns. Thus | |
40 | if you want to do event 5 again except for some small change, you | |
41 | can type "ed 5", make the change and leave the editor. "ed -3" | |
42 | and "ed" are analogous to redo. | |
43 | .Ee | |
44 | Finally, you can get the value of event 7 with the function (valueof 7). | |
45 | The other interesting feature of the top-level is that it makes outermost | |
46 | parentheses superfluous for the most part. This works the same way as in | |
47 | CMULisp, so you can use the help for an explanation. If you're not sure | |
48 | and don't want to risk it you can always just include the parentheses. | |
49 | ||
50 | .Lf top-level | |
51 | .Se | |
52 | .i top-level | |
53 | is the LISP top level function. As well | |
54 | as being the top level function with which the user | |
55 | interacts, it can be called recursively by the user or | |
56 | any function. Thus, the top level can be invoked from | |
57 | inside the editor, break package, or a user function to | |
58 | make its commands available to the user. | |
59 | .No | |
60 | The CMU | |
61 | .Fr | |
62 | top-level uses | |
63 | .i lineread | |
64 | rather than | |
65 | .i read. | |
66 | The difference will not usually be noticeable. The principal thing to be | |
67 | careful about is that input to the function or system being called | |
68 | cannot appear on the same line as the top-level call. For example, | |
69 | typing \fI(editf foo)fP on one line will edit | |
70 | .i foo | |
71 | and evaluate P, not edit | |
72 | .i foo | |
73 | and execute the p command in the editor. | |
74 | .i top-level | |
75 | specially recognizes the following commands: | |
76 | ||
77 | .Lf valueof "'g_eventspec" | |
78 | .Re | |
79 | the value(s) of the event(s) specified by g_eventspec. If a single | |
80 | event is specified, its value will be returned. If more than one event | |
81 | is specified, or an event has more than one subevent (as for | |
82 | .i redo, | |
83 | etc), a list of vlaues will be returned. | |
84 | ||
85 | .sh 2 The\ File\ Package | |
86 | ||
87 | Users typically define functions in lisp and then want to save them for | |
88 | the next session. If you do \fI(changes)\fP, a list of the functions that are | |
89 | newly defined or changed will be printed. When you type \fI(dskouts)\fP, the | |
90 | functions associated with files will be saved in the new versions of | |
91 | those files. In order to associate functions with files you can either | |
92 | add them to the \fIfilefns\fP list of an existing file or create a new file to | |
93 | hold them. This is done with the | |
94 | .i file | |
95 | function. If you type \fI(file new)\fP | |
96 | the system will create a variable called | |
97 | .i newfns. | |
98 | You may add the names of the functions to go into that file to | |
99 | .i newfns. | |
100 | After you do \fI(changes)\fP, | |
101 | the functions which are in no other file are stored in the value of the | |
102 | atom | |
103 | .i changes. | |
104 | To put these all in the new file, \fI(setq newfns (append newfns changes))\fP. | |
105 | Now if you do \fI(changes)\fP, all of the changed functions | |
106 | should be associated with files. In order to save the changes on the | |
107 | files, do \fI(dskouts)\fP. All of the changed files (such as NEW) will be | |
108 | written. To recover the new functions the next time you run | |
109 | .Fr , | |
110 | do \fI(dskin new)\fP. | |
111 | .Eb | |
112 | Script started on Sat Mar 14 11:50:32 1981 | |
113 | $ newlisp | |
114 | Welcome to newlisp... | |
115 | 1.(defun square (x) (* x x)) ; define a new function | |
116 | square | |
117 | 2.(changes) ; See, this function is associated | |
118 | ; with no file. | |
119 | <no-file> (square)nil | |
120 | 3.(file 'new) ; So let's declare file NEW. | |
121 | new | |
122 | 4.newfns ; It doesn't have anything on it yet. | |
123 | nil | |
124 | 5.(setq newfns '(square)) ; Add the function associated | |
125 | (square) ; with no file to file NEW. | |
126 | 6.(changes) ; CHANGES magically notices this fact. | |
127 | ||
128 | new (square)nil | |
129 | 7.(dskouts) ; We write the file. | |
130 | creating new | |
131 | (new) | |
132 | 8.(dskin new) ; We read it in! | |
133 | (new) | |
134 | 14.Bye | |
135 | $ | |
136 | script done on Sat Mar 14 11:51:48 1981 | |
137 | ||
138 | .Ee | |
139 | ||
140 | .Lf changes "s_flag" | |
141 | .Re | |
142 | Changes computes a list containing an entry for each file which | |
143 | defines atoms that have been marked changed. The entry contains the | |
144 | file name and the changed atoms defined therein. There is also a | |
145 | special entry for changes to atoms which are not defined in any known | |
146 | file. The global variable | |
147 | .i filelst | |
148 | contains the list of "known" files. If no flag is passed this result | |
149 | is printed in human readable form and the value returned is t if there | |
150 | were any changes and nil if not. Otherwise nothing is printed and the | |
151 | computer list is returned. The global variable | |
152 | .i changes | |
153 | contains the atoms which are marked changed but not yet associated | |
154 | with any file. The | |
155 | .i changes | |
156 | function attempts to associate these names with files, and any that are not | |
157 | found are considered to belong to no file. The | |
158 | .i changes | |
159 | property is the means by which changed functions are associated with | |
160 | files. When a file is read in or written out its | |
161 | .i changes | |
162 | property is removed. | |
163 | .Lf dc "s_word s_id [ g_descriptor1 ... ] <text> <esc>" | |
164 | .Re | |
165 | .i dc | |
166 | defines comments. It is exceptional in that its behavior is very | |
167 | context dependent. When | |
168 | .i dc | |
169 | is executed from | |
170 | .i dskin | |
171 | it simply records the | |
172 | fact that the comment exists. It is expected that in interactive mode | |
173 | comments will be found via | |
174 | .i getdef | |
175 | - this allows large | |
176 | comments which do not take up space in your core image. When | |
177 | .i dc | |
178 | is executed from the terminal it expects you to type a comment. | |
179 | .i dskout | |
180 | will write out the comments that you define and also copy the comments on the | |
181 | old version of the file, so that the new version will keep the old comments | |
182 | even though they were never actually brought into core. | |
183 | The optional id is a mechanism for distinguishing among several | |
184 | comments associated with the same word. It defaults to nil. However | |
185 | if you define two comments with the same id, the second is considered | |
186 | to be a replacement for the first. | |
187 | The behavior of | |
188 | .i dc | |
189 | is determined by the value of the global variable | |
190 | .i def-comment. | |
191 | .i def-comment | |
192 | contains the name of a function that is run. | |
193 | Its arguments are the word, id and attribute list. | |
194 | .i def-comment | |
195 | is initially | |
196 | .i dc-define. | |
197 | Other functions rebind it to | |
198 | .i dc-help, | |
199 | .i dc-userhelp, | |
200 | and the value of | |
201 | .i dskin-comment. | |
202 | The comment property of an atom is a list of entries, each representing | |
203 | one comment. Atomic entries are assumed to be identifiers of comments on | |
204 | a file but not in core. In-core comments are represented by a list of the | |
205 | id, the attribute list and the comment text. The comment text is an | |
206 | uninterned atom. Comments may be deleted or reordered by editing the | |
207 | comment property. | |
208 | ||
209 | .Lf dskin "l_filenames" | |
210 | .Se | |
211 | READ-EVAL-PRINTs the contents of the given files. This | |
212 | is the function to use to read files created by | |
213 | .i dskout. | |
214 | .i dskin | |
215 | also declares the files that it reads (if a | |
216 | .i file-fns | |
217 | list is defined and the file is otherwise declarable by | |
218 | .i file | |
219 | ), so that changes to it can be recorded. | |
220 | ||
221 | .Lf dskout "s_file1 ..." | |
222 | .Se | |
223 | For each file specified, | |
224 | .i dskout | |
225 | assumes the list named | |
226 | filenameFNS (i.e., the file name, excluding extension, | |
227 | concatenated with | |
228 | .i fns | |
229 | ) contains a list of function | |
230 | names, etc., to be loaded | |
231 | Any previous version of the file will be renamed to have extension | |
232 | ".back". | |
233 | .Lf dskouts "s_file1 ..." | |
234 | .Se | |
235 | applies | |
236 | .i dskout | |
237 | to and prints the name of each | |
238 | s_filei (with no additional arguments, assuming | |
239 | filenameFNS to be a list to be loaded) for which s_file\fIi\fP | |
240 | is either not in \fIfilelst\fP (meaning it is a new file not | |
241 | previously declared by \fIfile\fP or given as an argument to | |
242 | \fIdskin\fP, \fIdskouts\fP, or \fIdskouts\fP) or is in \fIfilelst\fP and has some | |
243 | recorded changes to definitions of atoms in filenameFNS, | |
244 | as recorded by \fImark!changed\fP and noted by changes. | |
245 | If \fIfile\fPi is not specified, \fIfilelst\fP will be | |
246 | used. This is the most common way of using dskouts. | |
247 | Typing \fI(dskouts)\fP will save every file reported by | |
248 | \fI(changes)\fP to have changed definitions. | |
249 | ||
250 | .Lf dv "s_atom g_value" | |
251 | .Eq | |
252 | \fI(setq atom 'value)\fP. | |
253 | .i dv | |
254 | calls | |
255 | .i mark!changed. | |
256 | .Lf file "'s_file" | |
257 | .Se | |
258 | declares its argument to be a file to be used for reporting and saving | |
259 | changes to functions by adding the file name to a list of files, | |
260 | .i filelst. | |
261 | .i file | |
262 | is called for each file argument of | |
263 | .i dskin, | |
264 | .i dskout, | |
265 | and | |
266 | .i dskouts. | |
267 | .Lf file-fns "'s_file" | |
268 | .Re | |
269 | the name of the fileFNS list for its file argument s_file. | |
270 | .Lf getdef "'s_file ['s_i1 ...]" | |
271 | .Se | |
272 | selectively executes definitions for atoms s_i1 ... from the | |
273 | specified file. Any of the words to be defined which end with "@" | |
274 | will be treated as patterns in which the @ matchs any suffix | |
275 | (just like the editor). | |
276 | .i getdef | |
277 | is driven by | |
278 | .i getdeftable | |
279 | (and thus may be programmed). It looks for lines in the file that start | |
280 | with a word in the table. The first character must be a "(" or "[" | |
281 | followed by the word, followed by a space, return or something else that will | |
282 | not be considered as part of the identifier by | |
283 | .i read, | |
284 | e.g., "(" is unacceptable. When one is found the next word is read. If | |
285 | it matches one of the identifiers in the call to | |
286 | .i getdef | |
287 | then the table entry is executed. The table entry is a function of the | |
288 | expression starting in this line. Output from | |
289 | .i dskout | |
290 | is in acceptable format for | |
291 | .i getdef. | |
292 | .i getdef | |
293 | .Re | |
294 | a list of the words which match the ones it looked for, for which it found | |
295 | (but, depending on the table, perhaps did not execute) in the file. | |
296 | .No | |
297 | .i getdeftable | |
298 | is the table that drives | |
299 | .i getdef. | |
300 | It is in the form of an association list. Each element is a dotted pair | |
301 | consisting of the name of a function for which | |
302 | .i getdef | |
303 | searches and a function of one argument to be executed when it is found. | |
304 | .Lf mark!changed "'s_f" | |
305 | .Se | |
306 | records the fact that the definition of s_f has been changed. It is | |
307 | automatically called by | |
308 | .i def, | |
309 | .i defun, | |
310 | .i de, | |
311 | .i df, | |
312 | .i defprop, | |
313 | .i dm, | |
314 | .i dv, | |
315 | and the editor when a definition is altered. | |
316 | ||
317 | ||
318 |