X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcompiler%2Ftypetran.lisp;h=5d0fa9d2aba2dfb0835ee5f48c6b2cbeaf8530a3;hb=5ecef987f3847ed5de8c03f66ef9d8ab468af993;hp=c1b19088ae5529a6e36cb3cd6b3362eabd73b97e;hpb=2034cb134af58c5998f4e305673af6e2c75bc179;p=sbcl.git diff --git a/src/compiler/typetran.lisp b/src/compiler/typetran.lisp index c1b1908..5d0fa9d 100644 --- a/src/compiler/typetran.lisp +++ b/src/compiler/typetran.lisp @@ -148,6 +148,9 @@ (define-source-transform atom (x) `(not (consp ,x))) +#!+sb-unicode +(define-source-transform base-char-p (x) + `(typep ,x 'base-char)) ;;;; TYPEP source transform @@ -324,12 +327,13 @@ ;;; Return forms to test that OBJ has the rank and dimensions ;;; specified by TYPE, where STYPE is the type we have checked against -;;; (which is the same but for dimensions.) +;;; (which is the same but for dimensions and element type). (defun test-array-dimensions (obj type stype) (declare (type array-type type stype)) (let ((obj `(truly-the ,(type-specifier stype) ,obj)) (dims (array-type-dimensions type))) - (unless (eq dims '*) + (unless (or (eq dims '*) + (equal dims (array-type-dimensions stype))) (collect ((res)) (when (eq (array-type-dimensions stype) '*) (res `(= (array-rank ,obj) ,(length dims)))) @@ -341,6 +345,24 @@ (res `(= (array-dimension ,obj ,i) ,dim))))) (res))))) +;;; Return forms to test that OBJ has the element-type specified by +;;; type specified by TYPE, where STYPE is the type we have checked +;;; against (which is the same but for dimensions and element type). +(defun test-array-element-type (obj type stype) + (declare (type array-type type stype)) + (let ((obj `(truly-the ,(type-specifier stype) ,obj)) + (eltype (array-type-specialized-element-type type))) + (unless (type= eltype (array-type-specialized-element-type stype)) + (with-unique-names (data) + `((do ((,data ,obj (%array-data-vector ,data))) + ((not (array-header-p ,data)) + ;; KLUDGE: this isn't in fact maximally efficient, + ;; because though we know that DATA is a (SIMPLE-ARRAY * + ;; (*)), we will still check to see if the lowtag is + ;; appropriate. + (typep ,data + '(simple-array ,(type-specifier eltype) (*)))))))))) + ;;; If we can find a type predicate that tests for the type without ;;; dimensions, then use that predicate and test for dimensions. ;;; Otherwise, just do %TYPEP. @@ -351,12 +373,11 @@ ;; not safe to assume here that it will eventually ;; have (UPGRADED-ARRAY-ELEMENT-TYPE type)=T, so punt.) (not (unknown-type-p (array-type-element-type type))) - (type= (array-type-specialized-element-type stype) - (array-type-specialized-element-type type)) (eq (array-type-complexp stype) (array-type-complexp type))) (once-only ((n-obj obj)) `(and (,pred ,n-obj) - ,@(test-array-dimensions n-obj type stype))) + ,@(test-array-dimensions n-obj type stype) + ,@(test-array-element-type n-obj type stype))) `(%typep ,obj ',(type-specifier type))))) ;;; Transform a type test against some instance type. The type test is @@ -493,7 +514,7 @@ (intersection-type (source-transform-intersection-typep object type)) (member-type - `(member ,object ',(member-type-members type))) + `(if (member ,object ',(member-type-members type)) t)) (args-type (compiler-warn "illegal type specifier for TYPEP: ~S" (cadr spec))