X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fearly-type.lisp;h=43394ffa6d9e5a571897202d0ef1736a4745aab2;hb=02c9007b4ca5753406f60019f4fe5e5f8392541a;hp=6dfad22385e434b721bdaddde87a541546701d20;hpb=80304981972c91c1b3f3fca75f36dacf1fecf307;p=sbcl.git diff --git a/src/code/early-type.lisp b/src/code/early-type.lisp index 6dfad22..43394ff 100644 --- a/src/code/early-type.lisp +++ b/src/code/early-type.lisp @@ -23,10 +23,11 @@ ;;; the original type spec. (defstruct (hairy-type (:include ctype (class-info (type-class-or-lose 'hairy)) - (enumerable t)) + (enumerable t) + (might-contain-other-types-p t)) (:copier nil) #!+cmu (:pure nil)) - ;; the Common Lisp type-specifier + ;; the Common Lisp type-specifier of the type we represent (specifier nil :type t)) (!define-type-class hairy) @@ -37,6 +38,18 @@ (defstruct (unknown-type (:include hairy-type) (:copier nil))) +(defstruct (negation-type (:include ctype + (class-info (type-class-or-lose 'negation)) + ;; FIXME: is this right? It's + ;; what they had before, anyway + (enumerable t) + (might-contain-other-types-p t)) + (:copier nil) + #!+cmu (:pure nil)) + (type (missing-arg) :type ctype)) + +(!define-type-class negation) + ;;; ARGS-TYPE objects are used both to represent VALUES types and ;;; to represent FUNCTION types. (defstruct (args-type (:include ctype) @@ -57,7 +70,9 @@ (defstruct (values-type (:include args-type (class-info (type-class-or-lose 'values))) + (:constructor %make-values-type) (:copier nil))) +(define-cached-synonym make-values-type) (!define-type-class values) @@ -180,6 +195,11 @@ (t ;; no canonicalization necessary (values low high))) + (when (and (eq class 'rational) + (integerp canonical-low) + (integerp canonical-high) + (= canonical-low canonical-high)) + (setf class 'integer)) (%make-numeric-type :class class :format format :complexp complexp @@ -206,6 +226,7 @@ ;;; things such as SIMPLE-STRING. (defstruct (array-type (:include ctype (class-info (type-class-or-lose 'array))) + (:constructor %make-array-type) (:copier nil)) ;; the dimensions of the array, or * if unspecified. If a dimension ;; is unspecified, it is *. @@ -216,6 +237,7 @@ (element-type (missing-arg) :type ctype) ;; the element type as it is specialized in this implementation (specialized-element-type *wild-type* :type ctype)) +(define-cached-synonym make-array-type) ;;; A MEMBER-TYPE represent a use of the MEMBER type specifier. We ;;; bother with this at this level because MEMBER types are fairly @@ -230,7 +252,8 @@ ;;; A COMPOUND-TYPE is a type defined out of a set of types, the ;;; common parent of UNION-TYPE and INTERSECTION-TYPE. -(defstruct (compound-type (:include ctype) +(defstruct (compound-type (:include ctype + (might-contain-other-types-p t)) (:constructor nil) (:copier nil)) (types nil :type list :read-only t)) @@ -246,6 +269,7 @@ (class-info (type-class-or-lose 'union))) (:constructor %make-union-type (enumerable types)) (:copier nil))) +(define-cached-synonym make-union-type) ;;; An INTERSECTION-TYPE represents a use of the AND type specifier ;;; which we couldn't canonicalize to something simpler. Canonical form: @@ -275,7 +299,7 @@ type)) ;;; A CONS-TYPE is used to represent a CONS type. -(defstruct (cons-type (:include ctype (:class-info (type-class-or-lose 'cons))) +(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 @@ -283,17 +307,22 @@ ;; 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-raw-type + cdr-raw-type + &aux + (car-type (type-*-to-t car-raw-type)) + (cdr-type (type-*-to-t cdr-raw-type)))) (:copier nil)) ;; the CAR and CDR element types (to support ANSI (CONS FOO BAR) types) ;; ;; FIXME: Most or all other type structure slots could also be :READ-ONLY. (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) + (if (or (eq car-type *empty-type*) + (eq cdr-type *empty-type*)) + *empty-type* + (%make-cons-type car-type cdr-type))) ;;;; type utilities @@ -304,15 +333,10 @@ ;;; type is defined (or redefined). (defun-cached (values-specifier-type :hash-function (lambda (x) - ;; FIXME: The THE FIXNUM stuff is - ;; redundant in SBCL (or modern CMU - ;; CL) because of type inference. - (the fixnum - (logand (the fixnum (sxhash x)) - #x3FF))) + (logand (sxhash x) #x3FF)) :hash-bits 10 :init-wrapper !cold-init-forms) - ((orig eq)) + ((orig equal-but-no-car-recursion)) (let ((u (uncross orig))) (or (info :type :builtin u) (let ((spec (type-expand u))) @@ -320,15 +344,15 @@ ((and (not (eq spec u)) (info :type :builtin spec))) ((eq (info :type :kind spec) :instance) - (sb!xc:find-class spec)) - ((typep spec 'class) + (find-classoid spec)) + ((typep spec 'classoid) ;; There doesn't seem to be any way to translate ;; (TYPEP SPEC 'BUILT-IN-CLASS) into something which can be ;; executed on the host Common Lisp at cross-compilation time. #+sb-xc-host (error "stub: (TYPEP SPEC 'BUILT-IN-CLASS) on xc host") - (if (typep spec 'built-in-class) - (or (built-in-class-translation spec) spec) + (if (typep spec 'built-in-classoid) + (or (built-in-classoid-translation spec) spec) spec)) (t (let* (;; FIXME: This automatic promotion of FOO-style @@ -343,7 +367,9 @@ (funcall fun lspec)) ((or (and (consp spec) (symbolp (car spec))) (symbolp spec)) - (when *type-system-initialized* + (when (and *type-system-initialized* + (not (eq (info :type :kind spec) + :forthcoming-defclass-type))) (signal 'parse-unknown-type :specifier spec)) ;; (The RETURN-FROM here inhibits caching.) (return-from values-specifier-type @@ -352,14 +378,20 @@ (error "bad thing to be a type specifier: ~S" spec)))))))))) -;;; Like VALUES-SPECIFIER-TYPE, except that we guarantee to never -;;; return a VALUES type. +;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to +;;; never return a VALUES type. (defun specifier-type (x) (let ((res (values-specifier-type x))) (when (values-type-p 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))) + ;;; Similar to MACROEXPAND, but expands DEFTYPEs. We don't bother ;;; returning a second value. (defun type-expand (form)