Simplify type hierarchy operations
Now that built-in types have classes that describe their relationships exactly like struct/eieio/oclosure classes, we can the code that navigates that DAG. * lisp/emacs-lisp/cl-generic.el (cl--generic-struct-tag): Move to `eieio-core.el`. (cl--generic-type-specializers): Rename from `cl--generic-struct-specializers`. Make it work for any class. (cl--generic-typeof-generalizer, cl--generic-oclosure-generalizer): Use it. (cl--generic-struct-generalizer): Delete generalizer. (cl-generic-generalizers :extra "cl-struct"): Delete method. (prefill 0 cl--generic-generalizer): Move to after the typeof. (cl-generic-generalizers :extra "typeof"): Rewrite to use classes rather than `cl--all-builtin-types`. (cl-generic--oclosure-specializers): Delete function. * lisp/emacs-lisp/cl-preloaded.el (cl--direct-supertypes-of-type) (cl--typeof-types, cl--all-builtin-types): Delete constants. * lisp/emacs-lisp/comp-cstr.el (comp--typeof-builtin-types): Delete constant. (comp--cl-class-hierarchy): Simplify. (comp--compute-typeof-types): Simplify now that `comp--cl-class-hierarchy` and `comp--all-classes` work for built-in types as well. (comp--direct-supertypes): Just use `cl--class-parents`. (comp-supertypes): Simplify since typeof-types should now be complete. * lisp/emacs-lisp/eieio-core.el (eieio-defclass-autoload): Use `superclasses` argument, so we can find parents before it's loaded. (eieio--class-precedence-c3, eieio--class-precedence-dfs): Don't add a `eieio-default-superclass` parent any more. (eieio--class/struct-parents): Delete function. (eieio--class-precedence-bfs): Use `eieio--class-parents` instead. Don't stop when reaching `eieio-default-superclass`. (cl--generic-struct-tag): Move from `cl-generic.el`.
This commit is contained in:
parent
945af4d9d1
commit
bd017175d4
4 changed files with 49 additions and 154 deletions
|
@ -38,12 +38,6 @@
|
|||
(require 'cl-lib)
|
||||
(require 'cl-extra) ;HACK: For `cl-find-class' when `cl-loaddefs' is missing.
|
||||
|
||||
(defconst comp--typeof-builtin-types (mapcar (lambda (x)
|
||||
(append x '(t)))
|
||||
cl--typeof-types)
|
||||
;; TODO can we just add t in `cl--typeof-types'?
|
||||
"Like `cl--typeof-types' but with t as common supertype.")
|
||||
|
||||
(cl-defstruct (comp-cstr (:constructor comp--type-to-cstr
|
||||
(type &aux
|
||||
(null (eq type 'null))
|
||||
|
@ -89,15 +83,7 @@ Integer values are handled in the `range' slot.")
|
|||
|
||||
(defun comp--cl-class-hierarchy (x)
|
||||
"Given a class name `x' return its hierarchy."
|
||||
(let ((parents (cl--class-allparents (cl--struct-get-class x))))
|
||||
(if (memq t parents)
|
||||
parents
|
||||
`(,@parents
|
||||
;; FIXME: AFAICT, `comp--all-classes' will also find those struct types
|
||||
;; which use :type and can thus be either `vector' or `cons' (the latter
|
||||
;; isn't `atom').
|
||||
atom
|
||||
t))))
|
||||
(cl--class-allparents (cl--find-class x)))
|
||||
|
||||
(defun comp--all-classes ()
|
||||
"Return all non built-in type names currently defined."
|
||||
|
@ -109,8 +95,7 @@ Integer values are handled in the `range' slot.")
|
|||
res))
|
||||
|
||||
(defun comp--compute-typeof-types ()
|
||||
(append comp--typeof-builtin-types
|
||||
(mapcar #'comp--cl-class-hierarchy (comp--all-classes))))
|
||||
(mapcar #'comp--cl-class-hierarchy (comp--all-classes)))
|
||||
|
||||
(defun comp--compute--pred-type-h ()
|
||||
(cl-loop with h = (make-hash-table :test #'eq)
|
||||
|
@ -275,19 +260,10 @@ Return them as multiple value."
|
|||
(symbol-name y)))
|
||||
|
||||
(defun comp--direct-supertypes (type)
|
||||
(or
|
||||
(gethash type cl--direct-supertypes-of-type)
|
||||
(let ((supers (comp-supertypes type)))
|
||||
(cl-assert (eq type (car supers)))
|
||||
(cl-loop
|
||||
with notdirect = nil
|
||||
with direct = nil
|
||||
for parent in (cdr supers)
|
||||
unless (memq parent notdirect)
|
||||
do (progn
|
||||
(push parent direct)
|
||||
(setq notdirect (append notdirect (comp-supertypes parent))))
|
||||
finally return direct))))
|
||||
(when (symbolp type) ;; FIXME: Can this test ever fail?
|
||||
(let* ((class (cl--find-class type))
|
||||
(parents (if class (cl--class-parents class))))
|
||||
(mapcar #'cl--class-name parents))))
|
||||
|
||||
(defsubst comp-subtype-p (type1 type2)
|
||||
"Return t if TYPE1 is a subtype of TYPE2 or nil otherwise."
|
||||
|
@ -359,23 +335,8 @@ Return them as multiple value."
|
|||
|
||||
(defun comp-supertypes (type)
|
||||
"Return the ordered list of supertypes of TYPE."
|
||||
;; FIXME: We should probably keep the results in
|
||||
;; `comp-cstr-ctxt-typeof-types' (or maybe even precompute them
|
||||
;; and maybe turn `comp-cstr-ctxt-typeof-types' into a hash-table).
|
||||
;; Or maybe we shouldn't keep structs and defclasses in it,
|
||||
;; and just use `cl--class-allparents' when needed (and refuse to
|
||||
;; compute their direct subtypes since we can't know them).
|
||||
(cl-loop
|
||||
named loop
|
||||
with above
|
||||
for lane in (comp-cstr-ctxt-typeof-types comp-ctxt)
|
||||
do (let ((x (memq type lane)))
|
||||
(cond
|
||||
((null x) nil)
|
||||
((eq x lane) (cl-return-from loop x)) ;A base type: easy case.
|
||||
(t (setq above
|
||||
(if above (comp--intersection x above) x)))))
|
||||
finally return above))
|
||||
(or (assq type (comp-cstr-ctxt-typeof-types comp-ctxt))
|
||||
(error "Type %S missing from typeof-types!" type)))
|
||||
|
||||
(defun comp-union-typesets (&rest typesets)
|
||||
"Union types present into TYPESETS."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue