Google
 

Trailing-Edge - PDP-10 Archives - decus_20tap1_198111 - decus/20-0016/mlisp.txt
There are 2 other files named mlisp.txt in the archive. Click here to see a list.
00010	WRITEUP
00020	
00030	   THIS WRITEUP IS INTENDED TO CORRECT, SUPPLEMENT AND EXTEND THE "MLISP USERS' MANUAL", S.A.I.P. MEMO #AI-84,
00040	BY DAVID C. SMITH.  IT IS A DESCRIPTION OF ALL THE DIFFERENCES BETWEEN THE CURRENT VERSION OF MLISP
00050	AND THE VERSION REPORTED IN THE "MLISP USERS' MANUAL".
00060	
00070	   THE MAIN DIFFERENCES RESULT FROM THE INCORPORATION OF A SUPER FAST TABLE-DRIVEN SCANNER INTO THE TRANSLATOR.
00080	THIS HAS DECREASED TRANSLATION TIME BY A FACTOR OF THREE;  MLISP TRANSLATION SPEED IS NOW 3000-5000 LINES/MIN.
00090	IT HAS ALSO RESULTED IN SOME ALTERATIONS (AND SIMPLIFICATIONS) IN THE SYNTAX, AND SOME IMPROVEMENTS IN THE
00100	OBJECT CODE GENERATED.
00110	
00120	   A SUMMARY OF ALL OF THESE CHANGES IS LISTED ON PAGES 2-1,2.  WHERE NECESSARY, FURTHER ELABORATION IS GIVEN
00130	ON FOLLOWING PAGES.
00140	
00150	   THE FOLLOWING IS A DIRECTORY FOR THIS WRITEUP:
00160	
00170	PAGE	  KEY			CONTENTS
00180	
00190	1-1	WRITEUP		INTRODUCTION, MOTIVATION, AND DIRECTORY
00200	2-1,2	CHANGES		SUMMARY OF CHANGES SINCE THE "MLISP USERS' MANUAL"
00210	3-1,2	SYNTAX		THE COMPLETE, UPDATED, MLISP SYNTAX
00220	4-1	COMPILER	IMPROVEMENTS IN CODE GENERATION FOR COMPILED OBJECT PROGRAMS
00230	5-1	FOR-LOOPS	CHANGES IN, AND ELABORATION ON, THE EXECUTION OF FOR-LOOPS
00240	5-2			THE LISP EQUIVALENT OF A SAMPLE FOR-LOOP
00250	6-1	STRINGS		NEW INTERNAL REPRESENTATION, AND ADDITIONAL FUNCTIONS
00260	6-2			REVIEW OF STRING-MANIPULATION FUNCTIONS
00270	7-1,3	PROGRAM		THE SAMPLE MLISP PROGRAM (PRESENTED IN THE "MLISP USERS' MANUAL") USING THE NEW SYNTAX
00280	8-1,3	TRANSLATION	THE GRINDEF'ED LISP TRANSLATION FOR THE SAMPLE PROGRAM
00290	9-1	FILES		REFERENCE FILE OF THE MLISP SOURCE FILES
00300	9-2			INSTRUCTIONS FOR REGENERATING MLISP AND MLISPC
00310	
     
00010	CHANGES
00020	
00030	   THE FOLLOWING IS A SUMMARY OF ALL THE CHANGES IN MLISP SINCE PUBLICATION OF THE "MLISP USERS' MANUAL".
00040	
00050		TOPIC			CHANGE
00060	
00070	FUNCTION DEFINITIONS	INSTEAD OF <NAME> := #<ARGLIST>: <BODY>;
00080				OR         <NAME> := *<ARGLIST>: <BODY>;
00090	
00100				USE     EXPR <NAME> (<ARGLIST>); <BODY>;
00110				OR     FEXPR <NAME> (<ARGLIST>); <BODY>;
00120				OR     MACRO <NAME> (<ARGLIST>); <BODY>;
00130	
00140				FOR DEFINING FUNCTIONS.  THIS IS A CLEARER AND MORE GENERAL NOTATION.
00150				MACROS ARE NOW PERMITTED AND ARE THE SAME AS LISP MACROS (CONSULT QUAM'S
00160				LISP 1.6 MANUAL).  NOTE: IF MACROS ARE USED, THEY SHOULD COME AT THE HEAD OF THE
00170				PROGRAM, OR AT LEAST BEFORE ANY FUNCTIONS WHICH USE THEM.
00180	
00190	NUMBERS		-----   ARE NOW LISP 1.6 NUMBERS, I.E. LISP SYNTAX AND LISP INTERNAL REPRESENTATION -- EXCEPT
00200				THAT '+' AND '-' ARE TREATED AS DELIMITERS.
00210				FOR EXAMPLE,   -19  IS TRANSLATED INTO  (MINUS 19)
00220				AND           X-19  IS TRANSLATED INTO  (DIFFERENCE X 19).
00230	
00240	OCTAL NUMBERS	-----	NUMBERS IN MLISP PROGRAMS ARE NORMALLY UNDERSTOOD TO BE DECIMALS (BASE 10).
00250				HOWEVER, OCTAL (BASE 8) NUMBERS MAY BE INCLUDED BY IMMEDIATELY PRECEEDING THE NUMBER
00260				WITH THE WORD 'OCTAL'.  FOR EXAMPLE:
00270					OCTAL 177
00280				      + OCTAL 1234567
00290				      - OCTAL 7654321
00300				NOTE: OCTAL - 7654321  IS INCORRECT!  'OCTAL' MUST IMMEDIATELY PRECEED THE NUMBER.
00310	
00320	STRINGS		-----   ARE NOW LISP 1.6 STRINGS, I.E. LISP SYNTAX AND LISP INTERNAL REPRESENTATION.  THIS WAS
00330				DONE BOTH TO SIMPLIFY THE SCANNER AND TO MAKE THE STORAGE OF STRINGS MORE EFFICIENT.
00340				IT HAS NECESSITATED THE REWRITING OF THE STRING-MANIPULATION FUNCTIONS:
00350				   STR,AT,CAT,SUBSTR,PRINTSTR
00360				AND THE ADDITION OF A NEW STRING 'EQ' FUNCTION, 'SEQ', TO TEST FOR THE EQUALITY
00370				OF TWO STRINGS.  THESE ARE ALL EXPLAINED IN DETAIL ON PAGES 6-1,2.
00380	
00390	:=		-----   NO LONGER EXISTS; USE _ (LEFT ARROW).
00400	
00410	**		-----   NO LONGER EXISTS; EXPONENTIATION IS NOW INCLUDED AS PART OF THE SYNTAX FOR NUMBERS.
00420	
00430	: (COLON)	-----   IS NOW CONSIDERED TO BE A LETTER, ALONG WITH A,B,C, ... ,X,Y,Z,! (EXCLAMATION MARK).
00440	
00450	NUMBERP		-----   IS NOW CONSIDERED TO BE A PREFIX, ALONG WITH +,-,NOT,NULL,ATOM .
00460	
00470	| (VERTICAL BAR)-----	IS NOW CONSIDERED TO BE AN INFIX OPERATOR, AN ABBREVIATION FOR 'OR'.
00480	
00490			-----	IS NOW CONSIDERED TO BE AN INFIX OPERATOR, AN ABBREVIATION FOR 'NEQUAL'.
00500	
00510	 (EPSILON)	-----	IS NOW CONSIDERED TO BE AN INFIX OPERATOR, AN ABBREVIATION FOR 'MEMBER'.
00520				SO THE COMPLETE SET OF INFIX-OPERATOR ABBREVIATIONS IS NOW:
00530				     ABBREV	INFIX OP
00540					+	PLUS
00550					-	DIFFERENCE
00560					*	TIMES
00570					/	QUOTIENT
00580					&	AND
00590					|	OR
00600					=	EQUAL
00610						NEQUAL
00620					@	APPEND
00630						MEMBER .
00640	
00650	?		-----   THE SLASHIFIER CHARACTER; SPECIAL (NON-LETTER-OR-DIGIT) CHARACTERS MAY NOW BE
00660				INCLUDED IN IDENTIFIERS BY PRECEEDING THEM WITH THE SLASHIFIER CHARACTER.
00670	
00680	FOR-LOOPS	-----   THE CONTROL VARIABLE IN FOR-LOOPS MAY NOW BE DECLARED TO BE LOCAL TO THE BODY
00690				OF THE FOR-LOOP BY SPECIFYING IT TO BE 'NEW' (C.F. PAGE 5-1).
00700	
00710	SPECIAL		-----	IN THE SAME VEIN AS THE ABOVE CHANGE, LAMBDA VARIABLES MAY BE DECLARED SPECIAL
00720				BY PRECEEDING THEM WITH THE WORD 'SPECIAL'.  FOR EXAMPLE:
00730					EXPR MARK (L,SPECIAL IND);   MAPCAR(FUNCTION(LAMBDA (A); PUTPROP(A,T,IND)),L);
00740				PREVIOUSLY, THE ONLY WAY TO DO THIS WOULD HAVE BEEN:
00750					EXPR MARK (L,IND);
00760					   BEGIN
00770					      SPECIAL IND;
00780					      RETURN(MAPCAR(FUNCTION(LAMBDA (A); PUTPROP(A,T,IND)), L));
00790					   END;
00800	
00810	SYNTAX		-----	THE CHANGES IN THE MLISP SYNTAX ARE MARKED WITH AN ASTERISK (*) ON PAGES 3-1,2.
00820	
00830	MACROS		-----  	MACROS ARE NOW USED TO EXPAND ITERATION LOOPS WHEN COMPILED USING MLISPC (PAGE 4-1).
00840	
00850	'MLISP'		-----	THE SUPERVISORY FUNCTION 'MLISP' NOW TAKES AT MOST TWO ARGUMENTS (INSTEAD OF THREE):
00860				(MLISP)			- TRANSLATES AN MLISP PROGRAM FROM THE CURRENTLY SELECTED
00870							  INPUT FILE, AND THEN EXECUTES THE TRANSLATED CODE.
00880							  THE LISP 'INPUT' FUNCTION SHOULD BE USED TO SELECT
00890							  THE INPUT FILE; E.G.
00900								(INPUT DTA1: FOO)
00910								(INPUT (1 DAV) BAZ)
00920								(INPUT DSK: FOOBAZ)
00930							  ETC., BEFORE (MLISP) IS CALLED.
00940				(MLISP <FILENAME>)	- TRANSLATES AN MLISP PROGRAM FROM DSK: <FILENAME>,
00950							  AND THEN EXECUTES THE TRANSLATED CODE.
00960				(MLISP <FILENAME> NIL)	- TRANSLATES AN MLISP PROGRAM FROM DSK: <FILENAME>,
00970							  AND THEN GRINDEF'S THE TRANSLATED PROGRAM ONTO
00980							  DSK: <FILENAME>.LSP .
00990							  'MLISP' MUST BE USED FOR THIS OPTION.
01000				(MLISP <FILENAME> T)	- TRANSLATES AN MLISP PROGRAM FROM DSK: <FILENAME>,
01010							  AND THEN COMPILES THE TRANSLATED PROGRAM ONTO
01020							  DSK: <FILENAME>.LAP .
01030							  'MLISPC' MUST BE USED FOR THIS OPTION.
01040	
01050	'MEXPR'		-----	A PROGRAM CALLED 'MEXPR' (FOR M-EXPRESSION) NOW EXISTS FOR TRANSLATING LISP
01060				PROGRAMS INTO MLISP.  THIS HELPS REDUCE THE OVERHEAD IN TRANSFORMING A LISP SYSTEM
01070				INTO AN MLISP SYSTEM.  IT SHOULD BE ABLE TO HANDLE THE LISP USED ON MOST LISP SYSTEMS.
01080	
     
00010	SYNTAX
00020	
00030	   FOR REFERENCE PURPOSES, THE COMPLETE MLISP SYNTAX IS REPRODUCED BELOW.
00040	DIFFERENCES WITH THE SYNTAX REPORTED IN THE "MLISP USERS' MANUAL" ARE MARKED WITH AN ASTERISK.
00050	IN ADDITION, THE SAMPLE PROGRAM GIVEN IN THE MANUAL IS REPRODUCED ON PAGES 6-1,***** IN THE NEW SYNTAX FORMAT.
00060	
00070	   AGAIN, SEVERAL SETS OF META-SYMBOLS ARE EMPLOYED TO SIMPLIFY THE PRESENTATION OF THE SYNTAX:
00080	(1) ANGLED BRACKETS <> ENCLOSE NON-TERMINAL SYMBOLS OR, IN SOME CASES, DESCRIPTIONS IN ENGLISH.
00090	(2) SQUARE BRACKETS [] ENCLOSE OPTIONAL ELEMENTS.
00100	(3) CURLY  BRACKETS {} ENCLOSE ALTERNATIVE ELEMENTS, WHICH ARE SEPARATED BY COMMAS.
00110	(4) THE SPECIAL META-SYMBOLS [] ENCLOSE OPTIONAL ELEMENTS WHICH MAY EXIST ZERO OR MORE TIMES.
00120	(5) ALL OTHER SYMBOLS (EXCEPT ::= AND |) STAND FOR THEMSELVES.
00130	
00140	<PROGRAM>		::=  <EXPRESSION> .
00150	
00160	<EXPRESSION>		::=  <SIMPLE EXPRESSION>  [<INFIX OPERATOR> <SIMPLE EXPRESSION>]
00170	
00180	* <INFIX OPERATOR>	::=  {+, -, *, /, &, |, =, , @, }
00190				 |   <IDENTIFIER>
00200	
00210	<SIMPLE EXPRESSION>	::=  <BLOCK>
00220				 |   <CONDITIONAL EXPRESSION>
00230	*			 |   <FOR EXPRESSION>
00240				 |   <WHILE EXPRESSION>
00250				 |   <UNTIL EXPRESSION>
00260	*			 |   <LAMBDA EXPRESSION>
00270	*			 |   <FUNCTION DEFINITION>
00280				 |   <FUNCTION CALL>
00290	*			 |   <ASSIGNMENT EXPRESSION>
00300				 |   <LIST EXPRESSION>
00310				 |   <QUOTE EXPRESSION>
00320				 |   (<EXPRESSION>)
00330	*			 |   <PREFIX> <SIMPLE EXPRESSION>
00340				 |   <STRING>
00350	*			 |   <NUMBER>
00360				 |   <EMPTY>
00370	
00380	<BLOCK>			::=  BEGIN  [<DECLARATION> ;]  [<EXPRESSION> ;]  END
00390	
00400	<DECLARATION>		::=  NEW <IDENTIFIER LIST>
00410				 |   SPECIAL <IDENTIFIER LIST>
00420	
00430	<IDENTIFIER LIST>	::=  <IDENTIFIER>  [, <IDENTIFIER>]
00440				 |   <EMPTY>
00450	
00460	<CONDITIONAL EXPRESSION>::=  IF <EXPRESSION> THEN <EXPRESSION>  [ELSE <EXPRESSION>]
00470	
00480	* <FOR EXPRESSION>	::=  FOR  [NEW]  <IDENTIFIER> {IN, ON} <EXPRESSION>
00490					{DO, COLLECT} <EXPRESSION>  [UNTIL <EXPRESSION>]
00500	*			 |   FOR  [NEW]  <IDENTIFIER> _ <EXPRESSION> TO <EXPRESSION>  [BY <EXPRESSION>]
00510					{DO, COLLECT} <EXPRESSION>  [UNTIL <EXPRESSION>]
00520	
00530	<WHILE EXPRESSION>	::=  WHILE <EXPRESSION> {DO, COLLECT} <EXPRESSION>
00540	
00550	<UNTIL EXPRESSION>	::=  {DO, COLLECT} <EXPRESSION> UNTIL <EXPRESSION>
00560	
00570	* <LAMBDA EXPRESSION>	::=  LAMBDA (<LAMBDA IDENTIFIER LIST>); <EXPRESSION>  [; (<ARGLIST>)]
00580	
00590	<LAMBDA IDENTIFIER LIST>::=  <IDENTIFIER LIST>
00600	*			 |   [SPECIAL]  <IDENTIFIER>  [,  [SPECIAL]  <IDENTIFIER>]
00610	
00620	* <FUNCTION DEFINITION>	::=  {EXPR, FEXPR, MACRO} <IDENTIFIER> (<LAMBDA IDENTIFIER LIST>); <EXPRESSION>
00630	
00640	<FUNCTION CALL>		::=  <IDENTIFIER> (<ARGLIST>)
00650	
00660	<ARGLIST>		::=  <EXPRESSION>  [, <EXPRESSION>]
00670				 |   <EMPTY>
00680	
00690	*<ASSIGNMENT EXPRESSION>::=  <IDENTIFIER> _ <EXPRESSION>
00700	
00710	<LIST EXPRESSION>	::=  < <ARGLIST> >
00720	
00730	<QUOTE EXPRESSION>	::=  ' <S-EXPRESSION>
00740	
00750	* <S-EXPRESSION>	::=  <SAME SYNTAX AS FOR LISP 1.6 S-EXPRESSIONS, EXCEPT THAT EVERY ATOM IN THE
00760					S-EXPRESSION MUST BE A LEGAL MLISP <IDENTIFIER> OR <NUMBER> ;
00770					I.E. ALL SPECIAL CHARACTERS IN IT MUST BE SLASHIFIED !>
00780	
00790	* <PREFIX>		::=  {+, -, NOT, NULL, ATOM, NUMBERP}
00800	
00810	<STRING>		::=  " <ANY SEQUENCE OF CHARACTERS -- POSSIBLY NONE -- EXCEPT "> "
00820	
00830	<NUMBER>		::=  <INTEGER>
00840	*			 |   OCTAL <INTEGER>
00850	*			 |   <REAL>
00860	
00870	<INTEGER>		::=  <DIGITS>  [.]
00880	
00890	<DIGITS>		::=  <DIGIT>  [<DIGIT>]
00900	
00910	<DIGIT>			::=  {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
00920	
00930	* <REAL>		::=  <INTEGER> <EXPONENT>
00940	*			 |   [<DIGITS>]  . <DIGITS>  [<EXPONENT>]
00950	
00960	* <EXPONENT>		::=  E  [{+, -}]  <DIGITS>
00970	
00980	<IDENTIFIER>		::=  <LETTER>  [{<LETTER>, <DIGIT>}]
00990	
01000	* <LETTER>		::=  {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V,
01010					W, X, Y, Z, !, :}
01020	*			 |   <SLASHIFIER CHARACTER> <ANY ASCII CHARACTER EXCEPT NULL OR RUBOUT>
01030	
01040	* <SLASHIFIER CHARACTER>::=  ?
     
00010	COMPILER
00020	
00030	   THERE HAVE BEEN SEVERAL IMPROVEMENTS IN THE WAY MLISP HANDLES CODE THAT IS TO BE COMPILED.
00040	
00050	   ITERATION STATEMENTS -- FOR-LOOPS, WHILE-LOOPS, UNTIL-LOPS -- NOW GENERATE IN-LINE CODE WHICH IS THEN
00060	COMPILED, WHEN FUNCTIONS CONTAINING THEM ARE COMPILED BY MLISPC.  PREVIOUSLY ITERATION STATEMENTS WERE
00070	TRANSLATED INTO CALLS ON RUN-TIME FUNCTIONS, BUT THIS HAD SEVERAL UNPLEASANT RESULTS:
00080	   (1) THE BODY OF THE ITERATION LOOP, A FOR-LOOP FOR EXAMPLE, HAD TO BE PASSED AS A FUNCTIONAL ARGUMENT
00090		TO THE RUN-TIME FUNCTION, AND AS SUCH IT COULD NOT BE COMPILED.  THIS MEANT THAT IF THE MAIN PART OF
00100		A FUNCTION WERE AN ITERATION LOOP AND THE FUNCTION WERE COMPILED, A LARGE PART OF THE FUNCTION
00110		WOULD REMAIN UNCOMPILED AND HAVE TO BE INTERPRETED.  IN ADDITION TO SEVERELY LIMITING THE SPEED OF
00120		COMPILED FUNCTIONS CONTAINING ITERATION LOOPS, THIS ALSO TOOK UP UNNECESARY FREE STORAGE SINCE
00130		THE BODIES OF THE LOOPS WERE STORED AS LIST STRUCTURE.
00140	   (2) ALL VARIABLES USED IN THE BODIES OF ITERATION LOOPS HAD TO BE DECLARED SPECIAL, SINCE THE BODIES
00150		WERE TREATED AS FUNCTIONAL ARGUMENTS (C.F. QUAM'S LISP 1.6 MANUAL FOR A DISCUSSION OF FUNCTIONAL
00160		ARGUMENTS).  THIS NECESSITATED A GREAT DEAL OF CARE AND EFFORT ON THE PART OF THE PROGRAMMER
00170		TO INSURE THAT HE HAD DECLARED ALL SUCH VARIABLES SPECIAL.
00180	
00190	   NOW MACROS HAVE BEEN WRITTEN TO GENERATE IN-LINE CODE FOR ITERATION LOOPS, RATHER THAN CALLS ON
00200	RUN-TIME FUNCTIONS.  THIS CODE IS THEN COMPILED BY THE LISP COMPILER.  NOT ONLY IS THE LAP CODE USUALLY SHORTER
00210	THAN THE CORRESPONDING LIST-STRUCTURE INTERPRETED CODE, BUT IT IS PUT IN BINARY PROGRAM SPACE AS WELL,
00220	WHERE IT DOES NOT HAVE TO BE GARBAGE COLLECTED, THUS SAVING BOTH GARBAGE COLLECTION TIME AND FREE STORAGE
00230	SPACE.  THE PROBLEM WITH SPECIALS ALSO GOES AWAY SINCE THERE ARE NO MORE FUNCTIONAL ARGUMENTS; THE
00240	VARIABLES IN THE BODIES OF ITERATION LOOPS REMAIN BOUND WITHIN THE SCOPE OF THE ENCOMPASING LAMBDA OR PROG.
00250	
00260	   THE USER SHOULD NOTE THAT ITERATION LOOPS ARE EXPANDED BY MACROS ONLY WHEN 'MLISPC' IS USED;
00270	WITH 'MLISP', ITERATION LOOPS ARE STILL TRANSLATED IN THE OLD WAY -- AS CALLS ON RUNTIME FUNCTIONS.
00280	THIS IS BECAUSE WITH 'MLISP', FUNCTIONS CAN ONLY BE RUN INTERPRETED (OR GRINDEFED), AND HAVING AT LEAST
00290	PART OF THE ITERATION LOOPS COMPILED NOT ONLY MAKES THEM RUN FASTER, BUT ENABLES THEM TO TAKE UP LESS
00300	SPACE AS WELL (I.E. LESS SPACE THAN THE EQUIVALENT LIST-STRUCTURE INTERPRETED CODE, BUT MORE THAN THE
00310	EQUIVALENT LAP CODE).  SO IN EACH CASE, WHETHER THE USER'S PROGRAM IS TO BE RUN INTERPRETED OR COMPILED,
00320	MLISP GENERATES THE OPTIMAL CODE BOTH IN TERMS OF SPEED AND IN TERMS OF STORAGE REQUIREMENTS.
00330	
00340	   MLISP DOES ANOTHER GOOD THING FOR THE USER WHEN HIS OBJECT CODE IS TO BE COMPILED:
00350	IT PUTS THE *FEXPR (FORWARD REFERENCE TO FEXPR) PROPERTY ON ALL FEXPR'S.  WHEN THE LISP COMPILER
00360	COMES ACROSS AN UNDEFINED FUNCTION, IT ASSUMES THE FUNCTION IS AN EXPR WHICH WILL BE DEFINED LATER
00370	AND GENERATES CODE ACCORDINGLY.  BUT IF THE FUNCTION TURNS OUT TO BE AN FEXPR, THIS CODE WILL BE
00380	INCORRECT.  MLISP NOW ELIMINATES THIS POSSIBILITY.
00390	
00400	   MLISP ALSO ELIMINATES THE POSSIBILITY OF THE USER UNKNOWINGLY REDEFINING ANY FUNCTION WHICH HAS
00410	ALREADY BEEN DEFINED BY LISP, MLISP, OR ANYONE ELSE; IT CHECKS THE PROPERTY LIST OF EVERY FUNCTION
00420	DEFINED BY THE USER FOR ANY OF THE FOLLOWING INDICATORS: EXPR, FEXPR, SUBR, FSUBR, MACRO, LEXPR, LSUBR.
00430	IF ONE OF THESE IS ALREADY ON THE PROPERTY LIST, THE MESSAGE
00440	      ***WARNING***, FUNCTION <FUNCTION NAME> REDEFINED
00450	IS PRINTED OUT.  THE DEFINITION IS STILL CARRIED OUT, BUT THE USER IS NOW AWARE OF WHAT HAS HAPPENED.
00460	
     
00010	FOR-LOOPS
00020	
00030	   THE CONTROL VARIABLE IN FOR-LOOPS MAY NOW BE DECLARED TO BE LOCAL TO THE BODY OF THE FOR-LOOP
00040	BY SPECIFYING IT TO BE 'NEW'.  FOR EXAMPLE:
00050	
00060	      FOR NEW I IN '(A B C D E) DO PRINT(I)			% VALUE IS  E %
00070	      FOR NEW L ON '(A B C D E) COLLECT <L> UNTIL L='(C D E)	% VALUE IS  ((A B C D E) (B C D E) (C D E)) %
00080	      FOR NEW EVEN _ 0 TO 100 BY 2 DO PRINT(BINARY(EVEN))	% VALUE IS  BINARY(100) %
00090	
00100	THIS RELIEVES THE USER FROM HAVING TO DECLARE THE CONTROL VARIABLE AS A PROG VARIABLE.  FOR EXAMPLE:
00110	      EXPR MAKELISTS (L);	% ADDS AN EXTRA LEVEL OF PARENTHESES AROUND THE ELEMENTS IN THE LIST 'L'. %
00120	         BEGIN			% I.E. IF 'L' IS  (A B C ...), THE VALUE IS  ((A) (B) (C) ...) %
00130	            NEW I;
00140	            RETURN(FOR I IN L COLLECT <<I>>);
00150	         END;
00160	IS EQUIVALENT TO:
00170	      EXPR MAKELISTS (L);   FOR NEW I IN L COLLECT <<I>>;
00180	
00190	   THE USER SHOULD NOTE, HOWEVER, THAT IF THE 'NEW' OPTION IS USED, THE CONTROL VARIABLE WILL HAVE
00200	THE SAME VALUE WHEN THE FOR-LOOP IS EXITED THAT IT HAD WHEN THE FOR-LOOP WAS ENTERED.
00210	THE OLD FORM MAY STILL BE USED IF THE USER WISHES TO REFERENCE THE VALUE OF THE CONTROL VARIABLE.
00220	AS AN EXAMPLE OF THE TYPE OF SITUATION IN WHICH THIS MIGHT BE DESIREABLE, THE LISP FUNCTION 'MEMBER'
00230	COULD BE WRITTEN IN MLISP AS FOLLOWS:
00240	
00250	      EXPR MEMBER (X,L);    MEMBER1(X,L,NIL);
00260	      EXPR MEMBER1(X,L,I);  PROG2(FOR I IN L DO UNTIL I = X,I);
00270	
00280	   THE EXECUTION OF THIS WILL NOW BE EXPLAINED IN DETAIL TO FURTHER CLARIFY THE OPERATION OF FOR-LOOPS:
00290	'I' STEPS THROUGH 'L', GETTING SET TO CAR(L), CADR(L), CADDR(L), ETC., UNTIL ONE OF TWO CONDITIONS IS SATISFIED:
00300	   (1) L IS EXHAUSTED, IN WHICH CASE THE FOR-LOOP EXITS "NORMALLY" WITH I BEING RESET TO NIL.
00310	         THUS THE VALUE OF THE PROG2 WILL BE NIL, AND SO THE VALUE OF THE WHOLE FUNCTION WILL BE NIL.
00320	   (2) ONE OF THE ELEMENTS OF L IS EQUAL TO X, IN WHICH CASE THE FOR-LOOP EXITS "ABNORMALLY"
00330	         WITH I STILL BOUND TO THAT ELEMENT.  THEN THE VALUE OF THE PROG2 WILL BE THE VALUE OF I
00340	         (NON-NIL IF X WAS NON-NIL), AND SO THE VALUE OF THE WHOLE FUNCTION WILL BE NON-NIL (I.E. TRUE).
00350	         (NOTE, HOWEVER, THAT THIS -- INFERIOR -- VERSION OF 'MEMBER' CANNOT TEST IF NIL MEMBER L.)
00360	
00370	ALTERNATIVELY, BUT LESS EFFICIENTLY, ONE COULD WRITE:
00380	
00390	      EXPR MEMBER (X,L);   FOR NEW I IN L DO I = X UNTIL I = X;   % THIS CAN TEST IF NIL MEMBER L. %
00400	
00410	OF COURSE, 'MEMBER' COULD ALSO BE WRITTEN MORE CONVENTIONALLY AS:
00420	
00430	      EXPR MEMBER (X,L);
00440	         IF NULL L THEN NIL ELSE
00450	         IF CAR(L) = X THEN T
00460	         ELSE X MEMBER CDR(L);
00470	
00480	OR EQUIVALENTLY:
00490	
00500	      EXPR MEMBER (X,L);   L & (CAR(L) = X) OR X MEMBER CDR(L);
00510	
00520	
00530	FOR-LOOPS
00540	
00550	   THE LISP EQUIVALENT OF A SAMPLE FOR-LOOP -- TO FURTHER ELABORATE ON THE OPERATION OF FOR-LOOPS,
00560	THE EXECUTION OF:
00570	
00580	      FOR I IN '(A B C D E) DO PRINT(I) UNTIL I EQ 'D
00590	
00600	IS THE SAME AS:
00610	
00620	      (PROG (&LST &V)					% IF 'NEW I' WERE SPECIFIED, THE PROG VARIABLES
00630									WOULD BE (&LST &V I). %
00640		    (SETQ &LST (QUOTE (A B C D E)))
00650	 	L   (COND ((NULL &LST) (RETURN (PROG2 (SETQ I NIL) &V))))
00660		    (SETQ I (CAR &LST))				% IF 'ON' RATHER THAN 'IN' WERE SPECIFIED, THIS
00670									WOULD BE (SETQ I &LST). %
00680		    (SETQ &V (PRINT I))				% IF 'COLLECT' RATHER THAN 'DO' WERE SPECIFIED, THIS
00690									WOULD BE (SETQ &V (APPEND &V (PRINT I))). %
00700		    (COND ((EQ I (QUOTE D)) (RETURN &V)))	% IF NO 'UNTIL' CONDITION WERE SPECIFIED, THIS
00710									WOULD BE OMITTED. %
00720		    (SETQ &LST (CDR &LST))
00730		    (GO L)
00740	      )
00750	
00760	
00770	
00780	
00790	
00800	
00810	N.B.  THE LISP 'RETURN' FUNCTION SHOULD NEVER BE USED TO TERMINATE ANY ITERATION LOOP !  THE ONLY LEGAL WAY TO
00820	HALT AN ITERATION LOOP SOONER THAN NORMAL IS WITH AN 'UNTIL' EXPRESSION.  FOR EXAMPLE:
00830	
00840		FOR I IN L DO IF I EQ 'STOP THEN RETURN(I)
00850	
00860	IS ILLEGAL AND WILL UNDOUBTEDLY GIVE SOME VERY STRANGE BEHAVIOR.  THE CORRECT WAY TO WRITE THE ABOVE LOOP IS:
00870	
00880		FOR I IN L DO I UNTIL I EQ 'STOP
00890	
     
00010	STRINGS
00020	
00030	   PREVIOUSLY STRINGS WERE STORED AS LISTS OF SINGLE CHARACTERS; FOR EXAMPLE:
00040	      "THIS IS A STRING"
00050	WAS STORED AS
00060	      (T H I S / I S / A / S T R I N G).		% THE CHARACTERS / REPRESENT THE BLANK CHARACTER. %
00070	IN ORDER TO MAKE THE STORAGE OF STRINGS MORE EFFICIENT, AND ALSO TO SIMPLIFY THE SCANNER, MLISP STRINGS ARE NOW
00080	IDENTICAL WITH LISP 1.6 STRINGS -- AND, INCIDENTALLY, MLISP NUMBERS ARE ALSO NOW IDENTICAL WITH
00090	LISP 1.6 NUMBERS (C.F. QUAM'S LISP 1.6 MANUAL FOR A COMPLETE DESCRIPTION OF LISP NUMBERS AND STRINGS).
00100	THIS MEANS THAT STRINGS ARE NOW STORED AS LISTS OF FIVE-CHARACTER ATOMS; FOR EXAMPLE:
00110	      "THIS IS A STRING"
00120	IS NOW STORED AS
00130	      (THIS/ IS/A/ STRIN G),
00140	A LIST WITH FOUR ELEMENTS INSTEAD OF SIXTEEN.  FURTHERMORE, THE FIVE-CHARACTER ATOMS ARE NOT INTERNED
00150	(PUT ON THE OBLIST) AND ARE STORED IN FULL-WORD SPACE, SO THAT NEITHER OBLIST SPACE NOR FREE STORAGE
00160	IS TAKEN UP BY STRINGS.
00170	
00180	   THE USER, HOWEVER, IS NOT AWARE OF ANY DIFFERENCE IN THE HANDLING OF STRINGS; ALL THE STRING-MANUPULATION
00190	FUNCTIONS -- STR, AT, CAT, SUBSTR, PRINTSTR -- OPERATE AS PREVIOUSLY, EVEN THOUGH THEY HAVE BEEN REWRITTEN.
00200	BUT SINCE STRINGS ARE NOT INTERNED, TESTING FOR THE EQUALITY OF TWO STRINGS USING 'EQUAL' WILL NO LONGER WORK;
00210	THEREFORE, A NEW FUNCTION HAS BEEN ADDED TO THE STRING-MANIPULATION PACKAGE:  'SEQ'.  THIS FUNCTION,
00220	AS WELL AS THE FUNCTION 'AT' WHICH WAS NOT INCLUDED IN THE "MLISP USERS' MANUAL", WILL NOW BE DESCRIBED.
00230	
00240	   IN THE FOLLOWING DESCRIPTIONS, THE TERM "S-EXPRESSION" IS TAKEN TO MEAN ANY ARBITRARY LISP
00250	S-EXPRESSION -- ATOM, NUMBER, LIST, DOTTED PAIR, OR STRING.
00260	
00270	* SEQ -	THE STRING 'EQ' FUNCTION.  'SEQ' TAKES TWO ARGUMENTS, WHICH MAY BE ANY S-EXPRESSIONS,
00280		AND RETURNS 'T' IF THE ARGUMENTS ARE IDENTICAL, 'NIL' OTHERWISE.
00290	
00300	* AT -	MAKES AN ATOM OUT OF A STRING.  'AT' TAKES ONE ARGUMENT, A STRING,
00310		AND RETURNS AN ATOM WITH A PRINTNAME OF THE CHARACTERS IN THE STRING.
00320		N.B. THE PRINTNAME WHICH RESULTS MUST BE A LEGAL LISP PRINTNAME !
00330	
00340	
00350	
00360	
00370	
00380	
00390	
00400	
00410	
00420	
00430	
00440	
00450	
00460	
00470	
00480	
00490	
00500	
00510	
00520	
00530	STRINGS
00540	
00550	   FOR REFERENCE PURPOSES, THE OTHER STRING-MANIPULATION FUNCTIONS ARE REVIEWED BELOW.
00560	
00570	* STR - 	MAKES A STRING OUT OF AN S-EXPRESSION.  'STR' TAKES ONE ARGUMENT, WHICH MAY BE ANY
00580			S-EXPRESSION, AND RETURNS A STRING CONTAINING THE CHARACTERS IN THE ARGUMENT.
00590			(N.B. THE FUNCTION 'STRING' DESCRIBED IN THE "MLISP USERS' MANUAL" IS NOW
00600			INCLUDED IN 'STR'.)
00610	
00620	* CAT -		CONCATENATION.  'CAT' TAKES TWO ARGUMENTS, WHICH MAY BE ANY S-EXPRESSIONS, DOES A 'STR' OF
00630			EACH ARGUMENT, AND RETURNS THE STRING FORMED BY CONCATENATING THE RESULTS.
00640			(NOTE:  THE ABOVE IS A DESCRIPTION OF THE BEHAVIOR OF 'CAT', NOT OF ITS ACTUAL OPERATION.)
00650	
00660	* SUBSTR -	SUBSTRING.  'SUBSTR' TAKES THREE ARGUMENTS:  SUBSTR(STRING,START,LENGTH).
00670			IT RETURNS THE STRING FORMED FROM THAT PART OF 'STRING' BEGINNING WITH THE CHARACTER
00680			SPECIFIED BY 'START' (COUNTING FROM 1) AND EXTENDING FOR 'LENGTH' CHARACTERS.
00690			IF 'LENGTH' IS NOT A NUMBER, THE REST OF THE STRING IS ASSUMED.  THUS,
00700			   SUBSTR("THIS IS A STRING",6,'ALL)  =  "IS A STRING",
00710			   SUBSTR("THIS IS A STRING",6,16)    =  "IS A STRING",
00720			   SUBSTR("THIS IS A STRING",6,1000)  =  "IS A STRING", BUT
00730			   SUBSTR("THIS IS A STRING",6,8)     =  "IS A STR".
00740	
00750	* PRINTSTR -	THE PRINT STRING FUNCTION.  'PRINTSTR' TAKES ONE ARGUMENT, WHICH MAY BE ANY S-EXPRESSION,
00760			PRINTS IT, DOES A 'TERPRI', AND RETURNS NIL.
00770	
00780	   NOTE:  THE FUNCTIONS ABOVE ALL HAVE ASTERISKS (*) IN FRONT OF THEM TO EMPHASIZE THAT THEIR ARGUMENTS HAVE
00790	BEEN GENERALIZED.  WHEREAS BEFORE THEY COULD ONLY BE STRINGS, NOW (WITH THE EXCEPTION OF 'AT') THEY CAN BE
00800	ANY S-EXPRESSION.
00810	
00820	
00830	EXAMPLES:
00840	
00850	"THIS IS A "  CAT  "STRING"		= "THIS IS A STRING"
00860	"THIS IS A "  CAT  'STRING		= "THIS IS A STRING"
00870	"THIS IS A "  CAT  STR('STRING)		= "THIS IS A STRING"
00880	STR('STRING)				= "STRING"
00890	STR('(A (B C) D))			= "(A (B C) D)"
00900	AT("STRING")				= STRING
00910	SUBSTR("THIS IS A STRING",6,4)		= "IS A"
00920	SUBSTR("THIS IS A STRING",1,'ALL)	= "THIS IS A STRING"
00930	PRINTSTR("STRING")  WILL PRINT		STRING
00940	PRINT("STRING")     WILL PRINT		"STRING"
00950	"STRING"  SEQ  "STRING"			= T
00960	"STRING"  SEQ  'STRING			= NIL
00970	"STRING"  SEQ  STR('STRING)		= T
00980	AT("STRING")  SEQ  'STRING		= T
00990	
01000	   
01010	PRELIST -	CAN NO LONGER BE USED ON STRINGS, BUT STILL WORKS AS BEFORE FOR LISTS:
01020			PRELIST(LIST,INTEGER) RETURNS A LIST OF THE FIRST 'INTEGER' ELEMENTS OF 'LIST'.
01030	
01040	SUFLIST -	CAN NO LONGER BE USED ON STRINGS, BUT STILL WORKS AS BEFORE FOR LISTS:
01050			SUFLIST(LIST,INTEGER) TAKES THE CDR OF 'LIST' 'INTEGER' TIMES AND RETURNS WHAT IS LEFT.
01060			SUFLIST IS THE GENERALIZED CDR FUNCTION:
01070				SUFLIST(L,0) = L
01080				SUFLIST(L,1) = CDR(L)
01090				SUFLIST(L,2) = CDDR(L)
01100				SUFLIST(L,3) = CDDDR(L)
01110				SUFLIST(L,4) = CDDDDR(L)
01120				SUFLIST(L,5) = CDR(CDDDDR(L))   ETC.
01130	
01140	F1 - F9		THE NINE 'FIELD' FUNCTIONS ALSO WORK AS BEFORE, ALTHOUGH THEY CAN NO LONGER
01150			BE USED ON STRINGS EITHER.
01160	
01170	EXAMPLES:     SUPPOSE  L = (A B C D E F G H I).
01180	
01190	PRELIST(L,5)	= (A B C D E)
01200	SUFLIST(L,5)	= (F G H I)
01210	F1(L)		= A		= CAR(L)
01220	F2(L)		= B		= CADR(L)
01230	F3(L)		= C		= CADDR(L)
01240	F4(L)		= D		= CADDDR(L)
01250	F5(L)		= E		= CAR(CDDDDR(L))
01260	F6(L)		= F		= CADR(CDDDDR(L))
01270	F7(L)		= G		= CADDR(CDDDDR(L))
01280	F8(L)		= H		= CADDDR(CDDDDR(L))
01290	F9(L)		= I		= CAR(CDDDDR(CDDDDR(L)))
01300	
     
00010	PROGRAM
00020	
00030	BEGIN  NEW EXPRLIST,FEXPRLIST,LEN,L;          % GLOBAL DECLARATIONS %
00040	   SPECIAL EXPRLIST,FEXPRLIST,LEN;
00050	
00060	% THERE ARE MANY WAYS TO WRITE THE FUNCTION 'REVERSE,' WHICH REVERSES THE TOP LEVEL OF A LIST, IN MLISP.
00070	   THE FOLLOWING PROGRAM PRESENTS SOME OF THOSE WAYS AND THEN EVALUATES THEM ON TEST LISTS.
00080	   IT PRINTS OUT THE TIME REQUIRED BY EACH FUNCTION, SO THAT THEY MAY BE RANK-ORDERED IN EFFICIENCY. %
00090	
00100	%##########################################################################################%
00110	%###################          DEFINE ALL THE REVERSE FUNCTIONS          ###################%
00120	%##########################################################################################%
00130	
00140	EXPR REVERSE1 (L);   REVERSE1A(L,NIL);     % THIS IS AN EXPR.  USES IF-THEN-ELSE. %
00150	
00160	EXPR REVERSE1A (L,LL);   IF NULL L THEN LL ELSE REVERSE1A(CDR(L),CAR(L) CONS LL);
00170	   % THE REVERSE OF 'L' IS BUILT UP IN THE SECOND ARGUMENT 'LL'. %
00180	
00190	
00200	EXPR REVERSE2 (L);   IF NULL L THEN NIL ELSE REVERSE2(CDR(L)) @ <CAR(L)>;
00210	   % THIS IS AN EXPR.  USES IF-THEN-ELSE AND A RECURSIVE CALL ON ITSELF.  IN THIS VERSION,
00220	      THE REVERSE OF THE REST OF THE LIST 'L' IS APPENDED (@) TO A LIST CONTAINING THE FIRST ELEMENT. %
00230	
00240	
00250	FEXPR REVERSE3 (L);
00260	   % THIS IS AN FEXPR; L IS AN UNEVALUATED LIST OF THE ACTUAL ARGUMENTS PASSED TO REVERSE3.  USES A FOR LOOP.
00270	      THE FOR-LOOP STEPS THROUGH THE LIST 'L,' SUCCESSIVELY ASSIGNING EACH ELEMENT IN IT TO 'I'. %
00280	   BEGIN  NEW V;     % RECALL THAT ALL 'NEW', I.E. PROG, VARIABLES ARE AUTOMATICALL INITIALIZED TO NIL. %
00290	      RETURN(FOR NEW I IN L DO V _ I CONS V);
00300	   END;
00310	
00320	
00330	EXPR REVERSE4 (L);
00340	   % THIS IS AN EXPR.  USES A WHILE LOOP.  WHILE THERE IS STILL SOMETHING LEFT IN 'L,' THE PROG2 IS EXECUTED. %
00350	   BEGIN  NEW V;
00360	      RETURN(WHILE L DO PROG1(V _ CAR(L) CONS V,L _ CDR(L)));
00370	   END;
00380	
00390	
00400	EXPR REVERSE5 (L);
00410	   % THIS IS AN EXPR.  USES A DO-UNTIL LOOP.  THE PROG2 IS EXECUTED UNTIL 'L' IS NIL. %
00420	   IF NULL L THEN NIL ELSE
00430	   BEGIN  NEW V;
00440	      RETURN(DO PROG1(V _ CAR(L) CONS V,L _ CDR(L)) UNTIL NULL L);
00450	   END;
00460	
00470	FEXPR REVERSE6 (L);
00480	   % THIS IS ANOTHER FEXPR -- THE ARGUMENTS ARE NOT EVALUATED. %
00490	   % THIS IS LESS GENERAL THAN THE OTHER FUNCTIONS;  IT WILL NOT WORK FOR LISTS OF LENGTH > 100.
00500	      HOWEVER, IT IS INCLUDED AS AN EXAMPLE OF A FOR-LOOP USING A NUMERICAL INCREMENT. %
00510	   IF NULL L THEN NIL ELSE
00520	   BEGIN  NEW V;
00530	      % THE 'UNTIL' CONDITION STOPS THE FOR-LOOP IF 'L' CONTAINED FEWER THAN 100 ELEMENTS. %
00540	      RETURN(FOR NEW I_1 TO 100 DO PROG1(V _ CAR(L) CONS V,L _ CDR(L)) UNTIL NULL L);
00550	   END;
00560	
00570	
00580	FEXPR REVERSE7 (L);   REVERSE7A(L,NIL);
00590	   % ANOTHER WAY OF WRITING REVERSE6.  THIS DOES NOT REQUIRE ANY BEGIN-END, NEW DECLARATIONS,
00600	      OR RETURN STATEMENT.  IT ALSO PRESERVES THE LENGTH OF 'L' IN THE GLOBAL VARIABLE 'LEN'. %
00610	
00620	EXPR REVERSE7A (L,V);
00630	   IF NULL L THEN NIL ELSE
00640	      FOR LEN_1 TO 100 DO PROG1(V _ CAR(L) CONS V,L _ CDR(L)) UNTIL NULL L;
00650	
00660	
00670	EXPR PROG1 (A,B);  A;
00680	   % 'PROG1' IS LIKE PROG2, EXCEPT THAT PROG1 RETURNS THE VALUE OF ITS FIRST ARGUMENT. %
00690	
00700	%##########################################################################################%
00710	%#######################           EXECUTION BEGINS HERE          #########################%
00720	%##########################################################################################%
00730	
00740	EXPRLIST _ '(REVERSE1 REVERSE2 REVERSE4 REVERSE5);
00750	FEXPRLIST _ '(REVERSE3 REVERSE6 REVERSE7);
00760	
00770	PRINTSTR("TYPE A LIST TO BE REVERSED.");
00780	
00790	% READ IN TEST LISTS UNTIL THE ATOM 'STOP' IS ENCOUNTERED %
00800	
00810	WHILE (L _ READ()) NEQ 'STOP DO
00820	   BEGIN  NEW FUNCLIST;
00830	      TERPRI();                         % SKIP A LINE IN THE OUTPUT. %
00840	      PRINTSTR("THE TEST LIST IS " CAT L);
00850	      % COLLECT TOGETHER THE FUNCTION NAMES APPLIED TO THE TEST LIST. %
00860	      FUNCLIST _ FOR NEW FUNCNAME IN EXPRLIST COLLECT <<FUNCNAME,<'QUOTE,L>>>;
00870	      FUNCLIST _ FUNCLIST @ FOR NEW FUNCNAME IN FEXPRLIST COLLECT <FUNCNAME CONS L>;
00880	
00890	      % EVALUATE ALL OF THE FUNCTIONS WITH THE TEST ARGUMENT. %
00900	      FOR NEW FUNC IN FUNCLIST DO
00910	      BEGIN  NEW START;
00920	         PRINT(CAR(FUNC));              % PRINT OUT THE FUNCTION NAME. %
00930	         START _ TIME();                % 'TIME()' YIELDS THE CURRENT TIME IN MILLISECONDS. %
00940	         PRINT(EVAL(FUNC));             % EVALUATE THE FUNCTION. %
00950	         PRINT((TIME()-START)/1000.0);  % PRINT THE TIME REQUIRED. %
00960	         PRINTSTR(" SECS");
00970	         TERPRI();                      % SKIP A LINE IN THE OUTPUT. %
00980	      END;
00990	      TERPRI();   TERPRI();             % SKIP TWO MORE LINES. %
01000	      PRINTSTR("TYPE ANOTHER LIST TO BE REVERSED, OR 'STOP'");
01010	   END;
01020	
01030	% THE LISP PROGRAM, INTO WHICH THIS MLISP PROGRAM IS TRANSLATED, IS LISTED ON THE FOLLOWING PAGES.
01040	   IT HAS BEEN PRINTED USING A STANFORD-WRITTEN FUNCTION CALLED 'GRINDEF,' AN S-EXPRESSION UN-CRUNCHER. %
01050	
01060	END.
     
00010	TRANSLATION
00020	
00030	
00040	(DEFPROP EXPRLIST T SPECIAL) 
00050	(DEFPROP FEXPRLIST T SPECIAL) 
00060	(DEFPROP LEN T SPECIAL) 
00070	
00080	(DEFPROP REVERSE3 T *FEXPR) 
00090	(DEFPROP REVERSE6 T *FEXPR) 
00100	(DEFPROP REVERSE7 T *FEXPR) 
00110	
00120	(DEFPROP REVERSE1 
00130	 (LAMBDA (L) (REVERSE1A L NIL)) 
00140	EXPR)
00150	
00160	(DEFPROP REVERSE1A 
00170	 (LAMBDA (L LL) (COND ((NULL L) LL) (T (REVERSE1A (CDR L) (CONS (CAR L) LL))))) 
00180	EXPR)
00190	
00200	(DEFPROP REVERSE2 
00210	 (LAMBDA (L) (COND ((NULL L) NIL) (T (APPEND (REVERSE2 (CDR L)) (LIST (CAR L)))))) 
00220	EXPR)
00230	
00240	(DEFPROP REVERSE3 
00250	 (LAMBDA (L) (PROG (V) (RETURN (&FOR (QUOTE (I)) (QUOTE (T . T)) L (QUOTE (SETQ V (CONS I V))) NIL)))) 
00260	FEXPR)
00270	
00280	(DEFPROP REVERSE4 
00290	 (LAMBDA (L)
00300	  (PROG (V) (RETURN (&WHILEDO (QUOTE L) (QUOTE (PROG1 (SETQ V (CONS (CAR L) V)) (SETQ L (CDR L)))))))) 
00310	EXPR)
00320	
00330	(DEFPROP REVERSE5 
00340	 (LAMBDA (L)
00350	  (COND ((NULL L) NIL)
00360		(T
00370		 (PROG (V)
00380		       (RETURN
00390			(&DOUNTIL (QUOTE (PROG1 (SETQ V (CONS (CAR L) V)) (SETQ L (CDR L)))) (QUOTE (NULL L)))))))) 
00400	EXPR)
00410	
00420	(DEFPROP REVERSE6 
00430	 (LAMBDA (L)
00440	  (COND ((NULL L) NIL)
00450		(T
00460		 (PROG (V)
00470		       (RETURN
00480			(&FORLOOP (QUOTE (I))
00490				  (QUOTE (1. 100. 1.))
00500	 			  T
00510				  (QUOTE (PROG1 (SETQ V (CONS (CAR L) V)) (SETQ L (CDR L))))
00520				  (QUOTE (NULL L)))))))) 
00530	FEXPR)
00540	
00550	(DEFPROP REVERSE7 
00560	 (LAMBDA (L) (REVERSE7A L NIL)) 
00570	FEXPR)
00580	
00590	(DEFPROP REVERSE7A 
00600	 (LAMBDA (L V)
00610	  (COND ((NULL L) NIL)
00620		(T
00630		 (&FORLOOP (QUOTE LEN)
00640			   (QUOTE (1. 100. 1.))
00650	 		   T
00660			   (QUOTE (PROG1 (SETQ V (CONS (CAR L) V)) (SETQ L (CDR L))))
00670			   (QUOTE (NULL L)))))) 
00680	EXPR)
00690	
00700	(DEFPROP PROG1 
00710	 (LAMBDA (A B) A) 
00720	EXPR)
00730	
00740	(DEFPROP RESTART 
00750	 (LAMBDA  NIL
00760	  (PROG (EXPRLIST FEXPRLIST LEN L)
00770		(SETQ EXPRLIST (QUOTE (REVERSE1 REVERSE2 REVERSE4 REVERSE5)))
00780		(SETQ FEXPRLIST (QUOTE (REVERSE3 REVERSE6 REVERSE7)))
00790		(PRINTSTR (QUOTE "TYPE A LIST TO BE REVERSED."))
00800		(&WHILEDO (QUOTE (NEQ (SETQ L (READ)) (QUOTE STOP)))
00810			  (QUOTE
00820			   (PROG (FUNCLIST)
00830				 (TERPRI)
00840				 (PRINTSTR (CAT (QUOTE "THE TEST LIST IS ") L))
00850				 (SETQ FUNCLIST
00860				       (&FOR (QUOTE (FUNCNAME))
00870					     (QUOTE (T))
00880	 				     EXPRLIST
00890					     (QUOTE (LIST (LIST FUNCNAME (LIST (QUOTE QUOTE) L))))
00900	 				     NIL))
00910				 (SETQ FUNCLIST
00920				       (APPEND FUNCLIST
00930					       (&FOR (QUOTE (FUNCNAME))
00940						     (QUOTE (T))
00950	 					     FEXPRLIST
00960						     (QUOTE (LIST (CONS FUNCNAME L)))
00970	 					     NIL)))
00980				 (&FOR (QUOTE (FUNC))
00990				       (QUOTE (T . T))
01000	 			       FUNCLIST
01010				       (QUOTE
01020					(PROG (START)
01030					      (PRINT (CAR FUNC))
01040					      (SETQ START (TIME))
01050					      (PRINT (EVAL FUNC))
01060					      (PRINT (QUOTIENT (DIFFERENCE (TIME) START) 1000.0))
01070					      (PRINTSTR (QUOTE " SECS"))
01080					      (TERPRI)))
01090	 			       NIL)
01100				 (TERPRI)
01110				 (TERPRI)
01120				 (PRINTSTR (QUOTE "TYPE ANOTHER LIST TO BE REVERSED, OR 'STOP'"))))))) 
01130	EXPR)
     
00010	FILES
00020	
00030	   THE FOLLOWING IS A REFERENCE FILE TO KEEP TRACK OF THE MLISP SOURCE FILES.
00040	
00050	
00060	
00070	FILE			CONTENTS
00080	
00090	MLISP		LISP SOURCE FILE OF THE MLISP TRANSLATOR
00100	
00110	MINIT		INITIALIZATION FOR THE MLISP TRANSLATOR (RESERVED WORDS, ET. AL.)
00120	SETFNS		INITIALIZATION OF THE MLISP GLOBALLY-DEFINED ATOMS
00130	
00140	UTILS		RUNFN1.LAP, RUNFN3.LAP, SETFNS
00150	MUTILS		RUNFN1.LAP, RUNFN3.LAP, GRINDF.LAP, MINIT, SETFNS
00160	UTILS.MAC	RUNFN2.LAP, RUNFN3.LAP, SETFNS
00170	MUTILS.MAC	MACROS.LSP, MACRO1.LAP, RUNFN3.LAP, COMPLR.LAP, COMDEF, MINIT, SETFNS
00180	
00190	RUNFN1		&FOR,&DOUNTIL,&LISTUNTIL,&WHILEDO,&WHILELIST,&FORLOOP,F1,F2,F3,F4 -- ALL IN LISP
00200	RUNFN2		F1,F2,F3,F4 -- ALL IN LISP
00210	RUNFN3		F5,F6,F7,F8,F9,STR,AT,CAT,SUBSTR,PRELIST,SUFLIST,PRINTSTR,NEQ,NEQUAL,SEQ -- ALL IN LISP
00220	MACROS		&FOR,&DOUNTIL,&LISTUNTIL,&WHILEDO,&WHILELIST,&FORLOOP,F1,F2,F3,F4 -- ALL MACROS, IN MLISP
00230	MACRO1		MACRO EXPANDING FUNCTIONS FOR THE FILE 'MACROS' -- IN MLISP
00240	
00250	GRINDF		ALL THE GRINDEF FUNCTIONS
00260	
00270	MEXPR		LISP-TO-MLISP TRANSLATOR -- IN MLISP
00280	
00290	
00300	
00310	
00320	
00330	   THE FOLLOWING IS A SUMMARY OF DATA ON 'MLISP' AND 'MLISPC'.  ALL NUMBERS ARE OCTAL EXCEPT THE CORE IMAGES.
00340	
00350	
00360						AVAILABLE	AVAILABLE	AVAILABLE
00370	NAME		   ALLOC		FREE STG.	FULL WDS.	BINARY PROG. SP.	CORE IMAGE
00380	
00390	MLISP		FULL WDS=1000		21605		1002		2517			25K WORDS
00400			BIN.PROG.SP=7000
00410			SPEC.PDL=
00420			REG. PDL=
00430			HASH=
00440	
00450	MLISPC		FULL WDS=1300		20260		1017		404			30K WORDS
00460			BIN.PROG.SP=15100
00470			SPEC.PDL=
00480			REG. PDL=
00490			HASH=
00500	
00510	
00520	
00530	FILES
00540	
00550	   THE MLISP VERSION SHOULD BE USED WHEN THE MLISP PROGRAM IS TO BE RUN INTERPRETED OR GRINDEFED OUT.
00560	TO GET IT, SAY:
00570		R MLISP    OR    R MLISP  <CORE SIZE> .
00580	THE MLISPC VERSION SHOULD BE USED WHEN THE MLISP PROGRAM IS TO BE COMPILED ONTO AN OUTPUT FILE.
00590	TO GET IT, SAY:
00600		R MLISPC   OR    R MLISPC <CORE SIZE> .
00610	
00620	   THESE TWO CORE IMAGES SHOULD BE SUFFICIENT TO HANDLE SMALL- TO INTERMEDIATE-SIZED PROGRAMS.
00630	FOR LARGER PROGRAMS, A CORE SIZE WILL HAVE TO BE SPECIFIED; THEN WHEN MLISP RETURNS WITH A STAR (*),
00640	THE USER SHOULD TYPE ^C AND REE TO ACTUALLY ALLOCATE THE EXTRA CORE.  FOR EXAMPLE:
00650	
00660		.R MLISP 30
00670		*^C
00680		.REE
00690		*
00700	
00710	THE EXTRA CORE IS ALLOCATED ACCORDING TO THE FOLLOWING FORMULA:
00720	
00730		1/4  FOR FULL WORD SPACE
00740		1/64 FOR THE SPECIAL PUSHDOWN LIST
00750		1/64 FOR THE REGULAR PUSHDOWN LIST
00760		THE REST FOR FREE STORAGE
00770	
00780	MLISP  MAY BE REGENERATED BY READING IN MLISP.LAP AND MUTILS.
00790	MLISPC MAY BE REGENERATED BY READING IN MLISP.LAP AND MUTILS.MAC .
00800	
00810	
00820	   AS MENTIONED ON PAGE 1-1, MLISP NOW MAKES USE OF A SUPER FAST, TABLE-DRIVEN SCANNER.  THE SCANNER
00830	FUNCTIONS WERE WRITTEN BY LYN QUAM, AND MODIFY THE LISP 'READ' FUNCTION.  THEY ARE WRITTEN IN DEC MACRO
00840	AND MUST BE LOADED SEPARATELY INTO THE 'MLISP' AND 'MLISPC' CORE IMAGES.
00850	
00860	   TO LOAD THE SCANNER INTO MLISP AND MLISPC, TYPE THE FOLLOWING AFTER ALL THE OTHER FILES HAVE BEEN READ IN :
00870	
00880		*(SCANNER1INIT)
00890		*SCAN[1,LSP]$			% THE SCAN FILE MUST BE IN .REL FORMAT. %
00900		*(SCANNER2INIT)
00910	
00920	   TO READ IN AN MLISP PROGRAM AFTER IT HAS BEEN GRINDEFED ONTO AN OUTPUT FILE,
00930	READ IN <THE LISP FILE> AND SYS: UTILS .
00940	   TO READ IN AN MLISP PROGRAM AFTER IT HAS BEEN GRINDEFED ONTO AN OUTPUT FILE AND THEN COMPILED,
00950	READ IN <THE LAP FILE>  AND SYS: UTILS .
00960	   TO READ IN AN MLISP PROGRAM COMPILED BY MLISPC,
00970	READ IN <THE LAP FILE>  AND SYS: UTILS.MAC .
00980