X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcode%2Ftypedefs.lisp;h=45b91042c9ca054105f306d68cf5955089b0cd8a;hb=05525d3a5906d7a89fcb689c26177732493c40ce;hp=cc6a4a77e4244b3f2c794fa0990e07264c8c64a5;hpb=f0670f28705c01e79fb23cb2a582074d3e51ec98;p=sbcl.git diff --git a/src/code/typedefs.lisp b/src/code/typedefs.lisp index cc6a4a7..45b9104 100644 --- a/src/code/typedefs.lisp +++ b/src/code/typedefs.lisp @@ -27,7 +27,7 @@ ;;; Define the translation from a type-specifier to a type structure for ;;; some particular type. Syntax is identical to DEFTYPE. (defmacro !def-type-translator (name arglist &body body) - (check-type name symbol) + (declare (type symbol name)) ;; FIXME: Now that the T%CL hack is ancient history and we just use CL ;; instead, we can probably return to using PARSE-DEFMACRO here. ;; @@ -69,16 +69,26 @@ ;; named TYPE-CLASS-INFO which is an accessor for the CTYPE structure ;; even though the TYPE-CLASS structure also exists in the system. ;; Rename this slot: TYPE-CLASS or ASSOCIATED-TYPE-CLASS or something. - (class-info (required-argument) :type type-class) + (class-info (missing-arg) :type type-class) ;; True if this type has a fixed number of members, and as such ;; could possibly be completely specified in a MEMBER type. This is ;; used by the MEMBER type methods. (enumerable nil :read-only t) ;; an arbitrary hash code used in EQ-style hashing of identity ;; (since EQ hashing can't be done portably) - (hash-value (random (1+ most-positive-fixnum)) + (hash-value (random #.(ash 1 20)) :type (and fixnum unsigned-byte) - :read-only t)) + :read-only t) + ;; Can this object contain other types? A global property of our + ;; implementation (which unfortunately seems impossible to enforce + ;; with assertions or other in-the-code checks and constraints) is + ;; that subclasses which don't contain other types correspond to + ;; disjoint subsets (except of course for the NAMED-TYPE T, which + ;; covers everything). So NUMBER-TYPE is disjoint from CONS-TYPE is + ;; is disjoint from MEMBER-TYPE and so forth. But types which can + ;; contain other types, like HAIRY-TYPE and INTERSECTION-TYPE, can + ;; violate this rule. + (might-contain-other-types-p nil :read-only t)) (def!method print-object ((ctype ctype) stream) (print-unreadable-object (ctype stream :type t) (prin1 (type-specifier ctype) stream))) @@ -88,33 +98,10 @@ (declare (type ctype type)) `(specifier-type ',(type-specifier type))) -;;;; utilities +;;;; miscellany -;;; sort of like ANY and EVERY, except: -;;; * We handle two-VALUES predicate functions like SUBTYPEP. (And -;;; if the result is uncertain, then we return (VALUES NIL NIL), -;;; just like SUBTYPEP.) -;;; * THING is just an atom, and we apply OP (an arity-2 function) -;;; successively to THING and each element of LIST. -(defun any/type (op thing list) - (declare (type function op)) - (let ((certain? t)) - (dolist (i list (values nil certain?)) - (multiple-value-bind (sub-value sub-certain?) (funcall op thing i) - (if sub-certain? - (when sub-value (return (values t t))) - (setf certain? nil)))))) -(defun every/type (op thing list) - (declare (type function op)) - (let ((certain? t)) - (dolist (i list (if certain? (values t t) (values nil nil))) - (multiple-value-bind (sub-value sub-certain?) (funcall op thing i) - (if sub-certain? - (unless sub-value (return (values nil t))) - (setf certain? nil)))))) - -;;; Look for a nice intersection for types that intersect only when -;;; one is a hierarchical subtype of the other. +;;; Look for nice relationships for types that have nice relationships +;;; only when one is a hierarchical subtype of the other. (defun hierarchical-intersection2 (type1 type2) (multiple-value-bind (subtypep1 win1) (csubtypep type1 type2) (multiple-value-bind (subtypep2 win2) (csubtypep type2 type1) @@ -122,15 +109,15 @@ (subtypep2 type2) ((and win1 win2) *empty-type*) (t nil))))) - -(defun vanilla-union (type1 type2) +(defun hierarchical-union2 (type1 type2) (cond ((csubtypep type1 type2) type2) ((csubtypep type2 type1) type1) (t nil))) -;;; Hash two things (types) down to 8 bits. In CMU CL this was an EQ hash, but -;;; since it now needs to run in vanilla ANSI Common Lisp at cross-compile -;;; time, it's now based on the CTYPE-HASH-VALUE field instead. +;;; Hash two things (types) down to 8 bits. In CMU CL this was an EQ +;;; hash, but since it now needs to run in vanilla ANSI Common Lisp at +;;; cross-compile time, it's now based on the CTYPE-HASH-VALUE field +;;; instead. ;;; ;;; FIXME: This was a macro in CMU CL, and is now an INLINE function. Is ;;; it important for it to be INLINE, or could be become an ordinary @@ -141,6 +128,15 @@ (logand (logxor (ash (type-hash-value type1) -3) (type-hash-value type2)) #xFF)) +#!-sb-fluid (declaim (inline type-list-cache-hash)) +(declaim (ftype (function (list) (unsigned-byte 8)) type-list-cache-hash)) +(defun type-list-cache-hash (types) + (logand (loop with res = 0 + for type in types + for hash = (type-hash-value type) + do (setq res (logxor res hash)) + finally (return res)) + #xFF)) ;;;; cold loading initializations