X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fdeftype.lisp;h=a0a992f838fde283d03295609bb75ffcdc4a4b88;hb=aa1a5c6ea31c248587d78f62943ad749ea8fbe2f;hp=0e02d0fbda604da6eb0e227778910d995057cc41;hpb=a530bbe337109d898d5b4a001fc8f1afa3b5dc39;p=sbcl.git diff --git a/src/compiler/deftype.lisp b/src/compiler/deftype.lisp index 0e02d0f..a0a992f 100644 --- a/src/compiler/deftype.lisp +++ b/src/compiler/deftype.lisp @@ -9,20 +9,44 @@ (in-package "SB!IMPL") -(file-comment - "$Header$") +(defun constant-type-expander (expansion) + (declare (optimize safety)) + (lambda (whole) + (if (cdr whole) + (sb!kernel::arg-count-error 'deftype (car whole) (cdr whole) nil 0 0) + expansion))) -(defmacro sb!xc:deftype (name arglist &body body) +(defun %deftype (name) + (setf (classoid-cell-pcl-class (find-classoid-cell name :create t)) nil)) + +(def!macro sb!xc:deftype (name lambda-list &body body) #!+sb-doc "Define a new type, with syntax like DEFMACRO." (unless (symbolp name) (error "type name not a symbol: ~S" name)) - (let ((whole (gensym "WHOLE-"))) - (multiple-value-bind (body local-decs doc) - (parse-defmacro arglist whole body name 'deftype :default-default ''*) - `(eval-when (:compile-toplevel :load-toplevel :execute) - (%compiler-deftype ',name - #'(lambda (,whole) - ,@local-decs - (block ,name ,body)) - ,@(when doc `(,doc))))))) + (multiple-value-bind (expander-form doc source-location-form) + (multiple-value-bind (forms decls doc) (parse-body body) + ;; FIXME: We could use CONSTANTP here to deal with slightly more + ;; complex deftypes using CONSTANT-TYPE-EXPANDER, but that XC:CONSTANTP + ;; is not availble early enough. + (if (and (not lambda-list) (not decls) (not (cdr forms)) + (or (member (car forms) '(t nil)) + (eq 'quote (caar forms)))) + (values `(constant-type-expander ,(car forms)) doc '(sb!c:source-location)) + (with-unique-names (whole) + (multiple-value-bind (macro-body local-decs doc) + (parse-defmacro lambda-list whole body name 'deftype :default-default ''*) + (values `(lambda (,whole) + ,@local-decs + ,macro-body) + doc + nil))))) + `(progn + (eval-when (:compile-toplevel :load-toplevel :execute) + (%compiler-deftype ',name + ',lambda-list + ,expander-form + ,doc + ,source-location-form)) + (eval-when (:load-toplevel :execute) + (%deftype ',name)))))