1 ;;;;------------------------------------------------------------------
3 ;;;; Copyright (C) 2001, 2003-2005,
4 ;;;; Department of Computer Science, University of Tromso, Norway.
6 ;;;; For distribution policy, see the accompanying file COPYING.
8 ;;;; Filename: compiler-types.lisp
9 ;;;; Description: Compile-time type computation and manipulation.
10 ;;;; Author: Frode Vatvedt Fjeld <frodef@acm.org>
11 ;;;; Created at: Wed Sep 10 00:40:07 2003
13 ;;;; $Id: compiler-types.lisp,v 1.26 2006/11/08 08:57:05 ffjeld Exp $
15 ;;;;------------------------------------------------------------------
19 (defun type-specifier-num-values (type-specifier)
20 "How many values does type-specifier represent?"
22 ((atom type-specifier
)
24 ((not (eq 'values
(car type-specifier
)))
26 ((not (cdr type-specifier
))
28 ((null (intersection '(&optional
&rest
) (rest type-specifier
)))
29 (length (cdr type-specifier
)))))
31 (defun type-specifier-nth-value (number type-specifier
)
32 "Return the type of the n'th value of a result type-specifier."
33 (check-type number
(integer 0 255))
35 ((or (atom type-specifier
)
36 (not (eq 'values
(car type-specifier
))))
40 ((null (cdr type-specifier
))
41 'null
) ; Zero values => primary value is NIL
42 (t (multiple-value-bind (reqs opts rest
)
43 (decode-normal-lambda-list (cdr type-specifier
) t
)
45 ((< number
(length reqs
))
47 ((< number
(+ (length reqs
) (length opts
)))
48 (let ((x (nth (- number
(length reqs
)) opts
)))
49 (if (eq x t
) t
`(or null
,x
))))
51 (if (eq rest t
) t
`(or null
,rest
)))
54 (defun type-specifier-primary (type-specifier)
55 (type-specifier-nth-value 0 type-specifier
))
57 (defun type-specifier-singleton (type-specifier)
58 "If type-specifier is a singleton type, return a singleton list
59 with the single member of <type-specifier>."
60 (multiple-value-call #'encoded-type-singleton
61 (type-specifier-encode type-specifier
)))
63 ;;; A numscope is a subset of the integers.
65 (defun make-numscope (&optional minimum maximum
)
66 (check-type minimum
(or number null
))
67 (check-type maximum
(or number null
))
68 (list (cons minimum maximum
)))
70 (defun numscope-minimum (numscope)
71 (loop for sub-range in numscope
72 if
(not (car sub-range
))
74 minimize
(car sub-range
)))
76 (defun numscope-maximum (numscope)
77 (loop for sub-range in numscope
78 if
(not (cdr sub-range
))
80 minimize
(car sub-range
)))
82 (defun numscope-memberp (numscope x
)
84 (dolist (sub-range numscope nil
)
86 ((and (not (car sub-range
)) (not (cdr sub-range
)))
88 ((not (car sub-range
))
89 (when (<= x
(cdr sub-range
))
91 ((not (cdr sub-range
))
92 (when (<= (car sub-range
) x
)
94 ((<= (car sub-range
) x
(cdr sub-range
))
97 (defun numscope-add-range (numscope min max
&optional
(epsilon 1))
98 "Add [min .. max] to numscope."
99 (assert (or (null min
) (null max
) (<= min max
)))
101 (list (cons min max
))
105 (dolist (sub-range numscope
)
107 ((and (not (car sub-range
))
108 (not (cdr sub-range
)))
111 ((not (car sub-range
))
112 (if (and (cdr sub-range
) new-min
(<= (cdr sub-range
) (- new-min epsilon
)))
113 (push sub-range new-numscope
)
115 new-max
(and new-max
(max new-max
(cdr sub-range
))))))
116 ((not (cdr sub-range
))
117 (if (and (car sub-range
) new-max
(<= (+ new-max epsilon
) (car sub-range
)))
118 (push sub-range new-numscope
)
119 (setf new-min
(and new-min
(min new-min
(car sub-range
)))
121 ((cond ; is <new-min, new-max> overlapping sub-range?
122 ((and (not new-min
) (not new-max
)) t
)
123 ((not new-min
) (<= (car sub-range
) (+ epsilon new-max
)))
124 ((not new-max
) (<= new-min
(+ epsilon
(cdr sub-range
))))
125 ((<= (- new-min epsilon
) (car sub-range
) (+ new-max epsilon
)) t
)
126 ((<= (- new-min epsilon
) (cdr sub-range
) (+ new-max epsilon
)) t
)
127 ((<= (car sub-range
) new-min
(cdr sub-range
))))
128 (setf new-min
(and new-min
(min new-min
(car sub-range
)))
129 new-max
(and new-max
(max new-max
(cdr sub-range
)))))
130 (t ;; (warn "Unaffected sub-range: ~A for ~D-~D" sub-range new-min new-max)
131 (push sub-range new-numscope
))))
132 (sort (cons (cons new-min new-max
) new-numscope
)
135 :key
(lambda (x) (or (car x
) (cdr x
)))))))
137 (defun numscope-subtract-range (numscope min max
&optional
(epsilon 1))
138 "Remove [min .. max] from numscope."
141 ;; nothing minus anything is still nothing.
143 ((and (not min
) (not max
))
144 ;; anything minus everything is nothing.
146 (t (let ((new-numscope ()))
147 (dolist (sub-range numscope
)
148 (let ((a (or (not min
) (and (car sub-range
) ; subtrahend extends below sub-range-min?
149 (<= min
(car sub-range
)))))
150 (b (or (not max
) (and (cdr sub-range
) ; subtrahend extends above sub-range-max?
151 (<= (cdr sub-range
) max
))))
152 (c (and max
(car sub-range
) ; subtrahend ends below sub-range?
153 (<= max
(+ (car sub-range
) epsilon
))))
154 (d (and min
(cdr sub-range
) ; subtrahend starts above sub-range?
155 (<= (+ (cdr sub-range
) epsilon
) min
))))
156 #+ignore
(warn "abcd: ~S ~S ~S ~S" a b c d
)
159 ;; sub-range is eclipsed by the subtrahend.
162 ;; sub-range is disjoint from subtrahend.
164 (numscope-add-range new-numscope
(car sub-range
) (cdr sub-range
) epsilon
)))
165 ((and (not a
) (not b
) (not c
) (not d
))
166 ;; subtrahend is eclipsed by sub-range, which is split in two pieces.
168 (numscope-add-range new-numscope
(car sub-range
) (- min epsilon
) epsilon
))
170 (numscope-add-range new-numscope
(+ max epsilon
) (cdr sub-range
) epsilon
)))
171 ((and a
(not c
)) ; (warn "left prune ~D with [~D - ~D]" new-numscope min max)
173 (numscope-add-range new-numscope
(+ max epsilon
) (cdr sub-range
) epsilon
)))
174 ((and (not d
) b
) ; (warn "right prune ~D with [~D-~D]" sub-range min max)
176 (numscope-add-range new-numscope
(car sub-range
) (- min epsilon
) epsilon
)))
177 (t (break "I am confused!")))))
180 (defun numscope-complement (numscope &optional
(epsilon 1))
181 (let ((new-numscope (make-numscope nil nil
)))
182 (dolist (sub-range numscope
)
184 (numscope-subtract-range new-numscope
(car sub-range
) (cdr sub-range
) epsilon
)))
187 (defun numscope-union (range0 range1
&optional
(epsilon 1))
188 (dolist (sub-range range0 range1
)
189 (setf range1
(numscope-add-range range1
(car sub-range
) (cdr sub-range
) epsilon
))))
191 (defun numscope-intersection (range0 range1
&optional
(epsilon 1))
192 (if (or (null range0
) (null range1
))
194 ;; <Krystof> (A n B) = ~(~A u ~B)
195 (numscope-complement (numscope-union (numscope-complement range0 epsilon
)
196 (numscope-complement range1 epsilon
)
200 (defun numscope-equalp (range0 range1
)
201 ;; Numscopes should always be kept on canonical form.
202 (equal range0 range1
))
204 (defun numscope-subsetp (range0 range1
)
205 "Is range0 included in range1?"
206 (numscope-equalp range1
(numscope-union range0 range1
)))
208 (defun numscope-allp (range)
209 "Does this numscope include every number?"
210 (let ((x (car range
)))
211 (and x
(not (car x
)) (not (cdr x
)))))
214 (defun numscope-combine (function range0 range1
)
216 (dolist (sub-range0 range0
)
217 (dolist (sub-range1 range1
)
219 (numscope-union result
221 (car sub-range0
) (cdr sub-range0
)
222 (car sub-range1
) (cdr sub-range1
))))))
225 (defun numscope-plus (range0 range1
)
226 "Return the numscope that covers the sum of any element of range0
227 and any element of range1."
228 (numscope-combine (lambda (min0 max0 min1 max1
)
229 (make-numscope (and min0 min1
(+ min0 min1
))
230 (and max0 max1
(+ max0 max1
))))
235 (defparameter *tb-bitmap
*
236 '(hash-table character function cons keyword symbol vector array integer ratio
:tail
)
237 "The union of these types must be t.")
239 (defun basic-typep (x type
)
242 (and (typep x
'movitz-struct
)
243 (eq (movitz-read 'muerte.cl
:hash-table
)
244 (slot-value x
'name
))))
246 (typep x
'movitz-character
))
248 (typep x
'movitz-funobj
))
250 (typep x
'movitz-cons
))
252 (typep x
'movitz-symbol
))
254 (typep x
'movitz-basic-vector
))
256 (typep x
'movitz-fixnum
))
258 (typep x
'movitz-bignum
))
260 (typep x
'movitz-ratio
))))
262 (defun type-code (first-type &rest types
)
263 "Find the code (a bitmap) for (or ,@types)."
264 (declare (dynamic-extent types
))
265 (if (eq t first-type
)
270 (let ((pos (position x
*tb-bitmap
*)))
271 (assert pos
(x) "Type ~S not recognized." x
)
272 (let ((code (ash 1 pos
)))
274 (symbol (logior code
(code 'keyword
)))
275 (array (logior code
(code 'vector
)))
276 ;; (number (logior code (code 'integer)))
278 (reduce #'logior
(mapcar #'code types
)
279 :initial-value
(code first-type
)))))
281 (defun encoded-type-decode (code integer-range members include complement
)
283 ((let ((mask (1- (ash 1 (position :tail
*tb-bitmap
*)))))
284 (= mask
(logand mask code
)))
286 (t (let ((sub-specs include
))
287 (loop for x in
*tb-bitmap
* as bit upfrom
0
288 do
(when (logbitp bit code
)
290 (when (not (null members
))
291 (push (cons 'member members
) sub-specs
))
292 (when (numscope-allp integer-range
)
293 (pushnew 'integer sub-specs
))
294 (when (and (not (member 'integer sub-specs
))
296 (dolist (sub-range integer-range
)
298 (or (car sub-range
) '*)
299 (or (cdr sub-range
) '*))
303 (if complement t nil
))
304 ((not (cdr sub-specs
))
307 (list 'not
(car sub-specs
))))
308 (t (if (not complement
)
310 (list 'not
(cons 'or sub-specs
)))))))))
312 (defun type-values (codes &key integer-range members include complement
)
313 ;; Members: A list of objects explicitly included in type.
314 ;; Include: A list of (non-encodable) type-specs included in type.
315 (check-type include list
)
316 (check-type members list
)
317 (check-type integer-range list
)
318 (when (eq 'and
(car include
))
320 (let ((new-intscope integer-range
)
322 (dolist (member members
) ; move integer members into integer-range
323 (let ((member (movitz-read member
)))
327 (numscope-union new-intscope
328 (make-numscope (movitz-fixnum-value member
)
329 (movitz-fixnum-value member
)))))
331 (pushnew member new-members
:test
#'movitz-eql
)))))
332 (let ((new-code (logior (if (atom codes
)
334 (apply #'type-code codes
))
335 (if (numscope-allp new-intscope
)
339 (if (type-code-p 'integer new-code
)
340 (make-numscope nil nil
)
349 (defun type-code-p (basic-type code
)
350 "is <type-code> included in <code>?"
351 (let ((x (type-code basic-type
)))
352 (= x
(logand x code
))))
354 (defun encoded-typep (errorp undecided-value x code integer-range members include complement
)
355 "Is the movitz-object x included in the encoded-type?"
356 (let ((x (or (= -
1 code
)
357 (and (member x members
:test
#'movitz-eql
) t
)
359 ((typep x
'movitz-null
)
360 (type-code-p 'symbol code
))
361 ((basic-typep x
'fixnum
)
362 (or (type-code-p 'integer code
)
364 (numscope-memberp integer-range
(movitz-fixnum-value x
)))))
365 ((basic-typep x
'bignum
)
366 (or (type-code-p 'integer code
)
368 (numscope-memberp integer-range
(movitz-bignum-value x
)))))
369 (t (dolist (bt '(symbol character function cons hash-table vector ratio
)
370 (error "Cant decide typep for ~S." x
))
371 (when (basic-typep x bt
)
372 (return (type-code-p bt code
))))))
376 (error "Can't decide typep for ~S because it includes ~S." x include
)
377 (return-from encoded-typep undecided-value
))))))
378 (if complement
(not x
) (and x t
))))
380 (defun encoded-types-and (code0 integer-range0 members0 include0 complement0
381 code1 integer-range1 members1 include1 complement1
)
383 ((or (encoded-emptyp code0 integer-range0 members0 include0 complement0
)
384 (encoded-emptyp code1 integer-range1 members1 include1 complement1
))
386 ((encoded-allp code0 integer-range0 members0 include0 complement0
)
387 (values code1 integer-range1 members1 include1 complement1
))
388 ((encoded-allp code1 integer-range1 members1 include1 complement1
)
389 (values code0 integer-range0 members0 include0 complement0
))
390 ((and (not complement0
) (not complement1
))
392 ((and (null include0
) (null include1
))
393 (values (logand code0 code1
)
394 (when (or integer-range0 integer-range1
)
395 (numscope-intersection integer-range0 integer-range1
))
396 (remove-if (lambda (x)
397 (not (encoded-typep t nil x code0 integer-range0 members0 include0 nil
)))
400 ((and (encoded-emptyp code0 nil members0 include0 complement0
)
401 (encoded-emptyp code1 nil members1 nil complement1
)
402 (flet ((integer-super-p (x)
403 (member x
'(rational real number t
))))
404 (every #'integer-super-p include1
)))
405 (type-values () :integer-range integer-range0
))
406 ((and (encoded-emptyp code0 nil members0 nil complement0
)
407 (encoded-emptyp code1 nil members1 include1 complement1
)
408 (flet ((integer-super-p (x)
409 (member x
'(rational real number t
))))
410 (every #'integer-super-p include0
)))
411 (type-values () :integer-range integer-range1
))
412 ((and (= code0 code1
) (equal integer-range0 integer-range1
)
413 (equal members0 members1
) (equal include0 include1
)
414 (eq complement0 complement1
))
415 (values code0 integer-range0 members0 include0 complement0
))
416 ((and include0
(null include1
))
417 ;; (and (or a b c) d) => (or (and a d) (and b d) (and c d))
418 (values (logand code0 code1
)
419 (when (or integer-range0 integer-range1
)
420 (numscope-intersection integer-range0 integer-range1
))
421 (intersection members0 members1
)
422 (mapcar (lambda (sub0)
423 `(and ,sub0
,(encoded-type-decode code1 integer-range1 members1 include1 nil
)))
426 ((and (null include0
) include1
)
427 ;; (and (or a b c) d) => (or (and a d) (and b d) (and c d))
428 (values (logand code0 code1
)
429 (when (or integer-range0 integer-range1
)
430 (numscope-intersection integer-range0 integer-range1
))
431 (intersection members0 members1
)
432 (mapcar (lambda (sub1)
433 `(and ,sub1
,(encoded-type-decode code0 integer-range0 members0 include0 nil
)))
436 (t ;; (warn "and with two includes: ~S ~S" include0 include1)
437 (type-values () :include
`((and ,(encoded-type-decode code0 integer-range0 members0
438 include0 complement0
)
439 ,(encoded-type-decode code1 integer-range1 members1
440 include1 complement1
)))))))
441 ((and complement0 complement1
)
442 (multiple-value-bind (code integer-range members include complement
)
443 (encoded-types-or code0 integer-range0 members0 include0
(not complement0
)
444 code1 integer-range1 members1 include1
(not complement1
))
445 (values code integer-range members include
(not complement
))))
446 (t (type-values () :include
`((and ,(encoded-type-decode code0 integer-range0 members0
447 include0 complement0
)
448 ,(encoded-type-decode code1 integer-range1 members1
449 include1 complement1
)))))))
451 (defun encoded-types-or (code0 integer-range0 members0 include0 complement0
452 code1 integer-range1 members1 include1 complement1
)
454 ((or (encoded-allp code0 integer-range0 members0 include0 complement0
)
455 (encoded-allp code1 integer-range1 members1 include1 complement1
))
457 ((encoded-emptyp code0 integer-range0 members0 include0 complement0
)
458 (values code1 integer-range1 members1 include1 complement1
))
459 ((encoded-emptyp code1 integer-range1 members1 include1 complement1
)
460 (values code0 integer-range0 members0 include0 complement0
))
461 ((and (not complement0
) (not complement1
))
462 (let* ((new-inumscope (numscope-union integer-range0 integer-range1
))
463 (new-code (logior code0 code1
(if (numscope-allp new-inumscope
)
467 (if (type-code-p 'integer new-code
)
470 (remove-if (lambda (x)
471 (or (encoded-typep nil t x code0 integer-range0 nil include0 nil
)
472 (encoded-typep nil t x code1 integer-range1 nil include1 nil
)))
473 (union members0 members1
:test
#'movitz-eql
))
474 (union include0 include1
:test
#'equal
)
476 ((and (not complement0
) complement1
)
480 (cons (encoded-type-decode code1 integer-range1 members1 include1 complement1
)
483 (t (error "Not implemented: ~S or ~S"
484 (encoded-type-decode code0 integer-range0 members0 include0 complement0
)
485 (encoded-type-decode code1 integer-range1 members1 include1 complement1
)))))
488 (defun type-specifier-encode (type-specifier)
489 "Encode a type-specifier to internal representation."
490 (let ((type-specifier (translate-program type-specifier
:muerte.cl
:cl
)))
492 ((atom type-specifier
)
495 (type-specifier-encode `(signed-byte ,+movitz-fixnum-bits
+)))
497 (type-specifier-encode `(or (integer * ,(1- +movitz-most-negative-fixnum
+))
498 (integer ,(1+ +movitz-most-positive-fixnum
+) *))))
499 ((t nil cons symbol keyword function array vector integer hash-table character
)
500 (type-values type-specifier
))
502 (type-values () :members
'(nil)))
504 (type-values 'cons
:members
'(nil)))
506 (type-values '(vector cons
) :members
'(nil)))
507 (t (let ((deriver (and (boundp '*image
*)
508 (gethash type-specifier muerte
::*compiler-derived-typespecs
*))))
510 (type-specifier-encode (funcall deriver
))
511 (type-values () :include
(list type-specifier
)))))))
512 ((listp type-specifier
)
513 (check-type (car type-specifier
) symbol
)
514 (case (car type-specifier
)
516 (type-values () :include
(list type-specifier
)))
518 (apply #'member-type-encode
(cdr type-specifier
)))
520 (member-type-encode (second type-specifier
)))
522 (if (not (cdr type-specifier
))
524 (multiple-value-bind (code integer-range members include complement
)
525 (type-specifier-encode (second type-specifier
))
526 (dolist (sub-specifier (cddr type-specifier
))
527 (multiple-value-setq (code integer-range members include complement
)
528 (multiple-value-call #'encoded-types-and code integer-range members include complement
529 (type-specifier-encode sub-specifier
))))
530 (values code integer-range members include complement
))))
532 (if (not (cdr type-specifier
))
534 (multiple-value-bind (code integer-range members include complement
)
535 (type-specifier-encode (second type-specifier
))
536 (dolist (sub-specifier (cddr type-specifier
))
537 (multiple-value-setq (code integer-range members include complement
)
538 (multiple-value-call #'encoded-types-or code integer-range members include complement
539 (type-specifier-encode sub-specifier
))))
540 (values code integer-range members include complement
))))
542 (assert (= 2 (length type-specifier
)))
543 (multiple-value-bind (code integer-range members include complement
)
544 (type-specifier-encode (second type-specifier
))
546 ((encoded-allp code integer-range members include complement
)
547 (type-specifier-encode nil
))
548 ((encoded-emptyp code integer-range members include complement
)
549 (type-specifier-encode t
))
550 (t (values code integer-range members include
(not complement
))))))
552 (flet ((integer-limit (s n
)
553 (let ((x (if (nthcdr n s
)
559 (t (error "Not an in integer limit: ~S" x
))))))
560 (type-values () :integer-range
(make-numscope (integer-limit type-specifier
1)
561 (integer-limit type-specifier
2)))))
563 (let ((car (star-is-t (if (cdr type-specifier
) (second type-specifier
) '*)))
564 (cdr (star-is-t (if (cddr type-specifier
) (third type-specifier
) '*))))
565 (if (and (eq t car
) (eq t cdr
))
567 (type-values () :include
(list type-specifier
)))))
568 ((array vector binding-type
)
569 (type-values () :include
(list type-specifier
)))
570 (t (let ((deriver (and (boundp '*image
*)
571 (gethash (translate-program (car type-specifier
)
573 muerte
::*compiler-derived-typespecs
*))))
574 (assert deriver
(type-specifier)
575 "Unknown type ~S." type-specifier
)
576 (type-specifier-encode (apply deriver
(cdr type-specifier
))))))))))
578 (defun member-type-encode (&rest member-objects
)
579 "Encode a member type-specifier holding member-objects."
580 (declare (dynamic-extent members
))
581 (multiple-value-bind (code integer-range members include complement
)
582 (type-specifier-encode nil
)
583 (dolist (x member-objects
)
584 (let ((member (movitz-read x
)))
585 (multiple-value-setq (code integer-range members include complement
)
586 (multiple-value-call #'encoded-types-or
587 code integer-range members include complement
590 (type-values () :integer-range
(make-numscope (movitz-fixnum-value member
)
591 (movitz-fixnum-value member
))))
593 (type-values () :members
(list member
))))))))
594 (values code integer-range members include complement
)))
596 (defun encoded-emptyp (code integer-range members include complement
)
597 "Return wether we know the encoded type is the empty set.
598 If it isn't, also return wether we _know_ it isn't empty."
599 (let ((x (and (= 0 code
) (not integer-range
) (null members
) t
)))
601 ((and x
(null include
) (not complement
))
603 ((and (null include
) complement
)
605 ((encoded-allp code integer-range members include nil
)
606 (warn "Seeing an encoded (not t), should be ()")
609 ((not (null include
))
612 (defun encoded-allp (code integer-range members include complement
)
613 "Return wether we know the encoded type is the all-inclusive set.
614 If it isn't, also return wether we _know_ it isn't."
616 ((let ((mask (1- (ash 1 (position :tail
*tb-bitmap
*)))))
617 (= mask
(logand mask code
)))
618 (values (if complement nil t
) t
))
620 (encoded-emptyp code integer-range members include complement
))
624 (t (values nil nil
))))
626 (defun encoded-numscope (code integer-range
)
627 (if (type-code-p 'integer code
)
628 (make-numscope nil nil
)
631 (defun encoded-subtypep (code0 integer-range0 members0 include0 complement0
632 code1 integer-range1 members1 include1 complement1
)
633 "Is every member of 0 also a member of 1?"
634 (macrolet ((result-is (subtypep decisivep
)
635 `(return-from encoded-subtypep
(values ,subtypep
,decisivep
))))
636 (block encoded-subtypep
638 ((encoded-allp code1 integer-range1 members1 include1 complement1
)
641 ((encoded-emptyp code0 integer-range0 members0 include0 complement0
)
642 ;; type0 is nil, which is a subtype of anything.
644 ((and (encoded-emptyp code1 integer-range1 members1 include1 complement1
)
645 #+ignore
(not (encoded-emptyp code0 integer-range0 members0 include0 complement0
)))
646 ;; type1 is nil and type0 isn't.
648 ((and (encoded-allp code0 integer-range0 members0 include0 complement0
)
649 (multiple-value-bind (all1 confident
)
650 (encoded-allp code1 integer-range1 members1 include1 complement1
)
651 (and (not all1
) confident
)))
652 ;; type0 is t, and type1 isn't.
654 ((and (not complement0
) (not complement1
))
655 (dolist (st *tb-bitmap
*)
656 (when (type-code-p st code0
)
657 (unless (type-code-p st code1
)
659 (unless (numscope-subsetp (encoded-numscope code0 integer-range0
)
660 (encoded-numscope code1 integer-range1
))
663 (ecase (encoded-typep nil
:unknown m code1 integer-range1 members1 include1 nil
)
672 ((and complement0 complement1
)
673 (encoded-subtypep code1 integer-range1 members1 include1 nil
674 code0 integer-range0 members0 include0 nil
))
675 (t (result-is nil nil
))))))
677 (defun encoded-type-singleton (code intscope members include complement
)
678 "If the encoded type is a singleton, return that element in a list."
680 ((or complement include
(not (= 0 code
)))
682 ((and (= 1 (length members
))
683 (= 0 code
) (null intscope
) (null include
) (not complement
))
685 ((and (= 1 (length intscope
))
689 (list (movitz-read (caar intscope
))))
690 ((and (null members
) (null intscope
))
691 (break "Not singleton, nulloton."))))
693 (defun movitz-subtypep (type0 type1
)
694 "Compile-time subtypep."
695 (multiple-value-call #'encoded-subtypep
696 (type-specifier-encode type0
)
697 (type-specifier-encode type1
)))
699 (defun encoded-integer-types-add (code0 integer-range0 members0 include0 complement0
700 code1 integer-range1 members1 include1 complement1
)
701 "Return the integer type that can result from adding a member of type0 to a member of type1."
702 ;; (declare (ignore members0 members1))
704 ((or include0 include1 members0 members1
(/= 0 code0
) (/= 0 code1
))
707 ((or complement0 complement1
)
708 (break "adding complement types..?"))
709 (t (let ((integer-range (numscope-plus (encoded-numscope code0 integer-range0
)
710 (encoded-numscope code1 integer-range1
))))
711 (encoded-type-decode (if (not (numscope-allp integer-range
))
713 (type-code 'integer
))