2/7/75   - JONL AND GLS -

BRIEF SYNOPSIS:
[1] THE VALUE OF PRIN1 CONTROLS USE OF PRIN1 BY LISP.
[2] NEW COMPLR SWITCHES, AND DECLARATIONS, AND THINGS:
	[2A] ^^ NOW ENTERS MAKLAP.
	[2B] COMPILER-STATE TO DETERMINE STATE OF COMPILER.
	[2C] EXPR-HASH (E SWITCH) FOR FUNCTION HASHING.
	[2D] THE GLOBAL VARIABLE "SOBARRAY" HOLDS THE ARRAY POINTER 
	     TO THE STANDARD LISP OBARRAY.
	[2E] EOC-EVAL TO EVAL THINGS AFTER COMPILATION IS COMPLETED.
	[2F] COUTPUT TO OUTPUT THINGS TO THE LAP FILE.
	[2G] DONT EVER, BUT EVER, USER "QUOTE" AS A LAMBDA OR 
	     PROG VARIABLE.
[3] VALUE OF DEFUN CONTROLS EXPR-HASH CROCK IN INTERPRETER.
[4] USE PLIST AND SETPLIST TO ACCESS AND STORE PROPERTY LISTS
[5] "ROMAN" APPEARS ON THE FEATURE LIST [GOTTEN BY (STATUS FEATURES),
    OR TESTED BY (STATUS FEATURE ROMAN)] IF THAT HACK IS ASSEMBLED IN.
[6] ON A DEC-10 MONITOR, (STATUS JNAME) RETURNS "NNNLSP".
[7] _ FIXNUM OUTPUT FORMAT EXTENDED TO _22, _11.
[8] (STATUS FREE ...), (SSTATUS FREE ...) FLUSHED.
[9] MANY CHANGES TO THE BREAK AND *BREAK FUNCTIONS:
	[4A] BREAK OF THREE ARGUMENTS NO LONGER EXISTS.
	[4B] BREAK/*BREAK LAMBDA-BIND *, +, -.
	[4C] ([S]STATUS BREAKLEVEL) IS LIKE ([S]STATUS TOPLEVEL).
	[4D] BREAK USES A CATCH; (THROW <VALUE> BREAK) EXITS.
    ALSO, AN ATTEMPT TO EXPLAIN BREAK AND TOPLEVEL IN EXPR CODE

----------------------------------------------------------------

[1] THE VALUE OF THE ATOM "PRIN1" NOW CONTROLS THE ACTION OF
    PRINTING BY THE TOP-LEVEL AND BREAK ROUTINES.  IN SHORT, AN
    ITEM X RESULTING FROM THE EVALUATION IN THESE LOOPS IS
    PRINTED LIKE 
	     (COND (PRIN1 (FUNCALL PRIN1 X)) 
		   (T     (PRIN1 X)))
    THIS FEATURE EXISTS PRIMARILY FOR THE OWL SYSTEM, WHICH HAS 
    CIRCULAR LIST STRUCTURE ABUNDANT, AND DOESN'T NEED TO
    REWRITE THE ENTIRE TOP-LEVEL ROUTINE MERELY TO ACCOUNT FOR 
    THE PRINTING OF CIRCULAR STRUCTURE.

[2] SOME NEW SWITCHES AND DECLARATIONS FOR THE COMPILER:
  [2A] TYPING ^^ NOW ENTERS MAKLAP [JUST AS IN MACSYMA, WHERE ^^
	DOES A (CONTINUE)].
  [2B] COMPILER-STATE
	THIS VARIABLE REVEALS TO THE USER ONE OF THREE STATES
	THAT THE COMPILER MAY BE IN, AND IS OF INTEREST TO 
	SOMEONE WHO WANTS TO WRITE SOPHISTICATED MACROS WHICH
	EXPAND  IN DIFFERENT WAYS DEPENDING ON THE REASON FOR
	THE EXPANSION.  POSSIBLE VALUES FOR COMPILER-STATE:
	  [2B1] "TOPLEVEL"
		THE COMPILER IS AT THE TOP LEVEL OF LISP.
	  [2B2] "MAKLAP"
		THE COMPILER IS SCANNING AN INPUT FILE LOOKING
		FOR FUNCTION DEFINITIONS TO COMPILE.  IN THIS
		STATE THE COMPILER WILL EXPAND ANY TOP-LEVEL
		FORM (FOO ...) FOR WHICH FOO HAS A MACRO
		PROPERTY TO SEE IF A FUNCTION DEFINITION IS
		PRODUCED [WHICH WOULD THEN BE COMPILED].
	  [2B3] "COMPILE"
		THE COMPILER IS ACTUALLY COMPILING A FORM
		WHICH IS A FUNCTION DEFINITION, PRODUCING
		LAP CODE.  IN THIS STATE ANY SUB-FORM
		(FOO ...) WHICH IS TO BE COMPILED IS EXPANDED
		IF FOO HAS A MACRO PROPERTY.
	RANDOM EXAMPLE:
	WHEN A FUNCTION IS DEFINED YOU WANT THE FLATSIZE OF
	THE DEFINITION TO BE PUT ON THE PROPERTY LIST OF
	THE FUNCTION.  IF THE FUNCTION IS COMPILED, YOU WANT
	TO ARRANGE TO OUTPUT AN APPROPRIATE DEFPROP INTO
	THE LAP FILE.
	(DEFUN STRANGE-DEFUN MACRO (FORM)
	       ;DO THE MACRO THING (NOT HAIRY)
	       (RPLACA FORM 'DEFUN)
	       ;NOW HACK THE FLATSIZE THING
	       (COND ((OR (NULL (BOUNDP COMPILER-STATE))
			  (EQ COMPILER-STATE 'TOPLEVEL))
		      ;IF INTERPRETING, OR AT COMPILER TOPLEVEL,
		      ; JUST GO AHEAD AND DO THE PUTPROP
		      (PUTPROP (CADR FORM)
			       (FLATSIZE FORM)
			       'STRANGE-FLATSIZE))
		     
		     ((EQ COMPILER-STATE 'MAKLAP)
		      ;IF COMPILING A TOP-LEVEL FORM FROM A FILE,
		      ; ARRANGE FOR A DEFPROP IN THE LAP FILE
		      (COUTPUT (LIST 'DEFPROP
				      (CADR FORM)
				      (FLATSIZE FORM)
				      'STRANGE-FLATSIZE)))
		     ((EQ COMPILER-STATE 'COMPILE)
		      ;WE DON'T WANT A DEFPROP IN THE
		      ; MIDDLE OF ANY LAP CODE!
		      (ERROR 'STRANGE-DEFUN/ IN/ SUBFORM
			     FORM
			     'FAIL-ACT))))
  [2C] EXPR-HASH
	THIS FEATURE CONTROLS THE AUTOMATIC OUTPUTTING BY THE 
	COMPILER OF A DEFPROP FOR EACH FUNCTION COMPILED WHICH
	DEFINES AN "EXPR-HASH" PROPERTY FOR THAT FUNCTION.  THIS
	PROPERTY IS A NUMBER, WHICH IS THE SXHASH OF THE
	LAMBDA-FORM STORED AS THE EXPR PROPERTY OF THE FUNCTION
	WHEN USED IN EXPRFORM.  THE INTENDED USE OF THIS IS TO
	HAVE A QUICK, AUTOMATIC SCHEME TO DECIDE WHICH FUNCTIONS
	HAVE BEEN EDITED SINCE COMPILATION, AND TO READ IN THE
	EXPR VERSIONS OF THOSE CHANGED FUNCTIONS.  STORING THE
	SXHASH OF THE LAMBDA DEFINITION OF THE FUNCTION LENDS
	ITSELF TO SIMPLE, QUICK, AND NON-SPACE-CONSUMING (IF NOT
	COMPLETELY FOOLPROOF) METHODS.  IT IS SET EITHER BY
	A DECLARATION
		(DECLARE (EXPR-HASH <T-OR-NIL>))
	OR BY USING THE "E" SWITCH IN THE MAKLAP COMMAND LINE.
	[SEE ITEM [3] BELOW FOR AN ASSOCIATED CHANGE IN DEFUN.]
  [2D] SOBARRAY 
	THIS VARIABLE HOLDS A POINTER TO THE STANDARD LISP OBARRAY, 
	IN WHICH THE COMPILER ITSELF IS RESIDENT.   "COBARRAY" HOLDS 
	THE ARRAY POINTER TO THE COMPILER'S OBARRAY USED WHILE 
	COMPILING FILES.  THESE TWO VARIABLES FACILITATE WRITING 
	OBARRAY-SWITCHING FUNCTIONS.
  [2E] EOC-EVAL
	THIS VARIABLE HOLDS A LIST OF FORMS TO BE EVALUATED
	AFTER COMPILATION OF A FILE HAS BEEN COMPLETED.  ONE CAN
	SET IT FROM A DECLARE, OR USE THE FUNCTION "EOC-EVAL"
	WHICH CONSES THE ITEMS OF THE CALLING FORM ONTO THE LIST
	STORED IN EOC-EVAL.  AT THE TIME OF COMPLETION OF
	COMPILATION, (MAPC 'EVAL EOC-EVAL) IS DONE.
	EOC-EVAL IS RESET BY INITIALIZATION, OR BY THE WHIM
	OF THE USER.
  [2F] COUTPUT
	THIS FUNCTION SHOULD BE USED TO OUTPUT RANDOM FORMS
	TO THE LAP FILE.  THIS IS CURRENTLY DONE BY USING
	PRINT; THUS ONE USED TO SAY, FOR EXAMPLE
		(DECLARE (PRINT (LIST 'SETQ
				      'VERSION
				      (CADR (STATUS UREAD)))))
	IT IS ANTICIPATED, HOWEVER, THAT EVENTUALLY THE COMPILER
	MAY NOT WRITE A LAP FILE, BUT WILL BUFFER UP FORMS
	FOR THE ASSEMBLY PASS.  THEREFORE THE FUNCTION
	COUTPUT SHOULD BE USED INSTEAD:
		(DECLARE (COUTPUT (LIST 'SETQ
					'VERSION
					(CADR (STATUS UREAD)))))
	WHICH WILL DO THE CORRECT THING IN THE FUTURE
	WHEN THE BUFFERING MODE MATERIALIZES.

[3] THE VALUE OF THE VARIABLE DEFUN CONTROLS A CROCK IN THE
    WORKINGS OF THE FUNCTION DEFUN.  IF THE VALUE OF DEFUN
    IS NON-NIL, THEN EVALUATING (DEFUN FOO ...) WILL SUCCEED
    IN CREATING THE NEW DEFINITION ONLY IF EITHER:
	[A] FOO HAS NO EXPR-HASH PROPERTY.
	[B] FOO HAS AN EXPR-HASH PROPERTY, BUT IT IS NOT
	    THE SAME AS SXHASH OF THE LAMBDA FORM FOR THE
	    NEW DEFINITION.
    THUS A POOR MAN'S WAY TO USE THE COMPILER'S EXPR-HASH
    FEATURE IS TO COMPILE A  FILE WITH THE (E) SWITCH,
    LOAD IT INTO A LISP, EDIT THE FILE SOME, DO (SETQ DEFUN T),
    THEN JUST READ IN THE UPDATED SOURCE, AND THE EXPR-HASH
    SCHEME WILL (PROBABLY) REDEFINE ONLY THOSE FUNCTIONS
    WHICH HAVE CHANGED, AND LEAVE THE SUBR VERSIONS IN FORCE
    FOR UNCHANGED FUNCTIONS, PROBABLY.

[4] THE NEW SUBR OF ONE ARGUMENT, PLIST, IS USED TO RETRIEVE THE 
    PROPERTY LIST OF A SYMBOL;  THIS FUNCTION WORKS ON ALL SYMBOLS 
    INCLUDING NIL, WHEREAS CDR WILL WORK ONLY FOR NON-NULL SYMBOLS 
    IN NON-*RSET MODE.  SIMILAR REMARKS HOLD FOR THE NEW SUBR OF TWO 
    ARGUMENTS, SETPLIST.  (SETPLIST X (PLIST X)) SHOULD BE A NOOP.

[5] IF "ROMAN" IS A FEATURE OF THE LISP YOU ARE USEING, THEN
    YOU CAN TRY (SETQ IBASE 'ROMAN) OR (SETQ BASE 'ROMAN) FOR
    FUN AND GAMES;  OTHERWISE, NO.

[6] IN THE DEC-10 VERSION OF MACLISP, (STATUS JNAME) RETURNS
    THE ATOMIC SYMBOL "NNNLSP", WHERE NNN IS THE JOB NUMBER
    IN DECIMAL.  THIS IS A STANDARD FIRST FILE NAME FOR
    TEMPORARY FILES, ETC.

[7] TO MAKE THE _ FORMAT OF FIXNUM OUTPUT MORE USEFUL,
    THE FOLLOWING FORMATS ARE NOW USED [WHEN IBASE IS 8
    AND (STATUS _) IS T]:
	IF THE NUMBER IS SMALLER THAN 2**18., 
	   OR IF THE LOW NINE BITS IN THE BINARY REPRESENTATION 
	   ARE NOT ALL ZERO, 
	  THEN THE _ FORMAT IS NOT USED.
	IF THE LOW 41 BITS ARE ALL ZERO, THEN N_41 IS USED.
	IF THE LOW 33 BITS ARE ALL ZERO, THEN N_33 IS USED.
	IF THE LOW 22 BITS ARE ALL ZERO, THEN N_22 IS USED.
	OTHERWISE, N_11 IS USED.
    NOTE THAT THESE CORRESPOND TO QUARTER-WORD BOUNDARIES
    (EXCEPT N_41); BUT N_11 IS NOT USED IF 6 OR FEWER
    DIGITS WOULD SUFFICE.

[8] (STATUS FREE ...) AND (SSTATUS FREE ...) HAVE BEEN, OR
    SOON WILL BE, FLUSHED, SINCE THEY ARE OBSOLETE AND
    MAINLY A PAIN TO MAINTAIN.

[9] MANY CHANGES TO THE BREAK FUNCTION:
	[9A] BREAK OF THREE ARGUMENTS HAS BEEN FLUSHED.
	     (THE THIRD ARGUMENT USED TO BE A FORM TO BE
	     EVALUATED IF P WERE TYPED.)
	[9B] *BREAK (ERGO ALSO BREAK) NOW LAMBDA-BINDS
	     *, +, AND - TO THEIR OWN CURRENT VALUES SO THAT
	     THEY WILL BE RESTORED ON EXIT FROM THE BREAK.
	[9C] (STATUS BREAKLEVEL) AND (SSTATUS BREAKLEVEL <FORM>)
	     ARE ANALOGOUS TO (STATUS TOPLEVEL) AND
	     (SSTATUS TOPLEVEL <FORM>).  THE DEFAULT BREAKLEVEL,
	     LIKE THE DEFAULT TOPLEVEL, IS A READ-EVAL-PRINT
	     LOOP WHICH UPDATES *, +, AND - PROPERLY.
	[9D] BREAK HAS BEEN REDEFINED USING CATCH, WITH A
	     CATCH-TAG OF "BREAK".  IF AT ANY TIME WITHIN A
	     BREAK THE FORM (THROW <VALUE> BREAK) IS EXECUTED,
	     THE BREAK (OR *BREAK) FUNCTION WILL BE EXITED,
	     RETURNING <VALUE>.  THUS, FOR EXAMPLE, IF ONE
	     TIRES OF TYPING (RETURN '(FOO)) TO UNBND-VRBL
	     BREAKS OR WHATEVER, ONE MIGHT DEFINE A MACRO-
	     CHARACTER
		(SETSYNTAX '/: 'MACRO
			   '(LAMBDA NIL
				    (THROW (LIST (READ)) BREAK)))
	     AND SIMPLY TYPE  :FOO  AT THE UNBND-VRBL BREAK
	     TO USE THE VARIABLE FOO INSTEAD.

    BELOW IS A NEW DEFINITION OF THE BREAK AND *BREAK FUNCTIONS W
    WRITTEN IN LISP, AS WELL AS A HALF-HEARTED ATTEMPT AT
    EXPLAINING THE TOP LEVEL LOOP.

(DEFUN BREAK FEXPR (X)
       (*BREAK (EVAL (CADR X)) (CAR X))	;NOTE ARGUMENT REVERSAL

;;; THE FIRST ARGUMENT TO BREAK IS A SWITCH, WHICH IF NIL CAUSES 
;;; IMMEDIATE EXIT WITH NOTHING BEING DONE; 
;;; OTHERWISE, THE VARIABLES ^Q, ^W, AND EVALHOOK ARE BOUND
;;; TO NIL, AND THE VARIABLES *, +, AND - ARE BOUND TO THEIR
;;; CURRENT VALUES, AND THE MESSAGE ";BKPT <BREAKID>" IS PRINTED.
;;; A READ-EVAL-PRINT LOOP SIMILAR TO THE TOP LEVEL LOOP
;;; IS THEN ENTERED.  THIS BREAK LOOP IS SURROUNDED BY AN
;;; ERRSET AND A CATCH.  ERRORS MERELY CAUSE THE BREAK
;;; LOOP TO BE RE-ENTERED.
;;; THE VALUE OF (STATUS BREAKLEVEL) SERVES A FUNCTION
;;; SIMILAR TO THAT OF (STATUS TOPLEVEL) IN THE TOP LEVEL
;;; LOOP.
;;; AS EACH FORM IS READ IN THE DEFAULT BREAK LOOP, THERE ARE
;;; FOUR CASES:
;;;	[1] END OF FILE.  THIS INDICATES OVER-RUBOUT AND
;;;	    SIMPLY CAUSES A TERPRI.
;;;	[2] THE FORM IS THE ATOM P.  *BREAK RETURNS NIL.
;;;	[3] THE FORM IS (RETURN <VALUE>).  THE FORM <VALUE>
;;;	    IS EVALUATED AND RETURNED.
;;;	[4] OTHERWISE, THE FORM IS EVALUATED AND THE RESULT
;;;	    PRINTED OUT IN A MANNER ANALOGOUS TO THE TOP
;;;	    LEVEL READ-EVAL-PRINT LOOP.  THE VARIABLES +, -,
;;;	    AND * ARE UPDATED APPROPRIATELY.  (RECALL, HOWEVER,
;;;	    THAT THEY WERE BOUND ON ENTRY TO *BREAK, AND SO
;;;	    WILL BE RESTORED EVENTUALLY.)
;;; THE WAY TO RETURN FROM A BREAK IS TO DO A THROW WITH
;;; A TAG OF "BREAK"; THIS WILL RETURN FROM THE CATCH WHICH
;;; SURROUNDS THE BREAK LOOP.  THIS IS HOW CASES [2] AND [3]
;;; RETURN THEIR VALUES; CASE [4] MAY ALSO CAUSE A RETURN FROM
;;; THE BREAK.

(DECLARE (SPECIAL Q ^W EVALHOOK * + -))

(DEFUN *BREAK (BREAKP BREAKID)
       (AND BREAKP
   	    ((LAMBDA (^Q ^W EVALHOOK * + -)
		     (TERPRI)
		     (PRINC '/;BKPT/ )
		     (PRINC BREAKID)
		     (SETQ + -)
		     (CATCH (DO NIL
				(NIL)
				(ERRSET (DO ((EOF (LIST NIL)) (FORM))
					    (NIL)
					    (COND ((STATUS BREAKLEVEL)
						   (EVAL (STATUS BREAKLEVEL)))
						  (T (SETQ FORM (READ EOF))
						     (COND ((EQ FORM EOF) (TERPRI))
							   ((EQ FORM 'P)
							    (THROW NIL BREAK))
							   ((EQ (CAR FORM) 'RETURN)
							    (THROW (EVAL (CADR FORM))
								   BREAK))
							   (T (SETQ - FORM)
							      (SYSPRINT (SETQ *
									      ((LAMBDA (+)
										       (EVAL FORM))
									       (PROG2 NIL +
										      (SETQ + -)))))
							      (TERPRI))))))))
			    BREAK)
		     (OR (STATUS LINMODE) (TERPRI)))
	     NIL
	     NIL
	     NIL
	     *
	     +
	     -)))

(DEFUN SYSPRINT (X)		;INTERNAL PRINTING FUNCTION
       (OR (STATUS LINMODE) (TERPRI))
       (COND (PRIN1 (FUNCALL PRIN1 X))
	     (T (PRIN1 X)))
       (TYO 40))

(DEFUN STANDARD-TOP-LEVEL NIL
       (PROG (^Q ^W ^R EVALHOOK BASE IBASE ...)
	ERRS		;ERRORS, UNCAUGHT THROWS, ETC. COME HERE
	     (RESET-BOUND-VARS)
	^G		;^G QUITS COME HERE
	     (RESET-INTERNAL-TOP-LEVEL-VARS)
	     (RESTORE-THE-WORLD)
	     (DO-DELAYED-INTERRUPTS)
;RECALL THAT ERRORS DO (SETQ // ERRLIST) SO LAMBDA-BINDING ERRLIST WORKS
	     (MAPC (FUNCTION EVAL) //)
	     (AND (STATUS LINMODE) (TERPRI))
	     (SETQ * '*)
	     (DO ((EOF (LIST NIL))) (NIL)
		 (RESET-INTERNAL-TOP-LEVEL-VARS)
		 (SETQ * (COND ((STATUS TOPLEVEL)
				(EVAL (STATUS TOPLEVEL)))
			       (T (SYSPRINT *)
				  (TERPRI)
				  (DO ((FORM (READ EOF) (READ EOF)))
				      ((NOT (EQ FORM EOF))
				       (SETQ - FORM))
				      (TERPRI))
				  ((LAMBDA (+) (EVAL -))
				   (PROG2 NIL + (SETQ + -)))))))))

(DEFUN RESTORE-THE-WORLD NIL
       (RESET-THE-PDLS)
       (SETQ ^Q NIL)
       (SETQ EVALHOOK NIL)
       (RESTORE-THE-IO-SYSTEM)
       (ENABLE-SYSTEM-INTERRUPTS)
       (RESET-INTERNAL-GC-MARK-BITS))

(DEFUN DO-DELAYED-INTERRUPTS NIL
       (OR INTERNAL-NOINTERRUPT-SWITCH
	   (PROCESS-PENDING-ALARMCLOCK-AND-TTY-INTERRUPTS)))