(!begin-collecting-cold-init-forms)
-;;; Has the type system been properly initialized? (I.e. is it OK to
-;;; use it?)
-(defvar *type-system-initialized* #+sb-xc-host nil) ; (set in cold load)
-\f
;;;; representations of types
;;; A HAIRY-TYPE represents anything too weird to be described
(defun args-types (lambda-list-like-thing)
(multiple-value-bind
- (required optional restp rest keyp keys allowp auxp aux)
+ (required optional restp rest keyp keys allowp auxp aux
+ morep more-context more-count llk-p)
(parse-lambda-list-like-thing lambda-list-like-thing)
- (declare (ignore aux))
+ (declare (ignore aux morep more-context more-count))
(when auxp
(error "&AUX in a FUNCTION or VALUES type: ~S." lambda-list-like-thing))
(let ((required (mapcar #'single-value-specifier-type required))
(key-info))))
(multiple-value-bind (required optional rest)
(canonicalize-args-type-args required optional rest)
- (values required optional rest keyp keywords allowp)))))
+ (values required optional rest keyp keywords allowp llk-p)))))
(defstruct (values-type
(:include args-type
:rest rest
:allowp allowp))
-;;; FIXME: ANSI VALUES has a short form (without lambda list
-;;; keywords), which should be translated into a long one.
(defun make-values-type (&key (args nil argsp)
required optional rest allowp)
(if argsp
(if (eq args '*)
*wild-type*
- (multiple-value-bind (required optional rest keyp keywords allowp)
+ (multiple-value-bind (required optional rest keyp keywords allowp
+ llk-p)
(args-types args)
(declare (ignore keywords))
(when keyp
(error "&KEY appeared in a VALUES type specifier ~S."
`(values ,@args)))
- (make-values-type :required required
- :optional optional
- :rest rest
- :allowp allowp)))
+ (if llk-p
+ (make-values-type :required required
+ :optional optional
+ :rest rest
+ :allowp allowp)
+ (make-short-values-type required))))
(multiple-value-bind (required optional rest)
(canonicalize-args-type-args required optional rest)
(cond ((and (null required)
;;; (SPECIFIER-TYPE 'FUNCTION) and its subtypes
(defstruct (fun-type (:include args-type
(class-info (type-class-or-lose 'function)))
- (:constructor %make-fun-type))
+ (:constructor
+ %make-fun-type (&key required optional rest
+ keyp keywords allowp
+ wild-args
+ returns
+ &aux (rest (if (eq rest *empty-type*)
+ nil
+ rest)))))
;; true if the arguments are unrestrictive, i.e. *
(wild-args nil :type boolean)
;; type describing the return values. This is a values type
:enumerable enumerable))
;;; An ARRAY-TYPE is used to represent any array type, including
-;;; things such as SIMPLE-STRING.
+;;; things such as SIMPLE-BASE-STRING.
(defstruct (array-type (:include ctype
(class-info (type-class-or-lose 'array)))
(:constructor %make-array-type)
;;; A CONS-TYPE is used to represent a CONS type.
(defstruct (cons-type (:include ctype (class-info (type-class-or-lose 'cons)))
(:constructor
- ;; ANSI says that for CAR and CDR subtype
- ;; specifiers '* is equivalent to T. In order
- ;; to avoid special cases in SUBTYPEP and
- ;; possibly elsewhere, we slam all CONS-TYPE
- ;; objects into canonical form w.r.t. this
- ;; equivalence at creation time.
- %make-cons-type (car-raw-type
- cdr-raw-type
- &aux
- (car-type (type-*-to-t car-raw-type))
- (cdr-type (type-*-to-t cdr-raw-type))))
+ %make-cons-type (car-type
+ cdr-type))
(:copier nil))
;; the CAR and CDR element types (to support ANSI (CONS FOO BAR) types)
;;
(car-type (missing-arg) :type ctype :read-only t)
(cdr-type (missing-arg) :type ctype :read-only t))
(defun make-cons-type (car-type cdr-type)
+ (aver (not (or (eq car-type *wild-type*)
+ (eq cdr-type *wild-type*))))
(if (or (eq car-type *empty-type*)
(eq cdr-type *empty-type*))
*empty-type*
(%make-cons-type car-type cdr-type)))
+
+(defun cons-type-length-info (type)
+ (declare (type cons-type type))
+ (do ((min 1 (1+ min))
+ (cdr (cons-type-cdr-type type) (cons-type-cdr-type cdr)))
+ ((not (cons-type-p cdr))
+ (cond
+ ((csubtypep cdr (specifier-type 'null))
+ (values min t))
+ ((csubtypep *universal-type* cdr)
+ (values min nil))
+ ((type/= (type-intersection (specifier-type 'cons) cdr) *empty-type*)
+ (values min nil))
+ ((type/= (type-intersection (specifier-type 'null) cdr) *empty-type*)
+ (values min t))
+ (t (values min :maybe))))
+ ()))
+
\f
;;;; type utilities
(or (built-in-classoid-translation spec) spec)
spec))
(t
- (let* (;; FIXME: This automatic promotion of FOO-style
- ;; specs to (FOO)-style specs violates the ANSI
- ;; standard. Unfortunately, we can't fix the
- ;; problem just by removing it, since then things
- ;; downstream should break. But at some point we
- ;; should fix this and the things downstream too.
- (lspec (if (atom spec) (list spec) spec))
+ (when (and (atom spec)
+ (member spec '(and or not member eql satisfies values)))
+ (error "The symbol ~S is not valid as a type specifier." spec))
+ (let* ((lspec (if (atom spec) (list spec) spec))
(fun (info :type :translator (car lspec))))
(cond (fun
(funcall fun lspec))
- ((or (and (consp spec) (symbolp (car spec)))
- (symbolp spec))
+ ((or (and (consp spec) (symbolp (car spec))
+ (not (info :type :builtin (car spec))))
+ (and (symbolp spec) (not (info :type :builtin spec))))
(when (and *type-system-initialized*
(not (eq (info :type :kind spec)
:forthcoming-defclass-type)))
;;; never return a VALUES type.
(defun specifier-type (x)
(let ((res (values-specifier-type x)))
- (when (values-type-p res)
+ (when (or (values-type-p res)
+ ;; bootstrap magic :-(
+ (and (named-type-p res)
+ (eq (named-type-name res) '*)))
(error "VALUES type illegal in this context:~% ~S" x))
res))
(defun single-value-specifier-type (x)
- (let ((res (specifier-type x)))
- (if (eq res *wild-type*)
- *universal-type*
- res)))
+ (if (eq x '*)
+ *universal-type*
+ (specifier-type x)))
;;; Similar to MACROEXPAND, but expands DEFTYPEs. We don't bother
;;; returning a second value.
(let ((def (cond ((symbolp form)
(info :type :expander form))
((and (consp form) (symbolp (car form)))
- (info :type :expander (car form)))
+ (info :type :expander (car form)))
(t nil))))
(if def
(type-expand (funcall def (if (consp form) form (list form))))
(when (boundp 'sb!kernel::*values-specifier-type-cache-vector*)
(values-specifier-type-cache-clear))
(values))
+
\f
(!defun-from-collected-cold-init-forms !early-type-cold-init)