mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-06 02:40:26 -08:00
predlib: add accessors for *elementary-types* and *member-types*
Previously elementary types were considered to be (CONS SPECC TAG), but I want to introduce additional slot information to them, so we define a structure for that type. The representation a is list because MAYBE-SAVE-TYPES calls COPY-TREE. Also DEFSTRUCT is not available yet. Rename PUSH-TYPE to PUSH-NEW-TYPE and move it to a correct section in the file.
This commit is contained in:
parent
783289c629
commit
47c17cbfa2
1 changed files with 80 additions and 38 deletions
|
|
@ -849,19 +849,56 @@ if not possible."
|
||||||
;;; Built-in tags for the top and the bottom types.
|
;;; Built-in tags for the top and the bottom types.
|
||||||
(defconstant +built-in-tag-t+ -1)
|
(defconstant +built-in-tag-t+ -1)
|
||||||
(defconstant +built-in-tag-nil+ 0)
|
(defconstant +built-in-tag-nil+ 0)
|
||||||
|
(defparameter *intervals-mask* #B1)
|
||||||
|
|
||||||
(defparameter *member-types*
|
(defparameter *member-types*
|
||||||
#+ecl-min NIL
|
#+ecl-min NIL
|
||||||
#-ecl-min '#.*member-types*)
|
#-ecl-min '#.*member-types*)
|
||||||
|
|
||||||
(defparameter *intervals-mask* #B1)
|
|
||||||
|
|
||||||
(defparameter *elementary-types*
|
(defparameter *elementary-types*
|
||||||
#+ecl-min
|
#+ecl-min
|
||||||
'()
|
'()
|
||||||
#-ecl-min
|
#-ecl-min
|
||||||
'#.*elementary-types*)
|
'#.*elementary-types*)
|
||||||
|
|
||||||
|
;;; The definition is commented out because DEFSTRUCT is not available yet
|
||||||
|
;;; during the bootstrap procedure, so we open-code the definition below.
|
||||||
|
#+ (or)
|
||||||
|
(defstruct (member-type (:type list))
|
||||||
|
(object (error "Argument :OBJECT is required.") :read-only t)
|
||||||
|
(tag (error "Argument :TAG is required.") :type integer))
|
||||||
|
|
||||||
|
(defun make-member-type (&key object tag)
|
||||||
|
(list object tag))
|
||||||
|
|
||||||
|
(defun find-member-type (object)
|
||||||
|
(assoc object *member-types*))
|
||||||
|
|
||||||
|
(setf (fdefinition 'member-type-object) #'first)
|
||||||
|
(setf (fdefinition 'member-type-tag) #'second)
|
||||||
|
(defsetf member-type-tag (mtype) (new-tag)
|
||||||
|
`(rplaca (cdr ,mtype) ,new-tag))
|
||||||
|
|
||||||
|
;;; The definition is commented out because DEFSTRUCT is not available yet
|
||||||
|
;;; during the bootstrap procedure, so we open-code the definition below.
|
||||||
|
#+ (or)
|
||||||
|
(defstruct (elementary-type (:type list))
|
||||||
|
(spec (error "Argument :SPEC is required.") :read-only t)
|
||||||
|
(tag (error "Argument :TAG is required.") :type integer))
|
||||||
|
|
||||||
|
(defun make-elementary-type (&key spec tag)
|
||||||
|
(declare (si::c-local))
|
||||||
|
(list spec tag))
|
||||||
|
|
||||||
|
(defun find-elementary-type (spec test)
|
||||||
|
(declare (si::c-local))
|
||||||
|
(find spec *elementary-types* :key #'elementary-type-spec :test test))
|
||||||
|
|
||||||
|
(setf (fdefinition 'elementary-type-spec) #'first)
|
||||||
|
(setf (fdefinition 'elementary-type-tag) #'second)
|
||||||
|
(defsetf elementary-type-tag (etype) (new-tag)
|
||||||
|
`(rplaca (cdr ,etype) ,new-tag))
|
||||||
|
|
||||||
;;; INV The function MAYBE-SAVE-TYPES ensures that we operate on fresh conses
|
;;; INV The function MAYBE-SAVE-TYPES ensures that we operate on fresh conses
|
||||||
;;; instead of modifying *MEMBER-TYPES* and *ELEMENTARY-TYPES*.
|
;;; instead of modifying *MEMBER-TYPES* and *ELEMENTARY-TYPES*.
|
||||||
(defmacro with-type-database (() &body body)
|
(defmacro with-type-database (() &body body)
|
||||||
|
|
@ -876,23 +913,33 @@ if not possible."
|
||||||
(prog1 *highest-type-tag*
|
(prog1 *highest-type-tag*
|
||||||
(setq *highest-type-tag* (ash *highest-type-tag* 1))))
|
(setq *highest-type-tag* (ash *highest-type-tag* 1))))
|
||||||
|
|
||||||
|
(defun push-new-type (type tag)
|
||||||
|
(declare (si::c-local)
|
||||||
|
(ext:assume-no-errors))
|
||||||
|
(dolist (i *member-types*)
|
||||||
|
(declare (cons i))
|
||||||
|
(when (typep (member-type-object i) type)
|
||||||
|
(setq tag (logior tag (member-type-tag i)))))
|
||||||
|
(push (make-elementary-type :spec type :tag tag) *elementary-types*)
|
||||||
|
tag)
|
||||||
|
|
||||||
;; Find out the tag for a certain type, if it has been already registered.
|
;; Find out the tag for a certain type, if it has been already registered.
|
||||||
;;
|
;;
|
||||||
(defun find-registered-tag (type &optional (test #'equal))
|
(defun find-registered-tag (type &optional (test #'equal))
|
||||||
(declare (si::c-local))
|
(declare (si::c-local))
|
||||||
(let ((pos (assoc type *elementary-types* :test test)))
|
(when-let ((etype (find-elementary-type type test)))
|
||||||
(and pos (cdr pos))))
|
(elementary-type-tag etype)))
|
||||||
|
|
||||||
;;; Make and register a new tag for a certain type.
|
;;; Make and register a new tag for a certain type.
|
||||||
(defun make-registered-tag (type same-kingdom-p type-<=)
|
(defun make-registered-tag (type same-kingdom-p type-<=)
|
||||||
(multiple-value-bind (tag-super tag-sub)
|
(multiple-value-bind (tag-super tag-sub)
|
||||||
(find-type-bounds type same-kingdom-p type-<=)
|
(find-type-bounds type same-kingdom-p type-<=)
|
||||||
(if (null tag-super)
|
(if (null tag-super)
|
||||||
(push-type type tag-sub)
|
(push-new-type type tag-sub)
|
||||||
(let ((tag (new-type-tag)))
|
(let ((tag (new-type-tag)))
|
||||||
(update-types tag-super tag)
|
(update-types tag-super tag)
|
||||||
(setf tag (logior tag tag-sub))
|
(setf tag (logior tag tag-sub))
|
||||||
(push-type type tag)))))
|
(push-new-type type tag)))))
|
||||||
|
|
||||||
;; We are going to make changes in the types database. Save a copy if this
|
;; We are going to make changes in the types database. Save a copy if this
|
||||||
;; will cause trouble.
|
;; will cause trouble.
|
||||||
|
|
@ -913,8 +960,9 @@ if not possible."
|
||||||
(declare (ext:assume-no-errors))
|
(declare (ext:assume-no-errors))
|
||||||
(maybe-save-types)
|
(maybe-save-types)
|
||||||
(dolist (i *elementary-types*)
|
(dolist (i *elementary-types*)
|
||||||
(unless (zerop (logand (cdr i) type-mask))
|
(unless (zerop (logand (elementary-type-tag i) type-mask))
|
||||||
(setf (cdr i) (logior new-tag (cdr i))))))
|
(setf (elementary-type-tag i)
|
||||||
|
(logior new-tag (elementary-type-tag i))))))
|
||||||
|
|
||||||
;;; FIND-TYPE-BOUNDS => (VALUES TAG-SUPER TAG-SUB)
|
;;; FIND-TYPE-BOUNDS => (VALUES TAG-SUPER TAG-SUB)
|
||||||
;;;
|
;;;
|
||||||
|
|
@ -942,8 +990,8 @@ if not possible."
|
||||||
(supertype-tag +built-in-tag-nil+))
|
(supertype-tag +built-in-tag-nil+))
|
||||||
(dolist (i *elementary-types*)
|
(dolist (i *elementary-types*)
|
||||||
(declare (cons i))
|
(declare (cons i))
|
||||||
(let ((other-type (car i))
|
(let ((other-type (elementary-type-spec i))
|
||||||
(other-tag (cdr i)))
|
(other-tag (elementary-type-tag i)))
|
||||||
(when (funcall in-our-family-p other-type)
|
(when (funcall in-our-family-p other-type)
|
||||||
(let ((other-sup-p (funcall type-<= type other-type))
|
(let ((other-sup-p (funcall type-<= type other-type))
|
||||||
(other-sub-p (funcall type-<= other-type type)))
|
(other-sub-p (funcall type-<= other-type type)))
|
||||||
|
|
@ -994,8 +1042,9 @@ if not possible."
|
||||||
;;;
|
;;;
|
||||||
(defun register-member-type (object)
|
(defun register-member-type (object)
|
||||||
;(declare (si::c-local))
|
;(declare (si::c-local))
|
||||||
(let ((pos (assoc object *member-types*)))
|
(let ((mtype (find-member-type object)))
|
||||||
(cond ((and pos (cdr pos)))
|
(cond (mtype
|
||||||
|
(member-type-tag mtype))
|
||||||
((not (realp object))
|
((not (realp object))
|
||||||
(simple-member-type object))
|
(simple-member-type object))
|
||||||
((and (floatp object) (zerop object))
|
((and (floatp object) (zerop object))
|
||||||
|
|
@ -1013,11 +1062,12 @@ if not possible."
|
||||||
(ext:assume-no-errors))
|
(ext:assume-no-errors))
|
||||||
(let ((tag (new-type-tag)))
|
(let ((tag (new-type-tag)))
|
||||||
(maybe-save-types)
|
(maybe-save-types)
|
||||||
(setq *member-types* (acons object tag *member-types*))
|
(push (make-member-type :object object :tag tag) *member-types*)
|
||||||
(dolist (i *elementary-types*)
|
(dolist (i *elementary-types*)
|
||||||
(let ((type (car i)))
|
(let ((type (elementary-type-spec i)))
|
||||||
(when (typep object type)
|
(when (typep object type)
|
||||||
(setf (cdr i) (logior tag (cdr i))))))
|
(setf (elementary-type-tag i)
|
||||||
|
(logior tag (elementary-type-tag i))))))
|
||||||
tag))
|
tag))
|
||||||
|
|
||||||
;;; We convert number into intervals, so that (AND INTEGER (NOT (EQL 10))) is
|
;;; We convert number into intervals, so that (AND INTEGER (NOT (EQL 10))) is
|
||||||
|
|
@ -1028,16 +1078,6 @@ if not possible."
|
||||||
(or (find-registered-tag type)
|
(or (find-registered-tag type)
|
||||||
(canonical-interval-type type))))
|
(canonical-interval-type type))))
|
||||||
|
|
||||||
(defun push-type (type tag)
|
|
||||||
(declare (si::c-local)
|
|
||||||
(ext:assume-no-errors))
|
|
||||||
(dolist (i *member-types*)
|
|
||||||
(declare (cons i))
|
|
||||||
(when (typep (car i) type)
|
|
||||||
(setq tag (logior tag (cdr i)))))
|
|
||||||
(push (cons type tag) *elementary-types*)
|
|
||||||
tag)
|
|
||||||
|
|
||||||
;;; ----------------------------------------------------------------------------
|
;;; ----------------------------------------------------------------------------
|
||||||
;;; SATISFIES types. Here we should signal some error which is caught somewhere
|
;;; SATISFIES types. Here we should signal some error which is caught somewhere
|
||||||
;;; up, to denote failure of the decision procedure.
|
;;; up, to denote failure of the decision procedure.
|
||||||
|
|
@ -1283,7 +1323,7 @@ if not possible."
|
||||||
(defun register-complex-type (upgraded-type)
|
(defun register-complex-type (upgraded-type)
|
||||||
(declare (si::c-local))
|
(declare (si::c-local))
|
||||||
(let ((tag (new-type-tag)))
|
(let ((tag (new-type-tag)))
|
||||||
(push-type upgraded-type tag)))
|
(push-new-type upgraded-type tag)))
|
||||||
|
|
||||||
;;----------------------------------------------------------------------
|
;;----------------------------------------------------------------------
|
||||||
;; CONS types. Only (CONS T T) and variants, as well as (CONS NIL *), etc
|
;; CONS types. Only (CONS T T) and variants, as well as (CONS NIL *), etc
|
||||||
|
|
@ -1444,15 +1484,16 @@ if not possible."
|
||||||
(new-type-tag (new-type-tag)))
|
(new-type-tag (new-type-tag)))
|
||||||
(unless (eq strict-supertype 't)
|
(unless (eq strict-supertype 't)
|
||||||
(extend-type-tag new-type-tag strict-supertype-tag))
|
(extend-type-tag new-type-tag strict-supertype-tag))
|
||||||
(push-type name new-type-tag)))))))
|
(push-new-type name new-type-tag)))))))
|
||||||
|
|
||||||
(defun extend-type-tag (tag minimal-supertype-tag)
|
(defun extend-type-tag (tag minimal-supertype-tag)
|
||||||
(declare (si::c-local)
|
(declare (si::c-local)
|
||||||
(ext:assume-no-errors))
|
(ext:assume-no-errors))
|
||||||
(dolist (type *elementary-types*)
|
(dolist (type *elementary-types*)
|
||||||
(let ((other-tag (cdr type)))
|
(let ((other-tag (elementary-type-tag type)))
|
||||||
(when (zerop (logandc2 minimal-supertype-tag other-tag))
|
(when (zerop (logandc2 minimal-supertype-tag other-tag))
|
||||||
(setf (cdr type) (logior tag other-tag))))))
|
(setf (elementary-type-tag type)
|
||||||
|
(logior tag other-tag))))))
|
||||||
|
|
||||||
;;; ----------------------------------------------------------------------------
|
;;; ----------------------------------------------------------------------------
|
||||||
;;; CANONICALIZE (removed)
|
;;; CANONICALIZE (removed)
|
||||||
|
|
@ -1470,14 +1511,14 @@ if not possible."
|
||||||
;;(print-types-database *elementary-types*)
|
;;(print-types-database *elementary-types*)
|
||||||
;;(print-types-database *member-types*)
|
;;(print-types-database *member-types*)
|
||||||
(dolist (i *member-types*)
|
(dolist (i *member-types*)
|
||||||
(unless (zerop (logand (cdr i) tag))
|
(unless (zerop (logand (member-type-tag i) tag))
|
||||||
(push (car i) out)))
|
(push (member-type-object i) out)))
|
||||||
(when out
|
(when out
|
||||||
(setq out `((MEMBER ,@out))))
|
(setq out `((MEMBER ,@out))))
|
||||||
(dolist (i *elementary-types*)
|
(dolist (i *elementary-types*)
|
||||||
(unless (zerop (logand (cdr i) tag))
|
(unless (zerop (logand (elementary-type-tag i) tag))
|
||||||
;;(print (list tag (cdr i) (logand tag (cdr i))))
|
;;(print (list tag (elementary-type-tag i) (logand tag (elementary-type-tag i))))
|
||||||
(push (car i) out)))
|
(push (elementary-type-spec i) out)))
|
||||||
(values tag `(OR ,@out)))))
|
(values tag `(OR ,@out)))))
|
||||||
|
|
||||||
;;; ----------------------------------------------------------------------------
|
;;; ----------------------------------------------------------------------------
|
||||||
|
|
@ -1543,10 +1584,11 @@ if not possible."
|
||||||
;;(FUNCTION (register-function-type type))
|
;;(FUNCTION (register-function-type type))
|
||||||
;;(VALUES (register-values-type type))
|
;;(VALUES (register-values-type type))
|
||||||
(FUNCTION (canonical-type 'FUNCTION env))
|
(FUNCTION (canonical-type 'FUNCTION env))
|
||||||
(t (ext:if-let ((expander (get-sysprop (first type) 'DEFTYPE-DEFINITION)))
|
(t
|
||||||
(canonical-type (funcall expander type env) env)
|
(ext:if-let ((expander (get-sysprop (first type) 'DEFTYPE-DEFINITION)))
|
||||||
(unless (assoc (first type) *elementary-types*)
|
(canonical-type (funcall expander type env) env)
|
||||||
(throw '+canonical-type-failure+ nil))))))
|
(unless (find-registered-tag (first type) #'eql)
|
||||||
|
(throw '+canonical-type-failure+ nil))))))
|
||||||
((clos::classp type)
|
((clos::classp type)
|
||||||
(register-class type env))
|
(register-class type env))
|
||||||
((and (fboundp 'function-type-p) (function-type-p type))
|
((and (fboundp 'function-type-p) (function-type-p type))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue