CHAPTER 13 The CMU User Toplevel and the File Package This documentation was written by Don Cohen, and the func- tions described below were imported from PDP-10 CMULisp. _N_o_n _C_M_U _u_s_e_r_s _n_o_t_e: this is not the default top level for your Lisp system. In order to start up this top level, you should type (_l_o_a_d '_c_m_u_e_n_v). 13.1. User Command Input Top Level The top-level is the function that reads what you type, evaluates it and prints the result. The _n_e_w_l_i_s_p top-level was inspired by the CMULisp top-level (which was inspired by interlisp) but is much simpler. The top-level is a function (of zero arguments) that can be called by your program. If you prefer another top-level, just redefine the top-level function and type "(reset)" to start running it. The current top- level simply calls the functions tlread, tleval and tlprint to read, evaluate and print. These are sup- posed to be replaceable by the user. The only one that would make sense to replace is tlprint, which currently uses a function that refuses to go below a certain level and prints "...]" when it finds itself printing a circular list. One might want to pretty- print the results instead. The current top-level numbers the lines that you type to it, and remembers the last n "events" (where n can be set but is defaulted to 25). One can refer to these events in the following "top-level commands": 9 9The CMU User Toplevel and the File Package 13-1 The CMU User Toplevel and the File Package 13-2 ____________________________________________________ _T_O_P_L_E_V_E_L _C_O_M_M_A_N_D _S_U_M_M_A_R_Y ?? prints events - both the input and the result. If you just type "??" you will see all of the recorded events. "?? 3" will show only event 3, and "?? 3 6" will show events 3 through 6. redo pretends that you typed the same thing that was typed before. If you type "redo 3" event number 3 is redone. "redo -3" redoes the thing 3 events ago. "redo" is the same as "redo -1". ed calls the editor and then does whatever the editor returns. Thus if you want to do event 5 again except for some small change, you can type "ed 5", make the change and leave the editor. "ed -3" and "ed" are analogous to redo. ____________________________________________________ Finally, you can get the value of event 7 with the function (valueof 7). The other interesting feature of the top-level is that it makes outermost parentheses superfluous for the most part. This works the same way as in CMULisp, so you can use the help for an explanation. If you're not sure and don't want to risk it you can always just include the parentheses. (top-level) SIDE EFFECT: _t_o_p-_l_e_v_e_l is the LISP top level function. As well as being the top level function with which the user interacts, it can be called recursively by the user or any function. Thus, the top level can be invoked from inside the editor, break package, or a user function to make its commands available to the user. NOTE: The CMU FRANZ LISP top-level uses _l_i_n_e_r_e_a_d rather than _r_e_a_d. The difference will not usu- ally be noticeable. The principal thing to be careful about is that input to the function or system being called cannot appear on the same line as the top-level call. For example, typing (_e_d_i_t_f _f_o_o)_f_P _o_n _o_n_e _l_i_n_e _w_i_l_l _e_d_i_t _f_o_o _a_n_d _e_v_a_l_u_a_t_e _P, _n_o_t _e_d_i_t _f_o_o _a_n_d _e_x_e_c_u_t_e _t_h_e _p _c_o_m_- _m_a_n_d _i_n _t_h_e _e_d_i_t_o_r. _t_o_p-_l_e_v_e_l _s_p_e_c_i_a_l_l_y _r_e_c_o_g_- _n_i_z_e_s _t_h_e _f_o_l_l_o_w_i_n_g _c_o_m_m_a_n_d_s: 9 9 Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-3 (valueof '_g__e_v_e_n_t_s_p_e_c) RETURNS: the value(s) of the event(s) specified by g_eventspec. If a single event is specified, its value will be returned. If more than one event is specified, or an event has more than one subevent (as for _r_e_d_o, etc), a list of vlaues will be returned. 13.2. The File Package Users typically define functions in lisp and then want to save them for the next session. If you do (_c_h_a_n_g_e_s), a list of the functions that are newly defined or changed will be printed. When you type (_d_s_k_o_u_t_s), the functions associated with files will be saved in the new versions of those files. In order to associate functions with files you can either add them to the _f_i_l_e_f_n_s list of an existing file or create a new file to hold them. This is done with the _f_i_l_e function. If you type (_f_i_l_e _n_e_w) the system will create a variable called _n_e_w_f_n_s. You may add the names of the functions to go into that file to _n_e_w_f_n_s. After you do (_c_h_a_n_g_e_s), the functions which are in no other file are stored in the value of the atom _c_h_a_n_g_e_s. To put these all in the new file, (_s_e_t_q _n_e_w_f_n_s (_a_p_p_e_n_d _n_e_w_f_n_s _c_h_a_n_g_e_s)). Now if you do (_c_h_a_n_g_e_s), all of the changed functions should be associated with files. In order to save the changes on the files, do (_d_s_k_o_u_t_s). All of the changed files (such as NEW) will be written. To recover the new functions the next time you run FRANZ LISP, do (_d_s_k_i_n _n_e_w). 9 9 Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-4 ____________________________________________________ Script started on Sat Mar 14 11:50:32 1981 $ newlisp Welcome to newlisp... 1.(defun square (x) (* x x)) ; define a new function square 2.(changes) ; See, this function is associated ; with no file. (square)nil 3.(file 'new) ; So let's declare file NEW. new 4.newfns ; It doesn't have anything on it yet. nil 5.(setq newfns '(square)) ; Add the function associated (square) ; with no file to file NEW. 6.(changes) ; CHANGES magically notices this fact. new (square)nil 7.(dskouts) ; We write the file. creating new (new) 8.(dskin new) ; We read it in! (new) 14.Bye $ script done on Sat Mar 14 11:51:48 1981 ____________________________________________________ (changes s_flag) RETURNS: Changes computes a list containing an entry for each file which defines atoms that have been marked changed. The entry contains the file name and the changed atoms defined therein. There is also a special entry for changes to atoms which are not defined in any known file. The global variable _f_i_l_e_l_s_t con- tains the list of "known" files. If no flag is passed this result is printed in human readable form and the value returned is t if there were any changes and nil if not. Other- wise nothing is printed and the computer list is returned. The global variable _c_h_a_n_g_e_s con- tains the atoms which are marked changed but not yet associated with any file. The _c_h_a_n_g_e_s function attempts to associate these names Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-5 with files, and any that are not found are considered to belong to no file. The _c_h_a_n_g_e_s property is the means by which changed func- tions are associated with files. When a file is read in or written out its _c_h_a_n_g_e_s property is removed. (dc s_word s_id [ g_descriptor1 ... ] ) RETURNS: _d_c defines comments. It is exceptional in that its behavior is very context dependent. When _d_c is executed from _d_s_k_i_n it simply records the fact that the comment exists. It is expected that in interactive mode comments will be found via _g_e_t_d_e_f - this allows large comments which do not take up space in your core image. When _d_c is executed from the ter- minal it expects you to type a comment. _d_s_k_o_u_t will write out the comments that you define and also copy the comments on the old version of the file, so that the new version will keep the old comments even though they were never actually brought into core. The optional id is a mechanism for distinguishing among several comments associated with the same word. It defaults to nil. However if you define two comments with the same id, the second is considered to be a replacement for the first. The behavior of _d_c is determined by the value of the global variable _d_e_f-_c_o_m_m_e_n_t. _d_e_f-_c_o_m_m_e_n_t contains the name of a function that is run. Its arguments are the word, id and attribute list. _d_e_f-_c_o_m_m_e_n_t is initially _d_c-_d_e_f_i_n_e. Other functions rebind it to _d_c- _h_e_l_p, _d_c-_u_s_e_r_h_e_l_p, and the value of _d_s_k_i_n- _c_o_m_m_e_n_t. The comment property of an atom is a list of entries, each representing one com- ment. Atomic entries are assumed to be iden- tifiers of comments on a file but not in core. In-core comments are represented by a list of the id, the attribute list and the comment text. The comment text is an uninterned atom. Comments may be deleted or reordered by edit- ing the comment property. 9 9 Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-6 (dskin l_filenames) SIDE EFFECT: READ-EVAL-PRINTs the contents of the given files. This is the function to use to read files created by _d_s_k_o_u_t. _d_s_k_i_n also declares the files that it reads (if a _f_i_l_e-_f_n_s list is defined and the file is otherwise declarable by _f_i_l_e ), so that changes to it can be recorded. (dskout s_file1 ...) SIDE EFFECT: For each file specified, _d_s_k_o_u_t assumes the list named filenameFNS (i.e., the file name, excluding extension, con- catenated with _f_n_s ) contains a list of function names, etc., to be loaded Any previous version of the file will be renamed to have extension ".back". (dskouts s_file1 ...) SIDE EFFECT: applies _d_s_k_o_u_t to and prints the name of each s_filei (with no additional arguments, assuming filenameFNS to be a list to be loaded) for which s_file_i is either not in _f_i_l_e_l_s_t (meaning it is a new file not previously declared by _f_i_l_e or given as an argument to _d_s_k_i_n, _d_s_k_o_u_t_s, or _d_s_k_o_u_t_s) or is in _f_i_l_e_l_s_t and has some recorded changes to definitions of atoms in filenameFNS, as recorded by _m_a_r_k!_c_h_a_n_g_e_d and noted by changes. If _f_i_l_ei is not specified, _f_i_l_e_l_s_t will be used. This is the most common way of using dskouts. Typing (_d_s_k_o_u_t_s) will save every file reported by (_c_h_a_n_g_e_s) to have changed definitions. (dv s_atom g_value) EQUIVALENT TO: (_s_e_t_q _a_t_o_m '_v_a_l_u_e). _d_v calls _m_a_r_k!_c_h_a_n_g_e_d. 9 9 Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-7 (file 's_file) SIDE EFFECT: declares its argument to be a file to be used for reporting and saving changes to functions by adding the file name to a list of files, _f_i_l_e_l_s_t. _f_i_l_e is called for each file argument of _d_s_k_i_n, _d_s_k_o_u_t, and _d_s_k_o_u_t_s. (file-fns 's_file) RETURNS: the name of the fileFNS list for its file argument s_file. (getdef 's_file ['s_i1 ...]) SIDE EFFECT: selectively executes definitions for atoms s_i1 ... from the specified file. Any of the words to be defined which end with "@" will be treated as patterns in which the @ matchs any suffix (just like the editor). _g_e_t_d_e_f is driven by _g_e_t_d_e_f_t_a_b_l_e (and thus may be programmed). It looks for lines in the file that start with a word in the table. The first character must be a "(" or "[" followed by the word, followed by a space, return or something else that will not be considered as part of the identif- ier by _r_e_a_d, e.g., "(" is unacceptable. When one is found the next word is read. If it matches one of the identifiers in the call to _g_e_t_d_e_f then the table entry is executed. The table entry is a function of the expression starting in this line. Output from _d_s_k_o_u_t is in acceptable format for _g_e_t_d_e_f. _g_e_t_d_e_f RETURNS: a list of the words which match the ones it looked for, for which it found (but, depending on the table, perhaps did not execute) in the file. NOTE: _g_e_t_d_e_f_t_a_b_l_e is the table that drives _g_e_t_d_e_f. It is in the form of an association list. Each ele- ment is a dotted pair consisting of the name of a function for which _g_e_t_d_e_f searches and a function of one argument to be executed when it is found. 9 9 Printed: July 21, 1983 The CMU User Toplevel and the File Package 13-8 (mark!changed 's_f) SIDE EFFECT: records the fact that the definition of s_f has been changed. It is automatically called by _d_e_f, _d_e_f_u_n, _d_e, _d_f, _d_e_f_p_r_o_p, _d_m, _d_v, and the editor when a definition is altered. 9 9 Printed: July 21, 1983