Merge /Users/sabetts/src/movitzcvs/movitz
[movitz-core.git] / compiler-types.lisp
blobc0b65fd6bb8330eb49af889831f517174d55aad3
1 ;;;;------------------------------------------------------------------
2 ;;;;
3 ;;;; Copyright (C) 2001, 2003-2005,
4 ;;;; Department of Computer Science, University of Tromso, Norway.
5 ;;;;
6 ;;;; For distribution policy, see the accompanying file COPYING.
7 ;;;;
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
12 ;;;;
13 ;;;; $Id: compiler-types.lisp,v 1.26 2006/11/08 08:57:05 ffjeld Exp $
14 ;;;;
15 ;;;;------------------------------------------------------------------
17 (in-package movitz)
19 (defun type-specifier-num-values (type-specifier)
20 "How many values does type-specifier represent?"
21 (cond
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))
34 (cond
35 ((or (atom type-specifier)
36 (not (eq 'values (car type-specifier))))
37 (if (= 0 number)
38 type-specifier
39 'null))
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)
44 (cond
45 ((< number (length reqs))
46 (nth number reqs))
47 ((< number (+ (length reqs) (length opts)))
48 (let ((x (nth (- number (length reqs)) opts)))
49 (if (eq x t) t `(or null ,x))))
50 (rest
51 (if (eq rest t) t `(or null ,rest)))
52 (t 'null))))))
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))
73 return nil
74 minimize (car sub-range)))
76 (defun numscope-maximum (numscope)
77 (loop for sub-range in numscope
78 if (not (cdr sub-range))
79 return nil
80 minimize (car sub-range)))
82 (defun numscope-memberp (numscope x)
83 "Is <x> in numscope?"
84 (dolist (sub-range numscope nil)
85 (cond
86 ((and (not (car sub-range)) (not (cdr sub-range)))
87 (return t))
88 ((not (car sub-range))
89 (when (<= x (cdr sub-range))
90 (return t)))
91 ((not (cdr sub-range))
92 (when (<= (car sub-range) x)
93 (return t)))
94 ((<= (car sub-range) x (cdr sub-range))
95 (return t)))))
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)))
100 (if (null numscope)
101 (list (cons min max))
102 (let ((new-min min)
103 (new-max max)
104 (new-numscope ()))
105 (dolist (sub-range numscope)
106 (cond
107 ((and (not (car sub-range))
108 (not (cdr sub-range)))
109 (setf new-min nil
110 new-max nil))
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)
114 (setf new-min nil
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)))
120 new-max nil)))
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)
133 (lambda (x y)
134 (and x y (< x y)))
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."
139 (cond
140 ((null numscope)
141 ;; nothing minus anything is still nothing.
142 nil)
143 ((and (not min) (not max))
144 ;; anything minus everything is nothing.
145 nil)
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)
157 (cond
158 ((and a b)
159 ;; sub-range is eclipsed by the subtrahend.
160 nil)
161 ((or c d)
162 ;; sub-range is disjoint from subtrahend.
163 (setf new-numscope
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.
167 (setf new-numscope
168 (numscope-add-range new-numscope (car sub-range) (- min epsilon) epsilon))
169 (setf new-numscope
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)
172 (setf new-numscope
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)
175 (setf new-numscope
176 (numscope-add-range new-numscope (car sub-range) (- min epsilon) epsilon)))
177 (t (break "I am confused!")))))
178 new-numscope))))
180 (defun numscope-complement (numscope &optional (epsilon 1))
181 (let ((new-numscope (make-numscope nil nil)))
182 (dolist (sub-range numscope)
183 (setf new-numscope
184 (numscope-subtract-range new-numscope (car sub-range) (cdr sub-range) epsilon)))
185 new-numscope))
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)
197 epsilon)
198 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)
215 (let ((result ()))
216 (dolist (sub-range0 range0)
217 (dolist (sub-range1 range1)
218 (setf result
219 (numscope-union result
220 (funcall function
221 (car sub-range0) (cdr sub-range0)
222 (car sub-range1) (cdr sub-range1))))))
223 result))
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))))
231 range0 range1))
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)
240 (ecase type
241 (hash-table
242 (and (typep x 'movitz-struct)
243 (eq (movitz-read 'muerte.cl:hash-table)
244 (slot-value x 'name))))
245 (character
246 (typep x 'movitz-character))
247 (function
248 (typep x 'movitz-funobj))
249 (cons
250 (typep x 'movitz-cons))
251 (symbol
252 (typep x 'movitz-symbol))
253 ((vector array)
254 (typep x 'movitz-basic-vector))
255 (fixnum
256 (typep x 'movitz-fixnum))
257 (bignum
258 (typep x 'movitz-bignum))
259 (ratio
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)
267 (labels ((code (x)
268 (if (not x)
270 (let ((pos (position x *tb-bitmap*)))
271 (assert pos (x) "Type ~S not recognized." x)
272 (let ((code (ash 1 pos)))
273 (case x
274 (symbol (logior code (code 'keyword)))
275 (array (logior code (code 'vector)))
276 ;; (number (logior code (code 'integer)))
277 (t code)))))))
278 (reduce #'logior (mapcar #'code types)
279 :initial-value (code first-type)))))
281 (defun encoded-type-decode (code integer-range members include complement)
282 (cond
283 ((let ((mask (1- (ash 1 (position :tail *tb-bitmap*)))))
284 (= mask (logand mask code)))
285 (not complement))
286 (t (let ((sub-specs include))
287 (loop for x in *tb-bitmap* as bit upfrom 0
288 do (when (logbitp bit code)
289 (push x sub-specs)))
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))
295 integer-range)
296 (dolist (sub-range integer-range)
297 (push (list 'integer
298 (or (car sub-range) '*)
299 (or (cdr sub-range) '*))
300 sub-specs)))
301 (cond
302 ((null sub-specs)
303 (if complement t nil))
304 ((not (cdr sub-specs))
305 (if (not complement)
306 (car sub-specs)
307 (list 'not (car sub-specs))))
308 (t (if (not complement)
309 (cons 'or sub-specs)
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))
319 (break "foo"))
320 (let ((new-intscope integer-range)
321 (new-members ()))
322 (dolist (member members) ; move integer members into integer-range
323 (let ((member (movitz-read member)))
324 (etypecase member
325 (movitz-fixnum
326 (setf new-intscope
327 (numscope-union new-intscope
328 (make-numscope (movitz-fixnum-value member)
329 (movitz-fixnum-value member)))))
330 (movitz-object
331 (pushnew member new-members :test #'movitz-eql)))))
332 (let ((new-code (logior (if (atom codes)
333 (type-code codes)
334 (apply #'type-code codes))
335 (if (numscope-allp new-intscope)
336 (type-code 'integer)
337 0))))
338 (values new-code
339 (if (type-code-p 'integer new-code)
340 (make-numscope nil nil)
341 new-intscope)
342 new-members
343 include
344 complement))))
346 (defun star-is-t (x)
347 (if (eq x '*) t x))
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)
358 (cond
359 ((typep x 'movitz-null)
360 (type-code-p 'symbol code))
361 ((basic-typep x 'fixnum)
362 (or (type-code-p 'integer code)
363 (and integer-range
364 (numscope-memberp integer-range (movitz-fixnum-value x)))))
365 ((basic-typep x 'bignum)
366 (or (type-code-p 'integer code)
367 (and integer-range
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))))))
373 (if (not include)
375 (if errorp
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)
382 (cond
383 ((or (encoded-emptyp code0 integer-range0 members0 include0 complement0)
384 (encoded-emptyp code1 integer-range1 members1 include1 complement1))
385 (type-values nil))
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))
391 (cond
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)))
398 members1)
399 nil 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)))
424 include0)
425 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)))
434 include1)
435 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)
453 (cond
454 ((or (encoded-allp code0 integer-range0 members0 include0 complement0)
455 (encoded-allp code1 integer-range1 members1 include1 complement1))
456 (type-values t))
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)
464 (type-code 'integer)
465 0))))
466 (values new-code
467 (if (type-code-p 'integer new-code)
469 new-inumscope)
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)
475 nil)))
476 ((and (not complement0) complement1)
477 (values code0
478 integer-range0
479 members0
480 (cons (encoded-type-decode code1 integer-range1 members1 include1 complement1)
481 include0)
482 nil))
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)))
491 (cond
492 ((atom type-specifier)
493 (case type-specifier
494 (fixnum
495 (type-specifier-encode `(signed-byte ,+movitz-fixnum-bits+)))
496 (bignum
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))
501 (null
502 (type-values () :members '(nil)))
503 (list
504 (type-values 'cons :members '(nil)))
505 (sequence
506 (type-values '(vector cons) :members '(nil)))
507 (t (let ((deriver (and (boundp '*image*)
508 (gethash type-specifier muerte::*compiler-derived-typespecs*))))
509 (if deriver
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)
515 (satisfies
516 (type-values () :include (list type-specifier)))
517 (member
518 (apply #'member-type-encode (cdr type-specifier)))
519 (eql
520 (member-type-encode (second type-specifier)))
521 (and
522 (if (not (cdr type-specifier))
523 (type-values t)
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))
533 (type-values nil)
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))))
541 (not
542 (assert (= 2 (length type-specifier)))
543 (multiple-value-bind (code integer-range members include complement)
544 (type-specifier-encode (second type-specifier))
545 (cond
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))))))
551 (integer
552 (flet ((integer-limit (s n)
553 (let ((x (if (nthcdr n s)
554 (nth n s)
555 '*)))
556 (cond
557 ((integerp x) x)
558 ((eq x '*) nil)
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)))))
562 (cons
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))
566 (type-values 'cons)
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)
572 :cl :muerte.cl)
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
588 (etypecase member
589 (movitz-fixnum
590 (type-values () :integer-range (make-numscope (movitz-fixnum-value member)
591 (movitz-fixnum-value member))))
592 (movitz-object
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)))
600 (cond
601 ((and x (null include) (not complement))
602 (values t t))
603 ((and (null include) complement)
604 (cond
605 ((encoded-allp code integer-range members include nil)
606 (warn "Seeing an encoded (not t), should be ()")
607 (values t t))
608 (t (values nil t))))
609 ((not (null include))
610 (values nil nil)))))
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."
615 (cond
616 ((let ((mask (1- (ash 1 (position :tail *tb-bitmap*)))))
617 (= mask (logand mask code)))
618 (values (if complement nil t) t))
619 ((and complement
620 (encoded-emptyp code integer-range members include complement))
621 (values t t))
622 ((null include)
623 (values nil t))
624 (t (values nil nil))))
626 (defun encoded-numscope (code integer-range)
627 (if (type-code-p 'integer code)
628 (make-numscope nil nil)
629 integer-range))
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
637 (cond
638 ((encoded-allp code1 integer-range1 members1 include1 complement1)
639 ;; type1 is t.
640 (result-is t t))
641 ((encoded-emptyp code0 integer-range0 members0 include0 complement0)
642 ;; type0 is nil, which is a subtype of anything.
643 (result-is t t))
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.
647 (result-is nil 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.
653 (result-is nil 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)
658 (result-is nil t))))
659 (unless (numscope-subsetp (encoded-numscope code0 integer-range0)
660 (encoded-numscope code1 integer-range1))
661 (result-is nil t))
662 (dolist (m members0)
663 (ecase (encoded-typep nil :unknown m code1 integer-range1 members1 include1 nil)
664 ((nil)
665 (result-is nil t))
666 ((:unknown)
667 (result-is nil nil))
668 ((t) nil)))
669 (if include0
670 (result-is nil nil)
671 (result-is t t)))
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."
679 (cond
680 ((or complement include (not (= 0 code)))
681 nil)
682 ((and (= 1 (length members))
683 (= 0 code) (null intscope) (null include) (not complement))
684 members)
685 ((and (= 1 (length intscope))
686 (caar intscope)
687 (eql (caar intscope)
688 (cdar 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))
703 (cond
704 ((or include0 include1 members0 members1 (/= 0 code0) (/= 0 code1))
705 ;; We can't know..
706 'number)
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))
714 integer-range
715 nil nil nil)))))