`(let ((,(car vars) ,value-form))
,@body)
(let ((ignore (gensym)))
- `(multiple-value-call #'(lambda (&optional ,@vars &rest ,ignore)
+ `(multiple-value-call #'(lambda (&optional ,@(mapcar #'list vars)
+ &rest ,ignore)
(declare (ignore ,ignore))
,@body)
,value-form)))
\f
;;;; various sequencing constructs
-(defmacro-mundanely prog (varlist &body body-decls)
- (multiple-value-bind (body decls) (parse-body body-decls nil)
- `(block nil
- (let ,varlist
- ,@decls
- (tagbody ,@body)))))
-
-(defmacro-mundanely prog* (varlist &body body-decls)
- (multiple-value-bind (body decls) (parse-body body-decls nil)
- `(block nil
- (let* ,varlist
- ,@decls
- (tagbody ,@body)))))
+(flet ((prog-expansion-from-let (varlist body-decls let)
+ (multiple-value-bind (body decls)
+ (parse-body body-decls :doc-string-allowed nil)
+ `(block nil
+ (,let ,varlist
+ ,@decls
+ (tagbody ,@body))))))
+ (defmacro-mundanely prog (varlist &body body-decls)
+ (prog-expansion-from-let varlist body-decls 'let))
+ (defmacro-mundanely prog* (varlist &body body-decls)
+ (prog-expansion-from-let varlist body-decls 'let*)))
(defmacro-mundanely prog1 (result &body body)
(let ((n-result (gensym)))
"Define a function at top level."
#+sb-xc-host
(unless (symbol-package (fun-name-block-name name))
- (warn "DEFUN of uninterned symbol ~S (tricky for GENESIS)" name))
+ (warn "DEFUN of uninterned function name ~S (tricky for GENESIS)" name))
(multiple-value-bind (forms decls doc) (parse-body body)
(let* (;; stuff shared between LAMBDA and INLINE-LAMBDA and NAMED-LAMBDA
(lambda-guts `(,args
(block ,(fun-name-block-name name)
,@forms)))
(lambda `(lambda ,@lambda-guts))
- #-sb-xc-host
+ #-sb-xc-host
(named-lambda `(named-lambda ,name ,@lambda-guts))
(inline-lambda
(when (inline-fun-name-p name)
name)
nil)))))
`(progn
-
- ;; In cross-compilation of toplevel DEFUNs, we arrange
- ;; for the LAMBDA to be statically linked by GENESIS.
+ ;; In cross-compilation of toplevel DEFUNs, we arrange for
+ ;; the LAMBDA to be statically linked by GENESIS.
;;
;; It may seem strangely inconsistent not to use NAMED-LAMBDA
;; here instead of LAMBDA. The reason is historical:
#+sb-xc-host
(cold-fset ,name ,lambda)
- (eval-when (:compile-toplevel :load-toplevel :execute)
- (sb!c:%compiler-defun ',name ',inline-lambda))
-
- (%defun ',name
- ;; In normal compilation (not for cold load) this is
- ;; where the compiled LAMBDA first appears. In
- ;; cross-compilation, we manipulate the
- ;; previously-statically-linked LAMBDA here.
- #-sb-xc-host ,named-lambda
- #+sb-xc-host (fdefinition ',name)
- ,doc)))))
+ (eval-when (:compile-toplevel)
+ (sb!c:%compiler-defun ',name ',inline-lambda t))
+ (eval-when (:load-toplevel :execute)
+ (%defun ',name
+ ;; In normal compilation (not for cold load) this is
+ ;; where the compiled LAMBDA first appears. In
+ ;; cross-compilation, we manipulate the
+ ;; previously-statically-linked LAMBDA here.
+ #-sb-xc-host ,named-lambda
+ #+sb-xc-host (fdefinition ',name)
+ ,doc
+ ',inline-lambda))))))
+
#-sb-xc-host
-(defun %defun (name def doc)
+(defun %defun (name def doc inline-lambda)
(declare (type function def))
(declare (type (or null simple-string) doc))
(aver (legal-fun-name-p name)) ; should've been checked by DEFMACRO DEFUN
+ (sb!c:%compiler-defun name inline-lambda nil)
(when (fboundp name)
(/show0 "redefining NAME in %DEFUN")
(style-warn "redefining ~S in DEFUN" name))
;; something sane, (1) doing so doesn't really fix the bug, and
;; (2) doing probably isn't even really safe.
#+nil (setf (%fun-name def) name)
-
+
(when doc
(setf (fdocumentation name 'function) doc))
name)
value, the old value is not clobbered. The third argument is an optional
documentation string for the variable."
`(progn
- (declaim (special ,var))
- ,@(when valp
- `((unless (boundp ',var)
- (set ',var ,val))))
- ,@(when docp
- `((setf (fdocumentation ',var 'variable) ',doc )))
- ',var))
+ (eval-when (:compile-toplevel)
+ (%compiler-defvar ',var))
+ (eval-when (:load-toplevel :execute)
+ (%defvar ',var (unless (boundp ',var) ,val) ',valp ,doc ',docp))))
(defmacro-mundanely defparameter (var val &optional (doc nil docp))
#!+sb-doc
previous value. The third argument is an optional documentation
string for the parameter."
`(progn
- (declaim (special ,var))
- (set ',var ,val)
- ,@(when docp
- `((setf (fdocumentation ',var 'variable) ',doc)))
- ',var))
+ (eval-when (:compile-toplevel)
+ (%compiler-defvar ',var))
+ (eval-when (:load-toplevel :execute)
+ (%defparameter ',var ,val ,doc ',docp))))
+
+(defun %compiler-defvar (var)
+ (sb!xc:proclaim `(special ,var)))
+
+#-sb-xc-host
+(defun %defvar (var val valp doc docp)
+ (%compiler-defvar var)
+ (when valp
+ (unless (boundp var)
+ (set var val)))
+ (when docp
+ (setf (fdocumentation var 'variable) doc))
+ var)
+
+#-sb-xc-host
+(defun %defparameter (var val doc docp)
+ (%compiler-defvar var)
+ (set var val)
+ (when docp
+ (setf (fdocumentation var 'variable) doc))
+ var)
\f
;;;; iteration constructs
(defmacro-mundanely dotimes ((var count &optional (result nil)) &body body)
(cond ((numberp count)
`(do ((,var 0 (1+ ,var)))
- ((>= ,var ,count) ,result)
- (declare (type unsigned-byte ,var))
- ,@body))
+ ((>= ,var ,count) ,result)
+ (declare (type unsigned-byte ,var))
+ ,@body))
(t (let ((v1 (gensym)))
`(do ((,var 0 (1+ ,var)) (,v1 ,count))
- ((>= ,var ,v1) ,result)
- (declare (type unsigned-byte ,var))
- ,@body)))))
+ ((>= ,var ,v1) ,result)
+ (declare (type unsigned-byte ,var))
+ ,@body)))))
(defmacro-mundanely dolist ((var list &optional (result nil)) &body body)
;; We repeatedly bind the var instead of setting it so that we never
;; environment. We spuriously reference the gratuitous variable,
;; since we don't want to use IGNORABLE on what might be a special
;; var.
- (multiple-value-bind (forms decls) (parse-body body nil)
- (let ((n-list (gensym)))
- `(do* ((,n-list ,list (cdr ,n-list)))
- ((endp ,n-list)
- ,@(if result
- `((let ((,var nil))
- ,var
- ,result))
- '(nil)))
- (let ((,var (car ,n-list)))
- ,@decls
- (tagbody
- ,@forms))))))
+ (multiple-value-bind (forms decls) (parse-body body :doc-string-allowed nil)
+ (let ((n-list (gensym "N-LIST"))
+ (start (gensym "START")))
+ `(block nil
+ (let ((,n-list ,list))
+ (tagbody
+ ,start
+ (unless (endp ,n-list)
+ (let ((,var (car ,n-list)))
+ ,@decls
+ (setq ,n-list (cdr ,n-list))
+ (tagbody ,@forms))
+ (go ,start))))
+ ,(if result
+ `(let ((,var nil))
+ ,var
+ ,result)
+ nil)))))
\f
;;;; conditions, handlers, restarts
,n-cond
(car *restart-clusters*)
,(if (eq name 'cerror)
- `(cerror ,(second expression) ,n-cond)
+ `(cerror ,(second exp) ,n-cond)
`(,name ,n-cond))))
expression))
expression)))
`(let ((,(caaddr annotated-case)
,var))
,@body))
- ((not (cdr body))
- (car body))
(t
- `(progn ,@body)))))))
+ `(locally ,@body)))))))
annotated-cases))))))))
\f
;;;; miscellaneous
;; functions appearing in fundamental defining
;; macro expansions:
%compiler-deftype
+ %compiler-defvar
%defun
%defsetf
+ %defparameter
+ %defvar
sb!c:%compiler-defun
sb!c::%define-symbol-macro
sb!c::%defconstant