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