$A START=1 $A TAB=4,8,12,16,20,24,28,50,66; INDENT=8 $B3 $L1ICU DRAFT $B20 $L1CM THE E.C.S.D LISP MANUAL $B29 $L3I .N. .H. @SHELNESS @DECEMBER, 1976 $N $A INDENT=0; JUST=1; PAGENO=1 $L1CU 1.0 INTRODUCTION $P2 @THIS MANUAL IS A BRIEF INTRODUCTION TO THE @EDINBURGH @COMPUTER @SCIENCE @DEPARTMENT .(ECSD) .LISP .SYSTEM RUNNING ON .EMAS. @IT IS NOT INTENDED AS AN INTRODUCTION TO .LISP. @THERE ARE A NUMBER OF REFERENCES LISTED IN THE BIBLIOGRAPHY THAT WILL FULFILL THAT FUNCTION. $P1 .ECSD .LISP WAS IMPLEMENTED BY THE AUTHOR FOR UNDERGRADUATE STUDENT USE, AND ITS STRUCTURE REFLECTS THIS FACT. @IT IS A RELATIVELY 'PURE' IMPLEMENTATION IN WHICH FUNCTIONS ARE DEFINED OVER MORE LIMITED DOMAINS THAN IS OFTEN THE CASE, AND IN WHICH EXTENSIVE ERROR CHECKING ENFORCES THESE LIMITATIONS. (IE. .CAR AND .CDR ARE ONLY DEFINED OVER .LISTS, AND WILL RESULT IN AN ERROR IF APPLIED TO .ATOMS.). $P @IT WAS THE AUTHOR'S INITIAL INTENT THAT THIS SYSTEM WOULD RAPIDLY BE SUPERCEDED BY THE .UPSALLA .INTERLISP SYSTEM, WHEN THE LATER BECAME AVAILABLE ON .EMAS. @THIS HAS NOT YET BEEN POSSIBLE. @DESPITE THIS FACT, THE AUTHOR HAS NO DESIRE TO RECODE THE INTERPRETER IN ASSEMBLER, NOR TO FLATTEN ITS PROCEDURAL STRUCTURE, THOUGH SUCH CHANGES MIGHT WELL RESULT IN A FOURFOLD PERFORMANCE IMPROVEMENT. @INSTEAD A STUDY HAS BEEN MADE OF THE PERFORMANCE OF CERTAIN ALGORITHMS IN THE INTERPRETER, AND A NUMBER OF CHANGES HAVE BEEN EFFECTED TO REDUCE SEARCH TIMES AND IMPROVE PAGING BEHAVIOUR. @THE LATER HAVE TURNED THE INTERPRETER INTO A VIABLE VECHICLE FOR THE SOLUTION OF SMALL TO MEDIUM SCALE PROBLEMS, BUT NOT FOR LARGE ONES. @FOR LARGE PROBLEMS THE USER WILL HAVE TO WAIT FOR A SUITABLE RELEASE OF THE .UPSALLA .INTERLISP SYSTEM. $P @THE STRUCTURE OF THIS MANUAL OWES A GREAT DEAL TO THE .LISP .F1 USERS MANUAL []. @THE AUTHOR WISHES TO EXTEND HIS GRATITUDE TO THE AUTHORS OF THAT MANUAL FOR PROVIDING SUCH A GOOD EXAMPLE FROM WHICH HE COULD BEGIN. $N $L1CU 2.0 ACCESS $P2 @THE .ECSD .LISP .SYSTEM IS CONTAINED IN THE LIBRARY .ECSC09.LISPLIB AND IS ENTERED VIA THE COMMAND .LISP WHICH TAKES A SINGLE ARGUMENT OF THE FORM '/FILENAME' OR 'FILENAME'. $P @WHEN THE FILENAME IS PRECEDED BY A SLASH, A .LISP .MEMORY .FILE OF THAT NAME IS CREATED AND INITIALIZED BY THE LISP INTERPRETER PRIOR TO ENTERING THE TOP LEVEL LOOP. @IF A FILE OF THAT NAME EXISTS PRIOR TO THE CALL, IT IS FIRST DELETED. $P @WHEN THE FILENAME IS NOT PRECEDED BY A SLASH, THE SYSTEM ASSUMES THAT A .LISP .MEMORY .FILE OF THAT NAME ALLREADY EXISTS, AND THE INTERPRETER WILL ENTER THE TOP LEVEL LOOP WITHOUT ALTERING IT. @IF SUCH A FILE DOES NOT EXIST AN ERROR IS INDICATED. $P @ALL .ATOMS, PROPERTIES, GLOBAL BINDINGS, AND .LISTS ARE HELD IN THE .LISP .MEMORY .FILE. @THIS ELIMINATES THE NEED FOR DUMPING AND LOADING THE CONTENTS OF THE .LISP .MEMORY BETWEEN SESSIONS, AND REDUCES THE CHANCE OF INFORMATION LOSS DUE TO CRASHES. $A INDENT=1 $B $L1IU EXAMPLES $A INDENT=2 $B $I1 .COMMAND:APPENDLIB(ECSC09.LISPLIB) $B $I2 @THIS COMMAND ENTERS THE .ECSD .LISP .SYSTEM INTO YOUR COMMAND LIBRARY. @IT NEED ONLY BE ISSUED ONCE. $B $I1 .COMMAND:LISP(/LISPMEMY) $B $I2 @CALLS THE LISP INTERPRETER, WHICH WILL DESTROY THE FILE .LISPMEMY IF IT EXISTS, AND CREATE AND INITIALIZE A .LISP .MEMORY .FILE CALLED .LISPMEMY BEFORE ENTERING THE TOP LEVEL LOOP. $B $I1 .COMMAND:LISP(LISPFILE) $B $I2 @CALLS THE LISP INTERPRETER, WHICH WILL CHECK THAT THE FILE .LISPFILE EXISTS AND IS A .LISP .MEMORY .FILE, PRIOR TO ENTERING THE TOP LEVEL LOOP. $A INDENT=0 $N $B2 $L1CU 3.1 LISP OBJECTS $P2 @ONLY THREE TYPES OF .LISP .OBJECT EXIST IN THE .ECSC .LISP .SYSTEM. @THESE ARE .NUMERIC .ATOMS, .SYMBOLIC .ATOMS, AND .LIST .CELLS. $P .NUMERIC .ATOMS ARE THE ONLY OBJECTS TO WHICH NUMERIC FUNCTIONS MAY BE APPLIED, AND HENCE ON WHICH ARITHMETIC CAN BE PERFORMED. .NUMERIC .ATOMS CARRY A CONSTANT BINDING TO THEMSELVES AND DO NOT POSSESS A .PROPERTY .LIST. @IN THE .ECSD .LISP .SYSTEM, .NUMERIC .ATOMS MAY ONLY REPRESENT INTEGER VALUES. @THERE ARE NO FLOATING POINT FORMS. $P .SYMBOLIC .ATOMS ARE ATOMIC OBJECTS WHICH ARE NOT .NUMERIC .ATOMS. @THEY MAY CARRY EITHER CONSTANT OR VARIABLE BINDINGS TO ANY .LISP .OBJECT, AND IN ADDITION POSSES A .PROPERTY .LIST. @THE .PRINTNAME OF A .SYMBOLIC .ATOM MAY BE ANY STRING OF .ISO CHARACTERS WITH MAXIMUM LENGTH 255. $P .LIST .CELLS ARE 2-TUPLES OF THE FORM {'CAR', 'CDR'}, WHERE BOTH 'CAR' AND 'CDR' MAY BE ANY .LISP .OBJECT. $P @THERE ARE TWO MECHANISMS WHICH THE .LISP .INTERPRETER PROVIDES FOR THE CREATION OF NEW .LISP .OBJECTS. @THESE ARE THE GENERATOR FUNCTIONS SUCH AS .CONS, .PACKLIST, .GENSYM AND .LIST WHICH MANIPULTATE THEIR ARGUMENTS (IE. ALLREADY EXISTENT .LISP .OBJECTS) SO AS TO CREATE NEW .LISP .OBJECTS, AND INPUT FUNCTIONS SUCH AS .READCH AND .READ WHICH ALLOW THE USER TO SPECIFY NEW .LISP .OBJECTS OR STRUCTURES OF .LISP .OBJECTS FROM OUTWITH THE .INTERPRETER. $B2 $L1CU 3.2 NOTATION $P2 @THE .LISP .OBJECTS DESCRIBED IN THE PREVIOUS SECTION ONLY EXIST AS OBJECTS WITHIN THE .LISP .INTERPRETER ITSELF. @IF WE ARE TO MANIPULATE THESE OBJECTS, WE NEED A NOTATION BY WHICH WE CAN REFER TO THEM. @WE NEED A NOTATION IN WHICH THE INTERPRETER CAN PRINT RESULTS, AND IN WHICH WE CAN ENTER INFORMATION INTO THE SYSTEM. $P @VERSIONS OF STANDARD .LISP .S-NOTATION ARE USED WITH SLIGHT VARIATION FOR INPUT AND OUTPUT. @IN DESCRIBING THIS NOTATION, WE NEED TO RECOGNIZE FIVE CLASSES OF CHARACTERS. @THESE ARE 'BREAK' CHARACTERS, 'ESCAPE' CHARACTERS, 'DIGITS', 'SIGN' CHARACTERS AND 'OTHER' CHARACTERS, WHERE THE LATTER CONTAINS ALL THOSE .ISO CHARACTERS THAT DO NOT FALL INTO THE OTHER FOUR CLASSES, OR ANY .ISO CHARACTER THAT ON INPUT IS PRECEDED BY AN 'ESCAPE' CHARACTER. @THIS PRECEDING 'ESCAPE' CHARACTER IS NOT INCLUDED IN THE INTERNAL REPRESENTATION, AND IS NOT NORMALLY PRINTED. $B $I1 'BREAK' CHARACTERS: $T7 '(', ')', '[', ']', '$.', ' ', ''', '$@' $I7 AND ANY CONTROL CHARACTER .(ISO 0-31 DECIMAL). $B $I1 'ESCAPE' CHARACTERS: $T7 '$$$', '/'. $B $I1 'DIGITS': $T7 '0' - '9' $B $I1 'SIGN' CHARACTERS: $T7 '-', '+' $P @ALL .ATOMS ARE DELIMITED BY, BUT DO NOT INCLUDE, 'BREAK' CHARACTERS. @A .NUMERIC .ATOM CONSISTS OF A STRING OF DIGITS, WHICH MAY OPTIONALLY BE PRECEDED BY A SINGLE 'SIGN' CHARACTER. @A .SYMBOLIC .ATOM IS REPRESENTED BY A STRING OF 'DIGITS', 'SIGN' AND 'OTHER' CHARACTERS INCLUDING AT LEAST ONE NON-'DIGIT'. $P .LIST .CELLS ARE REPRESENTED IN ONE OF TWO NOTATIONS: AS A .DOTTED .PAIR '(' .LISP .OBJECT '.' .LISP .OBJECT ')' OR AS A .LIST '(' .LISP .OBJECT ' ' .LISP .OBJECT ' ' .LISP .OBJECT ' ' $.$.$. ')'. @WE MAY USE THE LATTER NOTATION WHEN THE RIGHT HAND .LISP .OBJECT OF A .DOTTED .PAIR IS ITSELF A .DOTTED .PAIR OR A .LIST. @IN SUCH CASES WE MAY REMOVE THE PARENTHESES '(' AND ')' FROM THE RIGHT HAND .LISP .OBJECT AND REPLACE THE DOT '.' OF THE .DOTTED .PAIR BY A SPACE ' ' OR ANY OTHER .ISO CONTROL CHARACTER. $B $I1 IE. .(A $. .(A $. .B)) BECOMES .(A @B $. .C) $P2 @BY AN ADDITIONAL CONVENTION, THE SYMBOLIC ATOM .NIL IS USED TO REPRESENT THE EMPTY .LIST '()'. @THERFORE IF THE RIGHT HAND OBJECT OF A .DOTTED .PAIR IS .NIL, WE MAY DROP BOTH THE DOT '.' AND THE .NIL. $B $I1 IE. .(A $. .(B $. .NIL)) BECOMES .(A .B) $P2 @EITHER NOTATION MAY BE USED WHEN INPUTING .S-EXPRESSIONS, BUT THE INTERPRETER WILL ALWAYS PRINT RESULTS IN .LIST NOTATION WHERE POSSIBLE. $P2 @THERE ARE TWO OTHER NOTATIONAL DETAILS THAT WE NEED TO COVER. @THEY ONLY HAVE EFFECT ON INPUT. @AS AN .S-EXPRESSION MAY CONTAIN MANY PARENTHESES WE MAY USE A RIGHT HAND SQUARE BRACKET ']' AS A ALIAS FOR A STRING OF RIGHT PARENTHESES SUCH THAT THE OUTERMOST RIGHT PARENTHESIS IN THE STRING WILL MATCH THE INNERMOST LEFT SQUARE BRACKET '['. @IF THERE IS NO LEFT SQUARE BRACKET THEN THE OUTERMOST RIGHT PARENTHESIS MATCHES THE OUTERMOST LEFT PARENTHESIS, AND THUS CLOSES THE .S-EXPRESSION. $B $I1 IE. .(A .[A .(B.(C]) AND .(A .(A .(B .(C] BOTH BECOME .(A .(A .(B .(C)))) $P2 @AS IT IS OFTEN NECCESSARY TO .'QUOTE' .S-EXPRESSIONS, TWO BREAK CHARACTERS ''' AND '$@' ARE PROVIDED AS ABREVIATIONS. @THE PRESENSE OF EITHER CHARACTER PRIOR TO AN .S-EXPRESSION WILL CAUSE THE .S-EXPRESSION TO BE ENCLOSED IN A LIST OF WHICH THE FIRST ELEMENT IS THE ATOM .QUOTE AND THE SECOND ELEMENT IS THE .S-EXPRESSION ITSELF. $B $I1 IE. .'A BECOMES .(QUOTE .A) WHILE .'(A @B .C) BECOMES .(QUOTE .(A @B .C)) $A INDENT=7 $V16 $B $L1U EXAMPLES $B $I1 .NUMERIC .ATOMS: $B $I2 1 100 -1 -123 $B $I1 .SYMBOLIC .ATOMS: $B $I2 @A ABC .A/( 1$$000 $T7 .NOTE: @THE LATTER TWO ARE IN INPUT NOTATION AND WILL PRINT AS .A( AND 1000. $B $I1 .DOTTED .PAIRS AND .LISTS: $B $I2 .(A $. B) .(A @B .C) .(A '(B $. C] $A INDENT=0 $B2 $L1CU 3.3 BINDINGS $P2 @IN A PREVIOUS SECTION, WE INDICATED THAT ATOMS COULD POSSESS VALUES IN THE FORM OF BINDINGS. @THERE ARE THREE SORTS OF BINDINGS THAT AN ATOM IN THE .ECSD .LISP SYSTEM MAY POSSESS: @A CONSTANT BINDING, @A NUMBER OF LOCAL BINDINGS, AND @A GLOBAL BINDING, IN THAT ORDER OF PRIORITY. @A NUMERIC ATOM POSSESSES A SINGLE CONSTANT BINDING TO ITSELF, WHILE A SYMBOLIC ATOM MAY POSSES ALL THREE. $P @SYMBOLIC ATOMS ARE GIVEN CONSTANT BINDINGS WHEN THEY HAVE A SINGLE CONSTANT USE. @NORMALLY, THE ATOMS: .NIL, .T, $%, AND .STOP ALL POSSES CONSTANT BINDINGS TO THEMSELVES. @IF THE USER WISHES TO GIVE OTHER ATOMS CONSTANT BINDINGS, HE MAY DO SO USING THE FUNCTION .CSET, WHICH ACHIEVES ITS EFFECT BY PLACING THE VALUE SPECIFIED IN THE CALL ON THE PROPERTY LIST OF A NOMINATED ATOM UNDER THE PROPERTY .APVAL. @AS A CONSTANT BINDING HAS PRECEDENCE OVER ANY OTHER FORM OF BINDING, AN ATTEMPT TO CREATE EITHER A GLOBAL OR LOCAL BINDING FOR AN ATOM THAT ALLREADY POSSESSES A CONSTANT BINDING WILL RESULT IN A WARNING MESSAGE BEING PRINTED BY THE .LISP INTERPRETER. $P @LOCAL BINDINGS ARE CREATED BY THE .LISP INTERPRETER IN TWO CIRCUMSTANCES: UPON ENTRY TO A .PROG AND WHEN APPLYING A .LAMBDA EXPRESSION. @IN THE FIRST CASE, .NIL IS BOUND TO EACH ELEMENT OF THE .PROG VARIABLE LIST. @IN THE SECOND CASE ELEMENTS OF THE ACTUAL ARGUMENT LIST ARE BOUND TO THE APPROPRIATE .LAMBDA VARIABLES. @THIS BINDING MAY TAKE ONE OF THREE FORMS DEPENDING ON THE FIRST ARGUMENT OF THE .LAMBDA EXPRESSION. @IF THE FIRST ARGUMENT IS A SINGLE SYMBOLIC ATOM, THE ENTIRE ACTUAL ARGUMENT LIST IS BOUND TO IT. @IF IT IS A SIMPLE LIST OF SYMBOLIC ATOMS, SUCCESSIVE ELEMENTS OF THE ACTUAL ARGUMENT LIST ARE BOUND TO EACH SUCCESSIVE ELEMENT OF IT. @IF IT IS A LIST OF SYMBOLIC ATOMS ENDING IN A DOTTED ATOM, SUCCESSIVE ELEMENTS OF THE ACTUAL ARGUMENT LIST ARE BOUND AS IN THE PREVIOUS CASE, WITH WHATEVER REMAINS OF THE ACTUAL ARGUMENT LIST BEING BOUND TO THE DOTTED ATOM $A INDENT=2 $B $I1 IE. CONSIDER THE ARGUMENT LIST (1 2 3 4) $B $I2 @GIVEN THE .LAMBDA EXPRESSION .(LAMBDA .(A @B @C .D) $.$.$.) $I2 1 WILL BE BOUND TO .A, 2 TO .B, 3 TO @C AND 4 TO .D. $B $I2 @GIVEN THE .LAMBDA EXPRESSION .(MBDA ( @B $. .C) $.$.$.) $I2 1 WILL BE BOUND TO .A, 2 TO @B AND THE LIST (3 4) TO .C. $B $I2 @GIVEN THE .LAMBDA EXPRESSION .(LAMBDA @A $.$.$.) $I2 THE LIST (1 2 3 4) WILL BE BOUND TO .A. $A INDENT=0 $P2 @ALL LOCAL BINDINGS THAT ARE CREATED ON ENTRY TO A .PROG OR AS PART OF THE APPLICATION OF A .LAMBDA EXPRESSION ARE DELETED UPON EXIT FROM THE .PROG, OR COMPLETION OF THE APPLICATION. $P @A GLOBAL BINDING IS CREATED BY THE INTERPRETER WHENEVER THE FUNCTION .SET IS APPLIED TO A SYMBOLIC ATOM THAT DOES NOT POSSES A BINDING. @IF A LOCAL BINDING EXISTS, NO GLOBAL BINDING IS CREATED, INSTEAD THE LOCAL BINDING IS ALTERED TO TAKE THE NEW VALUE. $V20 $B $L1U EXAMPLES $B $L0C LISP:(DE TEST(A) (PROGN (PRINC A) (SETQ A '(A B C)) (PRINC A) (TERPRI] TEST $P @WE DEFINE A SIMPLE FUNCTION WHICH PRINTS THE INITIAL VALUE OF .A, GIVES @A A NEW BINDING .(A @B .C), AND THEN PRINTS THE NEW VALUE. $B $L0C LISP:A EVAL ERROR: A ATOM IS NOT BOUND TO A VALUE $%:(RESET) LISP:(TEST 3) 3(A B C) NIL $P @A HAS NO GLOBAL BINDING AS CAN BE SEEN FROM THE ATTEMPT TO EVALUATE IT AT THE TOP LEVEL. @THE APPLICATION OF THE FUNCTION .TEST CAUSES THE VALUE 3 TO BE BOUND TO @A AS A LOCAL BINDING. @IT IS THIS VALUE THAT IS PRINTED BY THE FIRST CALL ON .PRINC. @THE BINDING OF @A IS THEN ALTERED TO THE LIST .(A @B .C). @IT IS THIS NEW BINDING THAT IS PRINTED BY THE SECOND CALL ON .PRINC. .TERPRI TERMINATES THE PRINT LINE AND RETURNS .NIL. $B $L0C LISP:(EDITF TEST) EDIT:(R 2 (B)) P (LAMBDA (B) (PROGN (*** ***) (*** *** ***) (*** ***) (***))) EDIT:$%C END OF EDITF $P @HERE WE HAVE ALTERED THE DEFINITION OF .TEST. @NOW WHEN .TEST IS APPLIED, THE ACTUAL ARGUMENT WILL BE BOUND TO .B. $B $L0C LISP:(TEST 3) EVAL ERROR: A ATOM IS NOT BOUND TO A VALUE $%:$% EVAL:3 3(A B C) NIL LISP:A (A B C) $P @WE AGAIN EVALUATE .(TEST 3), BUT THIS TIME @A HAS NO LOCAL BINDING. @AS IT ALSO HAS NO GLOBAL BINDING AN ERROR OCCURS. @THE ATOM 3 IS RETURNED FROM THE .BREAK, AND IS PRINTED. @THIS TIME THE CALL ON .SETQ ESTABLISHES A GLOBAL BINDING OF THE LIST .(A @B .C) TO .A. @AS A GLOBAL BINDING HAS BEEN ESTABLISHED, THE BINDING IS RETAINED AT THE TOP LEVEL. $N $L1CU 3.4.1 PROPERTIES $P2 @IN ADDITION TO ITS POSSIBLE BINDINGS, EACH SYMBOLIC ATOM IN THE .ECSC .LISP SYSTEM POSSESSES A LIST OF 2-TUPLES OF THE FORM .{KEY, .LISP .OBJECT}. @THIS LIST IS CALLED THE .PROPERTY .LIST. @IT FUNCTIONS AS A CONTENT ADDRESSABLE STORE ASSOCIATED WITH EACH SYMBOLIC ATOM. @IN IT VALUES ARE STORED, RETRIEVED, AND REMOVED VIA THEIR .KEY, WHICH MUST BE A SYMBOLIC ATOM. $P @IN SOME .LISP SYSTEMS, THE PROPERTY LIST MAY BE ACCESSED AS THE .CDR OF THE SYMBOLIC ATOM. @IN .ECSD .LISP THIS IS NOT ALLOWED. PROPERTY LISTS MAY ONLY BE MANIPULATED USING THE BUILT IN SET OF .LISP FUNCTIONS: .PUTPROP, .DEFPROP, .GETPROP, .REMPROP AND .PROP. $B2 $L1CU 3.4.2 KNOWN PROPERTIES $P2 @IT HAS ALLREADY BEEN NOTED THAT A NUMBER OF SYMBOLIC ATOMS .(NIL FOR EXAMPLE) PERFORM A SPECIAL ROLE IN THE .LISP INTERPRETER. @THE SAME IS TRUE OF A NUMBER OF @K@E@YS THAT MAY APPEAR ON THE .PROPERTY .LIST OF A SYMBOLIC ATOM. $P @THE KEY .APVAL IS USED TO IDENTIFY A CONSTANT BINDING, WHILE THE KEYS .SUBR, .FSUBR, .EXPR AND .FEXPR ARE USED TO IDENTIFY FUNCTION DEFINITIONS. @IT IS POSSIBLE FOR A NUMBER OF FUNCTION DEFINITIONS TO APPEAR ON THE PROPERTY LIST OF A SYMBOLIC ATOM AT THE SAME TIME UNDER DIFFERENT KEYS, YET A SYMBOLIC ATOM CAN HAVE ONLY ONE CURRENT FUNCTION DEFINITION. @BY CONVENTION IN .ECSD .LISP, THE LAST FUNCTION DEFINITION TO BE .PUT ONTO THE PROPERTY LIST OF AN ATOM WILL BE TREATED AS THE CURRENT FUNCTION DEFINITION. @IF THE ACTIVE FUNCTION DEFINITION IS SUBSEQUENTLY REMOVED FROM THE PROPERTY LIST, THE SYMBOLIC ATOM WILL THEN POSSESS NO FUNCTION DEFINITION, DESPITE THE FACT THAT A NUMBER OF FUNCTION DEFINITIONS MAY STILL EXIST ON ITS PROPERTY LIST UNDER DIFFERENT KEYS. $N $L1CU 3.5 THE INTERPRETER $P2 @A .LISP INTERPRETER CONSISTS OF AN EXTENSIBLE NUMBER OF .LISP FUNCTIONS CALLED FROM THE SINGLE ROOT FUNCTION .EVAL, WHICH TAKES AS ITS ARGUMENT A SINGLE .S-EXPRESSION. $P @THE .ECSD .LISP INTERPRETER IS WRITTEN IN .IMP. @IN IT .EVAL HAS THE FOLLOWING SIMPLIFIED FORM. $A UND=0 $B2 $L0 %INTEGERFN EVAL(%INTEGER FORM) %RECORDNAME CELL(LISP CELL) %RECORDNAME ATOM(ATOM CELL) %INTEGER CAR, CDR ! NOTE: THE CELL ATOM_FUNC CONTAINS THE IDENTITY OF THE CURRENT ! FUNCTION DEFINITION OR CONSTANT BINDING ASSOCIATED WITH AN ATOM. ! THE CELL ATOM_FORM CONTAINS A TYPE MASK IDENTIFYING THE ! CRITICAL FEATURES OF THE LISP OBJECT HELD IN ATOM_FUNC. %IF FORM>=LIST BASE %THEN %START; ! FORM IS A LIST CELL==LIST(FORM); CAR=CELL_CAR; CDR=CELL_CDR %RESULT = APPLY(CAR,EVLIST(CDR)) %C %IF CAR>=LIST BASE; ! CAR IS A LIST %IF CAR>=NAME BASE %START; ! CAR IS A SYMBOLIC ATOM ATOM==NAME(CAR) CDR=EVLIST(CDR) %IF ATOM_FORM&4#0; ! EXPR/SUBR %RESULT = FUNC(ATOM,CDR); ! FORM OF APPLY %FINISH %RESULT = ERROR3; ! NUMERIC ATOM %FINISH %IF FORM>=NAME BASE %START; ! SYMBOLIC ATOM ATOM==NAME(FORM) %RESULT = ATOM_FUNC %IF ATOM_FORM&7=3; ! APVAL %RESULT = ATOM_BIND; ! RETURN BINDING %FINISH %RESULT = FORM; ! NUMERIC ATOM %END $N $P2 @AS FUNCTIONS MAY EITHER BE IMPLEMENTED AS PART OF THE INTERPRETER ITSELF .(SUBR AND .FSUBR) OR AS USER SPECIFIED FUNCTION DEFINITIONS .(EXPR OR .FEXPR), AN ADDITIONAL INTERNAL FUNCTION .FUNC IS INCLUDED IN THE .ECSD .LISP SYSTEM. .FUNC EITHER PASSES CONTROL TO AN INTERNAL FUNCTION OR @A@P@P@L@YS THE USER PROVIDED FUNCTION DEFINITION. $B $L0 %INTEGERFN FUNC(%RECORDNAME ATOM, %INTEGER ARGS) %RECORDNAME ATOM(ATOM CELL) %RECORDNAME CELL(LISP CELL) %SWITCH TYPE(0:3) ->TYPE(ATOM_FORM&3) TYPE(3): ! APVAL TYPE(0): ! NO FUNCTION DEFINITION ON PROPERTY LIST %RESULT = ERROR2 %UNLESS ATOM_BIND=ERROR1; ! NOR A BINDING %RESULT = APPLY(ATOM_BIND,EVLIST(ARGS)) TYPE(1): ! EXPR OR FEXPR %RESULT = APPLY(ATOM_FUNC,ARGS) TYPE(2): ! SUBR OR FSUBR ->MACH(ATOM_FUNC); ! JUMP TO MACHINE SUBROUTINE. %END %INTEGERFN APPLY(%INTEGER FN, ARGS) %RECORDNAME CELL(LISP CELL) %INTEGER CAR, CADR, CADDR %IF FN>=LIST BASE %THEN %START CELL==LIST(FN); CAR=CELL_CAR CELL==LIST(CELL_CDR); CADR=CELL_CAR CELL==LIST(CELL_CDR); CADDR=CELL_CAR %IF CAR=LABEL %THEN %START BIND(CADR,CADDR) %RESULT = APPLY(CADDR,ARGS) %FINISH %IF CAR=LAMBDA %THEN %START BINDLIST(CADR,ARGS); ! BIND ARGUMENT LIST. BIND(CADR,LIST) %IF CADR#NIL; ! BIND REST OF LIST. %RESULT = UNBIND(EVAL(CADDR)); ! EVAL AND THEN UNBIND. %FINISH %RESULT = APPLY(EVAL(FN),ARGS) %FINISH %IF FN>=NAME BASE %START; ! SYMBOLIC ATOM. %RESULT = FUNC(NAME(FN),ARGS) %FINISH %RESULT = ERROR3; ! NUMERIC ATOM. %END $A UND='_' $N $L1CU 3.6 THE TOP LEVEL LOOP $P2 @THE TOP LEVEL OF THE .ECSD .LISP .SYSTEM CONSISTS OF A .(PRINT .(EVAL .(READ))) LOOP IDENTIFIED BY THE PROMPT .'LISP:'. $L0CI TOPLEV = (LAMBDA NIL (PROG TEMP L (PRIND (COND ((EQ (SETQ TEMP (READ 'LISP:)) 'STOP) (RETURN 'STOP)) (T (EVAL TEMP)))) (GO L))) $P2 @THE SYSTEM WILL NORMALLY RETURN TO THE TOP LEVEL WHEN THE .S-EXPRESSION INPUT TO THE SYSTEM AT THE TOP LEVEL HAS BEEN EVALUATED, BUT THE SYSTEM MAY BE FORCED BACK TO THE TOP LEVEL AT ANY TIME BY EVALUATING THE FUNCTION .'(RESET)'. @THE MOST COMMON USE OF WHICH IS FROM WITHIN A .BREAK, TO ABANDON A FAULTY COMPUTATION. $P @AS MAY BEEN SEEN FROM THE ABOVE CODE, THE TOP LEVEL AND HENCE THE .LISP .INTERPRETER ARE EXITED WHEN THE ATOM .STOP IS READ AT THE TOP LEVEL. $V6 $B2 $L1CU 3.7 BREAKS $P2 @AN EXTREMELY POWERFULL FEATURE OF THE .ECSD .LISP .SYSTEM IS THE .BREAK: @AN INTERNALLY DEFINED .LISP FUNCTION, THAT IS CALLED BY .EVAL WHEN .EVAL FAILS TO EVALUATE AN .S-EXPRESSION. $L0CI BREAK = (LAMBDA (SEXP CAUSE) (PROG (TEMP) (INUNIT 0) (OUTUNIT 0) (ERRMESS CAUSE) L (COND ((NOT (EQ (SETQ TEMP (EVAL (READ '/ / / $%:))) '$%)) (PRIND TEMP) (GO L))) (RETURN (COND ((EQ (SETQ TEMP (EVAL (READ 'EVAL:))) '$%) (EVAL SEXP)) (T TEMP))))) $A INDENT=2 $B $I1 @THE .BREAK PERFORMS FOUR FUNCTIONS: $B $I1 1). $T2 @IT FREEZES A COMPUTATION AT THE POINT OF FAILURE. $B $I1 2). $T2 @IT RESETS THE INPUT AND OUTPUT STREAMS TO THE CONSOLE. $B $I1 3). $T2 @IT ENTERS A .(PRINT .(EVAL .(READ))) LOOP, FROM WHICH THE USER MAY EXAMINE AND ALTER THE STATE OF HIS COMPUTATION USING THE FULL POWER OF THE .LISP SYSTEM. $B $I1 4). $T2 @IT RESUMES THE COMPUTAION UNDER USER CONTROL, EITHER BY REEVALUATING THE .S-EXPRESSION THAT ORIGINALLY FAILED, OR BY SUBSTITUTING A NEW .S-EXPRESSION, PROVIDED BY THE USER, FOR THE ONE THAT FAILED. $A INDENT=1 $N $L1IU EXAMPLES $L0IC LISP:(CAR 1) EVAL ERROR: (CAR 1) ARGUMENT NOT OF THE CORRECT FORM IN (1) $%:$% EVAL:1 1 $P @THE FUNCTION .CAR IS NOT DEFINED FOR ATOMIC ARGUMENTS AND HENCE FAILS TO EVALUATE, WITH THE RESULT THAT A .BREAK IS ENTERED. @THE USER FIRST TYPES '$%', IN RESPONSE TO THE PROMPT '$ $ $ $%:', TO EXIT FROM THE .BREAK .LOOP, AND THEN ENTERS AN .S-EXPRESSION IN RESPONCE TO THE PROMPT .'EVAL:'. @THIS .S-EXPRESSION, IN THIS CASE THE .ATOM '1', IS THEN EVALUTED AND THE RESULT, IN THIS CASE ALSO THE .ATOM '1', IS RETURNED IN PLACE OF THE FAULTY .S-EXPRESSION .(CAR 1). @AS .(CAR 1) WAS INPUT AT THE TOP LEVEL, THE RESULT RETURNED BY THE TOP LEVEL .EVAL BECOMES THE .ATOM '1', AND IT IS THIS THAT IS PRINTED BY THE TOP LEVEL PRINT. $L0IC LISP:(CDR B) EVAL ERROR: B ATOM IS NOT BOUND TO A VALUE $%:(PEEK) EVAL * (CDR B) END OF PEEK $%:(SETQ B '(A B C)) (A B C) $%:$% EVAL:$% (B C) $P @AS .CDR IS A FUNCTION THAT EVALUATES ITS ARGUMENTS, .EVAL WILL EVALUATE @B PRIOR TO APPLYING .CDR. @IN THIS CASE THE EVALUATION OF @B FAILS, BECAUSE @B HAS NO BINDING. @THE FUNCTION .'(PEEK)' PRINTS OUT THE CONTENTS OF THE LOCAL STACK, WHICH CONTAINS BOTH FUNCTIONS BEING APPLIED AND LOCAL BINDINGS. @IN THIS CASE WE SEE THAT .EVAL IS BEING APPLIED TO .(CDR .B). @THE '*' INDICATES APPLICATION, WHILE A '=' INDICATES A BINDING. @THERE ARE CURRENTLY NO LOCAL BINDINGS. @THE USER THAN GIVES @B A GLOBAL BINDING, IN THIS CASE THE LIST .(A @B .C). @IF @B HAD POSSESSED A LOCAL BINDING, .SETQ WOULD HAVE ALTERED IT. @THE USER THEN EXITS FROM THE .BREAK .LOOP AND IN RESPONSE TO THE PROMPT .'EVAL:' TYPES '$%' WHICH INDICATES THAT HE WISHES TO CONTINUE THE COMPUTATION BY REEVALUATING THE FAULTY .S-EXPRESSION, IN THIS CASE THE .ATOM .B. @AS @B NOW POSSESSES A BINDING, IT EVALUATES SUCCESSFULLY, TO THE LIST .(A @B .C). @THE .CDR OF THIS LIST IS THE LIST .(B .C), AND IT IS THIS THAT IS RETURNED TO, AND PRINTED AT, THE TOP LEVEL. $B $L0IC LISP:(DE FACT(N) (COND ((ZEROP N) (TEST)) (T (TIMES N (FACT (SUB1 N] FACT $P @WE NOW SUCCESSFULLY DEFINE THE FUNCTION .FACT AT THE TOP LEVEL. @THE DEFINITION IS FAULTY, AS WE MAKE USE OF AN UNDEFINED FUNCTION .(TEST), BUT THIS WILL ONLY BECOME EVIDENT WHEN WE USE THE FUNCTION .FACT. $N $L0IC LISP:(FACT 4) EVAL ERROR: (TEST) FUNCTION NOT DEFINED = TEST $%:(PEEK) N = 0 FACT * (0) EVAL * (TIMES N (FACT (SUB1 N))) N = 1 FACT * (1) EVAL * (TIMES N (FACT (SUB1 N))) N = 2 FACT * (2) EVAL * (TIMES N (FACT (SUB1 N))) N = 3 FACT * (3) EVAL * (TIMES N (FACT (SUB1 N))) N = 4 FACT * (4) END OF PEEK $%:(RESET) $P @IN THIS CASE WE DECIDE THERE IS NO RECOVERY POSSIBLE AND WISH TO RETURN TO THE TOP LEVEL LOOP. @THIS IS ACHIEVED BY THE FUNCTION .(RESET), WHICH ABORTS THE CURRENT COMPUTATION AND RETURNS TO THE TOP LEVEL VIA AN ERROR ROUTE. IE. .EVAL DOES NOT RETURN. $B $L0IC LISP:(FACT 4) EVAL ERROR: (TEST) FUNCTION NOT DEFINED = TEST $%:$% EVAL:1 24 $P @IN THIS CASE WE SUBSTITUTE THE .ATOM 1 FOR THE CALL ON .(TEST), AND CONTINUE THE COMPUTATION, WHICH THEN RETURNS THE CORRECT ANSWER. $B $L0IC LISP:(FACT 4) EVAL ERROR: (TEST) FUNCTION NOT DEFINED = TEST $%:(DE TEST () 1) TEST $%:$% EVAL:$% 24 $P @IN THIS CASE WE DEFINE THE FUNCTION .TEST TO RETURN THE .ATOM 1 AS A RESULT, AND RESUME THE COMPUTATION BY REEVALUATING .(TEST). $B $L0IC LISP:(EDITF FACT) EDIT:(R* (TEST) 1) EDIT:$%C END OF EDITF LISP:(FACT 4) 24 $P @IN THIS CASE WE EDIT THE FUNCTION .FACT, SUBSTITUTING THE .ATOM 1 FOR ALL CALLS ON THE FUNCTION .(TEST). @THIS REMOVES THE ERROR FROM THE DEFINITION OF .FACT, WITH THE EFFECT THAT .(FACT 4) EVALUATES CORRECTLY. @THE EDITOR IS DESCRIBED IN DETAIL IN A LATER SECTION. $A INDENT=0 $V8 $B2 $L1CU 3.8 TRACING $P2 @TRACING IS A MECHANISM INCLUDED IN .EVAL WHICH ALLOWS THE USE OF FUNCTIONS, THEIR ARGUMENTS AND THE VALUES THEY RETURN TO BE MONITORED ON THE CURRENTLY SELECTED OUTPUT CHANNEL. @THE .FSUBR .TRACE TURNS ON TRACING OF A NOMINATED FUNCTION, WHILE THE .FSUBR .UNTRACE TURNS IT OFF. @THE MESSAGES THAT ARE OUTPUT HAVE THE FOLLOWING FORM: $B2 $I4 %MODEL $T8 EXAMPLE $I0 ON CALL: $T3 ---> FUNCTION (ARG1 ARG2 $.$.$. ARGN) $T8 ---> .CONS .(A .B) $I0 ON RETURN: $T3 <--- FUNCTION RESULT $T8 <--- .CONS .(A $. .B) $A INDENT=1 $B2 $L1IU EXAMPLE $B $L0IC LISP:(DE FACT (N) (COND ((ONEP N) 1) LISP: (T (TIMES N (FACT (SUB1 N] FACT LISP:(TRACE FACT) FACT LISP:(FACT 4) ---> FACT (4) ---> FACT (3) ---> FACT (2) ---> FACT (1) <--- FACT 1 <--- FACT 2 <--- FACT 6 <--- FACT 24 24 LISP:(UNTRACE FACT) FACT LISP:(FACT 4) 24 $A INDENT=0 $N $LICU 4.0 THE LISP EDITOR $P2 @THE EDITOR, WHICH IS ITSELF WRITTEN IN .LISP, IS A SLIGHTLY MODIFIED VERSION OF THAT PROVIDED WITH THE .LISP .F1 SYSTEM. $P @THE EDITOR PROVIDES A POWERFULL MEANS OF EXAMINING AND ALTERING LIST STRUCTURES. @IT IS NORMALLY USED FOR MODIFYING BINDINGS AND FUNCTION DEFINITIONS. @FOR THESE TWO USES SPECIFIC .FEXPRS ARE PROVIDED. .EDITB IS PROVIDED FOR EDITING BINDINGS, WHILE .EDITF IS PROVIDED FOR EDITING FUNCTION DEFINITIONS. $P @THE COMMAND $%@C WILL CAUSE THE EDITOR TO RETURN TO THE ENVIRONMENT FROM WHICH IT WAS CALLED. $P @IN THE SAME WAY THAT A TEXT EDITOR MAINTAINS A TEXT POINTER, THE LISP EDITOR MAINTAINS A LIST POINTER. @BECAUSE LISTS DO NOT HAVE THE LINEAR STRUCTURE OF TEXT, WE WILL NOT BE ABLE TO MOVE THE LIST POINTER IN THE SAME WAY THAT WE WOULD MOVE A TEXT POINTER, THOUGH THE CONCEPT IS SIMILAR. @INSTEAD OF MOVING A TEXT POINTER A NUMBER OF CHARTACTERS OR LINES FORWARDS OR BACKWARDS IN THE FILE, WE MAY SET THE LIST POINTER TO A SUB-EXPRESSION OF THE LIST AT WHICH IT CURRENTLY POINTS. $B2 $L1CU 4.1 MOVING THE LIST POINTER $P2 @THE USER MAY DESCEND INTO THE STUCTURE OF A LIST BY SETTING THE LIST POINTER TO A SUB-EXPRESSION OF THE CURRENT LIST. @THIS IS DONE BY TYPING A POSITIVE INTEGER .N, WHICH WILL CAUSES THE LIST POINTER TO BE SET TO THE @NTH SUB-EXPRESSION OF THE CURRENT LIST. @THIS PROCESS MAY BE REPEATED TO DESCEND FURTHER INTO THE LIST BEING EDITED. @THE INTEGER 0 FORCES THE EDITOR BACK TO THE OUTERMOST LIST. $A INDENT=1 $B $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:4 P (D (E)) EDIT:2 P (E) EDIT:0 P* (A B C (D (E)) F) $A INDENT=0 $N $L1CU 4.2 PRINTING LISTS $P2 @THE LISP OBJECT AT WHICH THE LIST POINTER IS POINTING IS PRINTED ON THE CONSOLE BY TYPING THE COMMAND .P. @TO AVAID WASTEFUL PRINTING, ANY LIST WITH SUB-LISTS NESTING TO GREATER THAN A DEPTH OF 3, IS PRINTED ONLY TO DEPTH 2, AFTER WHICH THE ATOM *** IS PRINTED TO INDICATE CONTINUATION OF THE LIST. @AN ADDITIONAL COMMAND P* IS INCLUDED WHICH WILL PRINT THE ENTIRE LIST WITHOUT CHANGE. $A INDENT=1 $B $L1IU EXAMPLE $B $L0IC EDIT:P* (A (B (C (D)))) EDIT:P (A (B (*** ***))) $A INDENT=0 $B2 $L1CU 4.3 REPLACING LIST ELEMENTS $P2 @TO REPLACE THE @NTH SUB-EXPRESSION OF THE CURRENT LIST BY ONE OR MORE .S-EXPRESSIONS TYPE THE COMAND .(R N E1 E2 $.$.$.) WHERE N IS A POSITIVE INTEGER AND E1, E2 $.$.$. ARE ARBITRARY .S-EXPRESSIONS. $P @TO REPLACE ALL OCCURANCES OF A LISP OBJECT IN THE CURRENT LIST TYPE THE COMMAND (@R* OLD NEW) WHERE OLD IS THE OBJECT TO BE REPLACED AND NEW IS THE OBJECT THAT REPLACES IT. $A INDENT=1 $B $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:4 P (D (E)) EDIT:(R 2 (G) H (A B)) EDIT:0 P* (A B C (D (G) H (A B)) F) EDIT:(R* A (A A)) P* ((A A) B C (D (G) H ((A A) B)) F) $A INDENT=0 $B2 $L1CU 4.4 DELETING LIST ELEMENTS $P2 @TO DELETE THE @NTH SUB-EXPRESSION OF THE CURRENT LIST TYPE THE COMMAND .(D N) WHERE N IS A POSITIVE INTEGER. $A INDENT=1 $B $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:(D 3) P* (A B (D (E)) F) $A INDENT=0 $N $L1CU 4.5 INSERTING LIST ELEMENTS $P2 @TO INSERT ONE OR MORE EXPRESSIONS IMMEDIATELY BEFORE THE @NTH SUB-EXPRESSION IN THE CURRENT LIST TYPE THE COMMAND .(I N E1 E2 $.$.$.), WHERE N IS THE NUMBER OF THE SUB-EXPRESSION AND E1, E2 $.$.$. ARE ARBITRARY .S-EXPRESSIONS. $A INDENT=1 $B $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:4 P (D (E)) (I 2 (G) H) EDIT:0 P* (A B C (D (G) H (E)) F) $A INDENT=0 $B2 $L1CU 4.6 DELETING PARENTHESES $P2 @THE COMMAND .(BO N) WHERE N IS A POSITIVE INTEGER, REMOVES THE FIRST LEVEL OF PARENTHESES FROM AROUND THE NTH SUB-EXPRESSION OF THE CURRENT LIST. @THIS CAUSES THE ELEMENTS OF THE NTH SUB-EXPRESSION TO BECOME ELEMENTS OF THE CURRENT LIST. $P @THE COMMAND .(LO N) WHERE N IS A POSITIVE INTEGER, REMOVES THE OUTERMOST LEFT PARENTHESIS FROM THE NTH SUB-EXPRESSION OF THE CURRENT LIST. @THE OUTERMOST RIGHT PARENTHESIS OF THE NTH SUB-EXPRESSION THEN BECOMES THE THE OUTERMOST RIGHT PARENTHESIS OF THE CURRENT LIST. @ELEMENTS THAT WERE PREVIOUSLY TO THE RIGHT OF THE NTH ELEMENT IN THE CURRENT LIST ARE LOST. $A INDENT=1 $B2 $L1IU EXAMPLES $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:(BO 4) P (A B C D (E) F) EDIT:(LO 5) P (A B C D E) $A INDENT=0 $N $L1CU 4.7 INSERTING PARENTHESES $P2 @THE COMMAND .(BI M N) PLACES A LEFT PARENTHESIS BEFORE THE MTH ELEMENT OF THE CURRENT LIST AND A RIGHT PARENTHESIS AFTER THE NTH ELEMENT OF THE CURRENT LIST, THUS SUBORDINATING A NUMBER OF ELEMENTS OF THE CURRENT LIST INTO THE MTH SUB-EXPRESSION. $P @THE COMMAND .(LI N) PLACES A LEFT PARENTHESIS BEFORE THE NTH ELEMENT OF THE CURRENT LIST, AND A RIGHT PARENTHESIS AT THE END OF THE CURRENT LIST, THUS SUBORDINATING ALL ELEMENTS OF THE CURRENT LIST STARTING WITH THE NTH ELEMENT INTO A SUB-EXPRESSION WHICH BECOMES THE NTH ELEMENT. $A INDENT=1 $B2 $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:(BI 2 3) P* (A (B C) (D (E)) F) EDIT:(LI 2) P* (A ((B C) (D (E)) F)) $A INDENT=0 $B2 $L1CU 4.8 MOVING PARENTHESES $P2 @THE COMMAND .(R0 M) WHERE M IS A POSITIVE INTEGER, MOVES THE RIGH:T PARENTHESIS AT THE END OF THE MTH SUB-EXPRESSION OF THE CURRENT LIST TO THE END OF THE CURRENT LIST. $P2 @THE COMMAND .(RI M: N) WHERE M AND N ARE POSITIVE INTEGERS, MOVES THE RIGH:T PARENTHESIS AT THE END OF THE MTH SUB-EXPRESSION TO THE END OF THE NTH SUB-EXPRESSION IN THE MTH SUB-EXPRESSION. @IT HAS THE SAME EFFECT AS THE COMMAND .(BO M) FOLLOWED BY THE COMMAND .(BI M+N) WHERE M+N IS A POSITIVE INTEGER EQUAL TO THE SUM OF M AND N. $A INDENT=1 $B2 $L1IU EXAMPLE $B $L0IC EDIT:P* (A B C (D (E)) F) EDIT:(RI 4: 1) P* (A B C (D) (E) F) EDIT:(RO 4) P* (A B C (D (E) F)) $A INDENT=0 $N $L1CU 5.0 FUNCTIONS $B2 ********** BASIC FUNCTIONS $B $I0 .QUOTE, .FUNCTION $T9 .FSUBR $B $I0 .CAR, .CDR $.$.$. .CADDR, .CDDR $T9 .SUBR $B $I0 .CONS $T9 .SUBR $B $I0 .LIST $T9 .SUBR $B $I0 .EXPLODE $T9 .SUBR $B $I0 .MAKEATOM $T9 .SUBR $B $I0 .GENSYM $T9 .EXPR $B2 ********** CONDITIONS & PREDICATES $B $I0 .SELECTQ $T9 .FSUBR $B $I0 .COND $T9 .FSUBR $B $I0 .AND $T9 .FSUBR $B $I0 .OR $T9 .FSUBR $B $I0 .NOT, .NULL $T9 .SUBR $B $I0 .LISTP $T9 .EXPR $B $I0 .ATOM $T9 .SUBR $B $I0 .NUMBERP $T9 .SUBR $B $I0 .EVENP $T9 .SUBR $B $I0 .ONEP $T9 .SUBR $B $I0 .ZEROP $T9 .SUBR $B $I0 .MINUSP $T9 .EXPR $B $I0 .EQ $T9 .SUBR $B $I0 .EQUAL $T9 .SUBR $B $I0 .LESSP $T9 .SUBR $B $I0 .GREATERP $T9 .SUBR $B2 ********** LIST MANIPUTAION FUNCTIONS $B $I0 .APPEND $T9 .EXPR $B $I0 .REVERSE $T9 .SUBR $B $I0 .LENGTH $T9 .EXPR $B $I0 .NTH $T9 .EXPR $B $I0 .FIND $T9 .EXPR $B $I0 .MEMB, .MEMQ $T9 .SUBR $B $I0 .MEMBER $T9 .SUBR $B $I0 .ASSOC $T9 .SUBR $B2 ********** ARITHMETIC MANIPULATION FUNCTIONS $B $I0 .PLUS $T9 .SUBR $B $I0 .*PLUS $T9 .SUBR $B $I0 .DIFFERENCE $T9 .SUBR $B $I0 .*DIFFERENCE $T9 .SUBR $B $I0 .TIMES $T9 .SUBR $B $I0 .*TIMES $T9 .SUBR $B $I0 .QUOTIENT $T9 .SUBR $B $I0 .*QUOTIENT $T9 .SUBR $B $I0 .ADD1 $T9 .SUBR $B $I0 .SUB1 $T9 .SUBR $B $I0 .MINUS $T9 .EXPR $B2 ********** PROPERTY LIST MANIPULATION $B $I0 .PROP $T9 .SUBR $B $I0 .GET $T9 .SUBR $B $I0 .GETD $T9 .EXPR $B $I0 .PUT, .PUTPROP $T9 .SUBR $B $I0 .DEFPROP $T9 .FSUBR $B $I0 .REM, .REMPROP $T9 .SUBR $B $I0 .DF, .DE $T9 .FEXPR $B $I0 .DEFINE $T9 .FEXPR $B $I0 .EDITF $T9 .FEXPR $B2 ********** EVALUATION FUNCTIONS $B $I0 .EVAL $T9 .SUBR $B $I0 .EVLIS $T9 .SUBR $B $I0 .APPLY $T9 .SUBR $B $I0 .ERRSET $T9 .FSUBR $B $I0 .MAP, .MAPC, .MAPLIST, .MAPCAR $T9 .EXPR $B2 ********** IMPERATIVE FUNCTIONS $B $I0 .RPLACA $T9 .SUBR $B $I0 .RPLACD $T9 .SUBR $B $I0 .NCONC $T9 .SUBR $B $I0 .CSETQ $T9 .FEXPR $B $I0 .CSET $T9 .EXPR $B $I0 .SETQ $T9 .FSUBR $B $I0 .SET $T9 .SUBR $B $I0 .EDITB $T9 .FEXPR $B2 ********** PROGRAMMING FUNCTIONS $B $I0 .PROG2 $T9 .SUBR $B $I0 .PROGN $T9 .FSUBR $B $I0 .PROG $T9 .FSUBR $B $I0 .RETURN $T9 .SUBR $B $I0 .GO $T9 .FSUBR $B2 ********** I/O FUNCTIONS $B $I0 .READCH $T9 .SUBR $B $I0 .READ $T9 .SUBR $B $I0 .TEREAD $T9 .EXPR $B $I0 .PRINC $T9 .SUBR $B $I0 .PRIND $T9 .SUBR $B $I0 .PRINT $T9 .EXPR $B $I0 .TERPRI $T9 .SUBR $B $I0 .INUNIT $T9 .SUBR $B $I0 .OUTUNIT $T9 .SUBR $B $I0 .INPUT $T9 .SUBR $B $I0 .OUTPUT $T9 .SUBR $B2 ********** META FUNCTIONS $B $I0 .TRACE $T9 .FSUBR $B $I0 .UNTRACE $T9 .FSUBR $B $I0 .BREAK $T9 .FSUBR $B $I0 .UNBREAK $T9 .FSUBR $B $I0 .PEEK $T9 .SUBR $B $I0 .GARB $T9 .SUBR $B $I0 .RESET $T9 .SUBR $B $I0 .ERR $T9 .SUBR $B $I0 .OBLIST $T9 .SUBR $B $I0 .ALIST $T9 .SUBR $E