mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-05 18:30:24 -08:00
subtypep: introduce the function MAKE-REGISTERED-TAG
This function is used by REGISTER-ELEMENTARY-INTERVAL and REGISTER-TYPE. Additionally we drop the call to LOGANDC2 in the invocation of UPDATE-TYPE, because FIND-TYPE-BOUNDS always does that for us (so it was redundant). Also remove redundant (and unused) function BOUNDS-<.
This commit is contained in:
parent
cfe1dec177
commit
fd101452b6
1 changed files with 34 additions and 39 deletions
|
|
@ -881,6 +881,15 @@ if not possible."
|
|||
(let* ((pos (assoc type *elementary-types* :test test)))
|
||||
(and pos (cdr pos))))
|
||||
|
||||
;;; Make and register a new tag for a certain type.
|
||||
(defun make-registered-tag (type same-kingdom-p type-<= minimize-super)
|
||||
(multiple-value-bind (tag-super tag-sub)
|
||||
(find-type-bounds type same-kingdom-p type-<= minimize-super)
|
||||
(let ((tag (new-type-tag)))
|
||||
(update-types tag-super tag)
|
||||
(setf tag (logior tag tag-sub))
|
||||
(push-type type tag))))
|
||||
|
||||
;; We are going to make changes in the types database. Save a copy if this
|
||||
;; will cause trouble.
|
||||
;;
|
||||
|
|
@ -955,12 +964,7 @@ if not possible."
|
|||
(optimize (safety 0))
|
||||
(function in-our-family-p type-<=))
|
||||
(or (find-registered-tag type)
|
||||
(multiple-value-bind (tag-super tag-sub)
|
||||
(find-type-bounds type in-our-family-p type-<= nil)
|
||||
(let ((tag (new-type-tag)))
|
||||
(update-types (logandc2 tag-super tag-sub) tag)
|
||||
(setf tag (logior tag tag-sub))
|
||||
(push-type type tag)))))
|
||||
(make-registered-tag type in-our-family-p type-<= nil)))
|
||||
|
||||
;;----------------------------------------------------------------------
|
||||
;; MEMBER types. We register this object in a separate list, *MEMBER-TYPES*,
|
||||
|
|
@ -1158,23 +1162,25 @@ if not possible."
|
|||
;; (INTEGER 0 2) = (AND (INTEGER 0 *) (NOT (INTEGER (2) *)))
|
||||
;; (SHORT-FLOAT (0.2) (2)) = (AND (SHORT-FLOAT (0.2) *) (NOT (SHORT-FLOAT 2 *)))
|
||||
|
||||
(defun numeric-range-p (type)
|
||||
(and (consp type)
|
||||
(member (car type)
|
||||
'(integer ratio short-float single-float double-float long-float))
|
||||
(or (null (cddr type))
|
||||
(error "NUMERIC-RANGE-P: ~s is not in the canonical form (TYPE B)." type))))
|
||||
|
||||
;;; Numeric ranges are decided separately depending on the type actual type.
|
||||
;;; When ranges belong to different sub-families, then they are disjoint and
|
||||
;;; can't be ordered.
|
||||
(defun numeric-range-<= (i1 i2)
|
||||
(and (eq (first i1) (first i2))
|
||||
(bounds-<= (second i2) (second i1))))
|
||||
|
||||
(defun register-elementary-interval (type b)
|
||||
(declare (si::c-local))
|
||||
(setq type (list type b))
|
||||
(or (find-registered-tag type #'equalp)
|
||||
(multiple-value-bind (tag-super tag-sub)
|
||||
(find-type-bounds type
|
||||
#'(lambda (other-type)
|
||||
(and (consp other-type)
|
||||
(null (cddr other-type))))
|
||||
#'(lambda (i1 i2)
|
||||
(and (eq (first i1) (first i2))
|
||||
(bounds-<= (second i2) (second i1))))
|
||||
t)
|
||||
(let ((tag (new-type-tag)))
|
||||
(update-types (logandc2 tag-super tag-sub) tag)
|
||||
(setq tag (logior tag tag-sub))
|
||||
(push-type type tag)))))
|
||||
(make-registered-tag type #'numeric-range-p #'numeric-range-<= t)))
|
||||
|
||||
(defun register-interval-type (interval)
|
||||
(declare (si::c-local))
|
||||
|
|
@ -1201,18 +1207,19 @@ if not possible."
|
|||
(t
|
||||
(ceiling low)))))
|
||||
(tag (logandc2 tag-low tag-high)))
|
||||
;; Here we do a rather peculiar thing - we register an interval that is
|
||||
;; right-bound. We could do without registering it, and then juggling with
|
||||
;; MINIMIZE-SUPERTYPE in FIND-TYPE-BOUNDS would not be necessary because all
|
||||
;; types in the kingdom would have a strict total order. -- jd 2023-07-18
|
||||
(unless (eq high '*)
|
||||
(push-type interval tag))
|
||||
tag))
|
||||
|
||||
;; All comparisons between intervals operations may be defined in terms of
|
||||
;;
|
||||
;; (BOUNDS-<= b1 b2) and (BOUNDS-< b1 b2)
|
||||
;;
|
||||
;; The first one checks whether (REAL b2 *) is contained in (REAL b1 *). The
|
||||
;; second one checks whether (REAL b2 *) is strictly contained in (REAL b1 *)
|
||||
;; (i.e., (AND (REAL b1 *) (NOT (REAL b2 *))) is not empty).
|
||||
;;
|
||||
;;; All comparisons between intervals operations may be defined in terms of
|
||||
;;;
|
||||
;;; (BOUNDS-<= b1 b2)
|
||||
;;;
|
||||
;;; that checks whether (REAL b2 *) is contained in (REAL b1 *).
|
||||
(defun bounds-<= (b1 b2)
|
||||
(cond ((eq b1 '*) t)
|
||||
((eq b2 '*) nil)
|
||||
|
|
@ -1225,18 +1232,6 @@ if not possible."
|
|||
(t
|
||||
(<= b1 b2))))
|
||||
|
||||
(defun bounds-< (b1 b2)
|
||||
(cond ((eq b1 '*) (not (eq b2 '*)))
|
||||
((eq b2 '*) nil)
|
||||
((consp b1)
|
||||
(if (consp b2)
|
||||
(< (first b1) (first b2))
|
||||
(< (first b1) b2)))
|
||||
((consp b2)
|
||||
(<= b1 (first b2)))
|
||||
(t
|
||||
(< b1 b2))))
|
||||
|
||||
;;----------------------------------------------------------------------
|
||||
;; COMPLEX types. We do not need to register anything, because all
|
||||
;; possibilities have been covered by the definitions above. We only have to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue