summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorAndrea Corallo <akrl@sdf.org>2020-11-14 17:38:05 +0100
committerAndrea Corallo <akrl@sdf.org>2020-11-14 22:06:31 +0100
commitf702426780475309bdd33ef896d28dd33484246b (patch)
tree2249e3d3de374e99728b0ccfef87403a41648474 /lisp/emacs-lisp
parentbcecdedcb7ee02a58383de396bf05fda88654a30 (diff)
downloademacs-f702426780475309bdd33ef896d28dd33484246b.tar.gz
emacs-f702426780475309bdd33ef896d28dd33484246b.tar.bz2
emacs-f702426780475309bdd33ef896d28dd33484246b.zip
Add `comp-constraint-to-type-spec' and better handle boolean type spec
* lisp/emacs-lisp/comp.el (comp-constraint-to-type-spec): New function splitting out code from comp-ret-type-spec + better handle boolean type specifier. (comp-ret-type-spec): Rework to leverage `comp-constraint-to-type-spec'. * test/src/comp-tests.el (comp-tests-type-spec-tests): Add a testcase.
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/comp.el66
1 files changed, 38 insertions, 28 deletions
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index d75a0547823..da144e4a24f 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -639,6 +639,41 @@ Return the corresponding `comp-constraint' or `comp-constraint-f'."
h)
"Hash table function -> `comp-constraint'")
+(defun comp-constraint-to-type-spec (mvar)
+ "Given MVAR return its type specifier."
+ (let ((valset (comp-mvar-valset mvar))
+ (typeset (comp-mvar-typeset mvar))
+ (range (comp-mvar-range mvar)))
+
+ (when valset
+ (when (memq nil valset)
+ (if (memq t valset)
+ (progn
+ ;; t and nil are values, convert into `boolean'.
+ (push 'boolean typeset)
+ (setf valset (remove t (remove nil valset))))
+ ;; Only nil is a value, convert it into a `null' type specifier.
+ (setf valset (remove nil valset))
+ (push 'null typeset))))
+
+ ;; Form proper integer type specifiers.
+ (setf range (cl-loop for (l . h) in range
+ for low = (if (integerp l) l '*)
+ for high = (if (integerp h) h '*)
+ collect `(integer ,low , high))
+ valset (cl-remove-duplicates valset))
+
+ ;; Form the final type specifier.
+ (let ((res (append typeset
+ (when valset
+ `((member ,@valset)))
+ range)))
+ (if (> (length res) 1)
+ `(or ,@res)
+ (if (memq (car-safe res) '(member integer))
+ res
+ (car res))))))
+
(defun comp-set-op-p (op)
"Assignment predicate for OP."
(when (memq op comp-limple-sets) t))
@@ -2934,34 +2969,9 @@ Set it into the `ret-type-specifier' slot."
do (pcase insn
(`(return ,mvar)
(push `(,mvar . nil) res))))
- finally (cl-return res))))
- (res-valset (comp-mvar-valset res-mvar))
- (res-typeset (comp-mvar-typeset res-mvar))
- (res-range (comp-mvar-range res-mvar)))
- ;; If nil is a value convert it into a `null' type specifier.
- (when res-valset
- (when (memq nil res-valset)
- (setf res-valset (remove nil res-valset))
- (push 'null res-typeset)))
-
- ;; Form proper integer type specifiers.
- (setf res-range (cl-loop for (l . h) in res-range
- for low = (if (integerp l) l '*)
- for high = (if (integerp h) h '*)
- collect `(integer ,low , high))
- res-valset (cl-remove-duplicates res-valset))
-
- ;; Form the final type specifier.
- (let ((res (append res-typeset
- (when res-valset
- `((member ,@res-valset)))
- res-range)))
- (setf (comp-func-ret-type-specifier func)
- (if (> (length res) 1)
- `(or ,@res)
- (if (memq (car-safe res) '(member integer))
- res
- (car res)))))))
+ finally (cl-return res)))))
+ (setf (comp-func-ret-type-specifier func)
+ (comp-constraint-to-type-spec res-mvar))))
(defun comp-finalize-container (cont)
"Finalize data container CONT."