;;; -*- Mode:LISP; Package:LISP-INTERNALS; Readtable:CL; Base:10; Lowercase:T -*- 
;;;
;;;
;;; TOP-LEVEL-FORMS.LISP
;;;
;;;----------------------------------------------------------------------------
;;; Compilation considerations
;;;
;;; Compiling the definitions of such macros as DEFVAR, DEFUN, and especially 
;;; DEFMACRO is a sometimes tricky process.  If the compiler encounters a
;;; (DEFMACRO FOO ...) somewhere in a file, then any subsequent form in the 
;;; same file which contains a FOO is macroexpanded with this new definition.
;;; This is often useful, but it causes problems when we would rather use the 
;;; old FOO for macroexpanding the rest of the file.  When the FOO is a symbol
;;; like DEFVAR or DEFMACRO, trouble is inevitable.
;;;
;;; There are other hassles as well, such as what happens when we load a KENV
;;; file containing (DEFMACRO DEFVAR ...) on the lambda.
;;;
;;; To get around these problems, I am naming the K versions of DEFVAR, DEFUN,
;;; etc. with different names.  The definitions do not need to be attached to
;;; the correct names immediately.  In fact, they will only be needed when a
;;; compiler or evaluator is explicitly invoked on the K.  Since the evaluator
;;; is installed much earlier than the compiler, these definitions should be
;;; made before the evaluator is used.
;;;
;;; The first place that the evaluator is used is in the hot-boot sequence.
;;; This part of the bootstrap is run after all the evaluator code has been
;;; loaded.  The hot-boot does several things.  It uses the newly loaded
;;; evaluator to evaluate the forms on k2::*cold-eval-list* and 
;;; k2::*warm-eval-list*.  (These are the lists of forms encountered earlier in
;;; the boot which needed to be evaluated, but couldn't, until the evaluator
;;; was loaded.)  Once these matters have been attended to, the hot-boot sets
;;; a variable to inform the fasloader that the evaluator is ready.
;;;
;;; I am adding additional code to the hot-boot which creates macro definitions
;;; for DEFVAR, DEFUN, etc., by explicitly bashing their function cells.  This
;;; code will run before the evaluator tackles the eval-lists.
;;;
;;; (James Rauen 23-Feb-88 17:04:27)
;;;----------------------------------------------------------------------------


;;;----------------------------------------------------------------------------
;;; Top level forms
;;;----------------------------------------------------------------------------
;;;
;;; Technically, these should call PROCLAIM rather than explicitly putting 
;;; stuff on the symbols' property lists.
;;;
;;; DEFUN also needs to gobble documentation strings...
;;;----------------------------------------------------------------------------

(defmacro defun-K (name lambda-list &body body)
  `(PROGN (SYMBOL::SET-SYMBOL-FUNCTION 
	    ',name
	    #'(nc::NAMED-LAMBDA ,name ,lambda-list ,@body))
	  ',name))

(defmacro defvar-K (name &optional value documentation)
  `(PROGN (IF (BOUNDP ',name)
	      NIL
	      (SET ',name ,value))
	  (SYMBOL::%PUT ',name 'SPECIAL T)
	  (SYMBOL::%PUT ',name 'VAR-DOCUMENTATION ',documentation)
	  ',name))

(defmacro defparameter-K (name value &optional documentation)
  `(PROGN (SET ',name ,value)
	  (SYMBOL::%PUT ',name 'SPECIAL T)
	  (SYMBOL::%PUT ',name 'VAR-DOCUMENTATION ',documentation)
	  ',name))

(defmacro defconstant-K (name value &optional documentation)
  `(PROGN (IF (BOUNDP ',name)
;	      (ERROR "Attempting to DEFCONSTANT ~A, which already has a 
;special value." ',name)
	      (SET ',name ,value)
	      (SET ',name ,value))
	  (SYMBOL::%PUT ',name 'SPECIAL T)
	  (SYMBOL::%PUT ',name 'CONSTANT T)
	  (SYMBOL::%PUT ',name 'VAR-DOCUMENTATION ',documentation)
	  ',name))

