mtype.scm 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Martin Gasbichler, Mike Sperber, Robert Ransom
  3. ; Type lattice.
  4. ; Sorry this is so hairy, but before it was written, type checking
  5. ; consumed 15% of compile time.
  6. (define-record-type meta-type :meta-type
  7. (really-make-type mask more info)
  8. meta-type?
  9. (mask type-mask)
  10. (more type-more)
  11. (info type-info))
  12. ; MASK is a bit set. The current bits are:
  13. ;
  14. ; Non values:
  15. ; syntax
  16. ; other static type
  17. ; no values - indicates an optional type; the type with only this bit set
  18. ; is the empty rail type.
  19. ; two or more - indicates a rail-type with at least two elements
  20. ;
  21. ; Values:
  22. ; exact integer
  23. ; integer
  24. ; exact rational
  25. ; rational
  26. ; exact real
  27. ; real
  28. ; exact complex
  29. ; complex
  30. ; other exact number
  31. ; other number
  32. ; boolean
  33. ; pair
  34. ; null
  35. ; record
  36. ; procedure
  37. ; other
  38. ;
  39. ; The MORE field is only used for rail types, which are like ML's tuples.
  40. ; If the TWO-OR-MORE? bit is set, then
  41. ; more = (head . tail).
  42. ; Otherwise, more = #f.
  43. ;
  44. ; For procedure types, the PROCEDURE bit is set and the INFO field is a three
  45. ; element list: (domain codomain restrictive?)
  46. ; If INFO field for the type of F is (t1 t2 #t), then
  47. ; if x : t1 then (f x) : t2 (possible error!), else (f x) : error.
  48. ; If INFO field for the type of F is (t1 t2 #f), then
  49. ; there exists an x : t1 such that (f x) : t2.
  50. ;
  51. ; For types which do not have bits, the OTHER bit is set and the INFO field is
  52. ; a symbol naming some type that doesn't have its own bit in the mask. The
  53. ; other types defined in this file are:
  54. ;
  55. ; :char
  56. ; :unspecific
  57. ; :string
  58. ; :symbol
  59. ; :vector
  60. ; :escape
  61. ; :structure
  62. ;
  63. ; More are constructed later by using SEXP->TYPE.
  64. (define-record-discloser :meta-type
  65. (lambda (t)
  66. `(type ,(let ((m (type-mask t)))
  67. (or (table-ref mask->name-table m)
  68. m))
  69. ,(let ((more (type-more t)))
  70. (if (and (pair? more) (eq? (cdr more) t))
  71. '*
  72. more))
  73. ,(type-info t))))
  74. (define (make-type mask more info)
  75. (make-immutable!
  76. (really-make-type mask more info)))
  77. (define name->type-table (make-table))
  78. (define mask->name-table (make-table))
  79. (define (name->type x)
  80. (or (table-ref name->type-table x)
  81. (make-other-type x)))
  82. (define (set-type-name! type name)
  83. (table-set! name->type-table name type)
  84. (if (not (or (type-info type)
  85. (type-more type)))
  86. (table-set! mask->name-table (type-mask type) name)))
  87. ; Masks
  88. ; Top of lattice has mask = -1, bottom has mask = 0.
  89. (define *mask* 1)
  90. (define (new-type-bit)
  91. (let ((m *mask*))
  92. (set! *mask* (arithmetic-shift *mask* 1))
  93. m))
  94. (define (mask->type mask)
  95. (make-type mask #f #f))
  96. (define bottom-type (mask->type 0))
  97. (define error-type bottom-type)
  98. (define (bottom-type? t)
  99. (= (type-mask t) 0))
  100. (set-type-name! bottom-type ':error)
  101. (define (new-atomic-type)
  102. (mask->type (new-type-bit)))
  103. (define (named-atomic-type name)
  104. (let ((t (new-atomic-type)))
  105. (set-type-name! t name)
  106. t))
  107. ; --------------------
  108. ; Top of the lattice.
  109. (define syntax-type (named-atomic-type ':syntax))
  110. (define other-static-type (new-atomic-type))
  111. ; --------------------
  112. ; "Rails" are argument sequence or return value sequences.
  113. ; Four constructors:
  114. ; empty-rail-type
  115. ; (rail-type t1 t2)
  116. ; (optional-rail-type t1 t2)
  117. ; (make-rest-type t)
  118. ; If a type's two-or-more? bit is set, then
  119. ; more = (head . tail).
  120. ; Otherwise, more = #f.
  121. (define empty-rail-type (new-atomic-type))
  122. (define (rail-type t1 t2) ;CONS analog
  123. (cond ((empty-rail-type? t2) t1)
  124. ((bottom-type? t1) t1)
  125. ((bottom-type? t2) t2)
  126. ((and (optional-type? t1)
  127. (rest-type? t2)
  128. (same-type? t1 (head-type t2)))
  129. ;; Turn (&opt t &rest t) into (&rest t)
  130. t2)
  131. ((or (optional-type? t1)
  132. (optional-type? t2))
  133. (make-type (bitwise-ior (type-mask t1) mask/two-or-more)
  134. (make-immutable! (cons t1 t2))
  135. #f))
  136. (else
  137. (make-type mask/two-or-more
  138. (make-immutable! (cons t1 t2))
  139. (type-info t1)))))
  140. (define (make-optional-type t)
  141. (if (type-more t)
  142. (warning 'make-optional-type "peculiar type in make-optional-type" t))
  143. (make-type (bitwise-ior (type-mask t) mask/no-values)
  144. #f
  145. (type-info t)))
  146. ; A rest type is an infinite rail type with both the no-values and the
  147. ; two-or-more bits set.
  148. (define (make-rest-type t)
  149. (if (bottom-type? t)
  150. t
  151. (let* ((z (cons (make-optional-type t) #f))
  152. (t (make-type (bitwise-ior (type-mask t) mask/&rest)
  153. z
  154. (type-info t))))
  155. (set-cdr! z t)
  156. (make-immutable! z)
  157. t)))
  158. (define (head-type t) ;Can return an &opt type
  159. (let ((more (type-more t)))
  160. (if more
  161. (car more)
  162. t)))
  163. (define (head-type-really t) ;Always returns a value type
  164. (let ((h (head-type t)))
  165. (if (optional-type? h)
  166. (make-type (bitwise-and (type-mask h) (bitwise-not mask/no-values))
  167. #f
  168. (type-info h))
  169. h)))
  170. (define (tail-type t)
  171. (if (empty-rail-type? t)
  172. ;; bottom-type ?
  173. (warning 'tail-type "rail-type of empty rail" t))
  174. (let ((more (type-more t)))
  175. (if more
  176. (cdr more)
  177. empty-rail-type)))
  178. (define (empty-rail-type? t)
  179. (= (bitwise-and (type-mask t) mask/one-or-more) 0))
  180. (define (rest-type? t) ;For terminating recursions
  181. (let ((more (type-more t)))
  182. (and more
  183. (eq? (cdr more) t))))
  184. (define (optional-type? t)
  185. (> (bitwise-and (type-mask t) mask/no-values) 0))
  186. ; The no-values type has one element, the rail of length zero.
  187. ; The two-or-more type consists of all rails of length two
  188. ; or more.
  189. (define mask/no-values (type-mask empty-rail-type))
  190. (define mask/two-or-more (new-type-bit))
  191. (define mask/&rest (bitwise-ior (type-mask empty-rail-type)
  192. mask/two-or-more))
  193. (table-set! mask->name-table mask/no-values ':no-values)
  194. (define value-type (mask->type (bitwise-not (- *mask* 1))))
  195. (set-type-name! value-type ':value)
  196. (define mask/value (type-mask value-type))
  197. (define (value-type? t)
  198. (let ((m (type-mask t)))
  199. (= (bitwise-and m mask/value) m)))
  200. (define any-values-type
  201. (make-rest-type value-type))
  202. (set-type-name! any-values-type ':values)
  203. (define any-arguments-type any-values-type)
  204. (define mask/one-or-more
  205. (bitwise-ior mask/value mask/two-or-more))
  206. ; --------------------
  207. ; Lattice operations.
  208. ; Equivalence
  209. (define (same-type? t1 t2)
  210. (or (eq? t1 t2)
  211. (and (= (type-mask t1) (type-mask t2))
  212. (let ((more1 (type-more t1))
  213. (more2 (type-more t2)))
  214. (if more1
  215. (and more2
  216. (if (eq? (cdr more1) t1)
  217. (eq? (cdr more2) t2)
  218. (if (eq? (cdr more2) t2)
  219. #f
  220. (and (same-type? (car more1) (car more2))
  221. (same-type? (cdr more1) (cdr more2))))))
  222. (not more2)))
  223. (let ((info1 (type-info t1))
  224. (info2 (type-info t2)))
  225. (or (eq? info1 info2) ; takes care of OTHER types
  226. (and (pair? info1) ; check for same procedure types
  227. (pair? info2)
  228. (same-type? (car info1) (car info2))
  229. (same-type? (cadr info1) (cadr info2))
  230. (eq? (caddr info1) (caddr info2))))))))
  231. (define (subtype? t1 t2) ;*** optimize later
  232. (same-type? t1 (meet-type t1 t2)))
  233. ; (mask->type mask/procedure) represents the TOP of the procedure
  234. ; subhierarchy.
  235. (define (meet-type t1 t2)
  236. (if (same-type? t1 t2)
  237. t1
  238. (let ((m (bitwise-and (type-mask t1) (type-mask t2))))
  239. (cond ((> (bitwise-and m mask/two-or-more) 0)
  240. (meet-rail t1 t2))
  241. ((eq? (type-info t1) (type-info t2))
  242. (make-type m #f (type-info t1)))
  243. ((> (bitwise-and m mask/other) 0)
  244. (let ((i1 (other-type-info t1))
  245. (i2 (other-type-info t2)))
  246. (if (and i1 i2)
  247. (mask->type (bitwise-and m (bitwise-not mask/other)))
  248. (make-type m
  249. #f
  250. (or i1 i2)))))
  251. ((> (bitwise-and m mask/procedure) 0)
  252. (meet-procedure m t1 t2))
  253. (else
  254. (mask->type m))))))
  255. (define (other-type-info t)
  256. (let ((i (type-info t)))
  257. (if (pair? i) #f i)))
  258. ;(define (p name x) (write `(,name ,x)) (newline) x)
  259. (define (meet-rail t1 t2)
  260. (let ((t (meet-type (head-type t1)
  261. (head-type t2))))
  262. (if (and (rest-type? t1)
  263. (rest-type? t2))
  264. (make-rest-type t)
  265. (rail-type t (meet-type (tail-type t1)
  266. (tail-type t2))))))
  267. ; Start with these assumptions:
  268. ;
  269. ; . (meet? t1 t2) == (not (bottom-type? (meet-type t1 t2)))
  270. ; . (subtype? t1 t2) == (same-type? t1 (meet-type t1 t2))
  271. ; . (subtype? t1 t2) == (same-type? t2 (join-type t1 t2))
  272. ; . We signal a type error if not (intersect? have want).
  273. ; . We infer the type of a parameter by intersecting the want-types
  274. ; of all definitely-reached points of use.
  275. ;
  276. ; 1. If both types are nonrestrictive, we have to JOIN both domains
  277. ; and codomains (if we are to avoid conjunctive types).
  278. ;
  279. ; (+ (f 1) (car (f 'a))) [reconstructing type of f by computing meet of all contexts]
  280. ; => meet (proc (:integer) :number nonr) (proc (:symbol) :pair nonr)
  281. ; => (proc ((join :integer :symbol)) (join :number :pair) nonr), yes?
  282. ;
  283. ; 2. If both types are restrictive, we need to MEET both domains and
  284. ; codomains.
  285. ;
  286. ; (define (foo) 3), (export (foo (proc (:value) :value)))
  287. ; Error - disjoint domains.
  288. ;
  289. ; (define (foo) 'baz), (export (foo (proc () :number)))
  290. ; Error - disjoint codomains.
  291. ;
  292. ; 3. If one is restrictive and the other isn't then we still need to
  293. ; MEET on both sides.
  294. ;
  295. ; (with-output-to-file "foo" car)
  296. ; => meet (proc () :any nonr), (proc (:pair) :value restr)
  297. ; => Error - disjoint domains.
  298. ;
  299. ; (frob (lambda () 'a)) where (define (frob f) (+ (f) 1))
  300. ; => meet (proc () :symbol restr), (proc () :number nonr)
  301. ; => Error - disjoint codomains.
  302. ;
  303. ; Does export checking look for (intersect? want have), or for
  304. ; (subtype? want have) ? We should be able to narrow something as we
  305. ; export it, but not widen it.
  306. ;
  307. ; (define (foo . x) 3), (export (foo (proc (value) value)))
  308. ; No problem, since the domain of the first contains the domain of the second.
  309. ;
  310. ; (define (foo x . y) (+ x 3)), (export (foo (proc (value) value)))
  311. ; Dubious; the domains intersect but are incomparable. The meet
  312. ; should be (proc (number) number).
  313. ;
  314. ; (define (foo x) (numerator x)), (export (foo (proc (real) integer)))
  315. ; This is dubious, since the stated domain certainly contains values
  316. ; that will be rejected. (But then, what about divide by zero, or
  317. ; vector indexing?)
  318. ;
  319. ; (define (foo x) (numerator x)), (export (foo (proc (integer) integer)))
  320. ; This should definitely be OK.
  321. (define (meet-procedure m t1 t2)
  322. (let ((dom1 (procedure-type-domain t1))
  323. (dom2 (procedure-type-domain t2))
  324. (cod1 (procedure-type-codomain t1))
  325. (cod2 (procedure-type-codomain t2)))
  326. (cond ((or (restrictive? t1)
  327. (restrictive? t2))
  328. (let ((dom (meet-type dom1 dom2))
  329. (cod (meet-type cod1 cod2)))
  330. (if (or (bottom-type? dom)
  331. (and (bottom-type? cod)
  332. (not (bottom-type? cod1)) ;uck
  333. (not (bottom-type? cod2))))
  334. (mask->type (bitwise-and m (bitwise-not mask/procedure)))
  335. (make-procedure-type m
  336. dom
  337. cod
  338. #t))))
  339. ((and (subtype? dom2 dom1)
  340. (subtype? cod2 cod1))
  341. ;; exists x : dom1 s.t. (f x) : cod1 adds no info
  342. (make-procedure-type m dom2 cod2 #f))
  343. (else
  344. ;; Arbitrary choice.
  345. (make-procedure-type m dom1 cod1 #f)))))
  346. ; MEET? is the operation used all the time by the compiler. We want
  347. ; getting a yes answer to be as fast as possible. We could do
  348. ;
  349. ; (define (meet? t1 t2) (not (bottom-type? (meet-type t1 t2))))
  350. ;
  351. ; but that would be too slow.
  352. (define (meet? t1 t2)
  353. (or (eq? t1 t2)
  354. (let ((m (bitwise-and (type-mask t1)
  355. (type-mask t2))))
  356. (cond ((= m mask/two-or-more)
  357. (and (meet? (head-type t1)
  358. (head-type t2))
  359. (meet? (tail-type t1)
  360. (tail-type t2))))
  361. ((= m 0)
  362. #f)
  363. ((eq? (type-info t1)
  364. (type-info t2))
  365. #t)
  366. ((= m mask/other)
  367. (not (and (other-type-info t1)
  368. (other-type-info t2))))
  369. ((= m mask/procedure)
  370. (meet-procedure? t1 t2))
  371. (else
  372. #t)))))
  373. (define (meet-procedure? t1 t2)
  374. (if (or (restrictive? t1)
  375. (restrictive? t2))
  376. (and (meet? (procedure-type-domain t1)
  377. (procedure-type-domain t2))
  378. (meet? (procedure-type-codomain t1)
  379. (procedure-type-codomain t2)))
  380. #t))
  381. ; Join
  382. (define (join-type t1 t2)
  383. (if (same-type? t1 t2)
  384. t1
  385. (let ((m (bitwise-ior (type-mask t1)
  386. (type-mask t2))))
  387. (if (> (bitwise-and m mask/two-or-more) 0)
  388. (join-rail t1 t2)
  389. (let ((info1 (type-info t1))
  390. (info2 (type-info t2)))
  391. (cond ((equal? info1 info2)
  392. (make-type m #f (type-info t1)))
  393. ((> (bitwise-and m mask/other) 0)
  394. (make-type m #f #f))
  395. ((> (bitwise-and m mask/procedure) 0)
  396. (join-procedure m t1 t2))
  397. (else
  398. (assertion-violation 'join-type "This shouldn't happen" t1 t2))))))))
  399. (define (join-rail t1 t2)
  400. (let ((t (join-type (head-type t1) (head-type t2))))
  401. (if (and (rest-type? t1)
  402. (rest-type? t2))
  403. (make-rest-type t)
  404. (rail-type t
  405. (if (type-more t1)
  406. (if (type-more t2)
  407. (join-type (tail-type t1)
  408. (tail-type t2))
  409. (tail-type t1))
  410. (tail-type t2))))))
  411. ; This is pretty gross.
  412. (define (join-procedure m t1 t2)
  413. (if (procedure-type? t1)
  414. (if (procedure-type? t2)
  415. (let ((dom1 (procedure-type-domain t1))
  416. (dom2 (procedure-type-domain t2))
  417. (cod1 (procedure-type-codomain t1))
  418. (cod2 (procedure-type-codomain t2)))
  419. (make-procedure-type m
  420. (join-type dom1 dom2) ;Error when outside here
  421. (join-type cod1 cod2)
  422. (and (restrictive? t1)
  423. (restrictive? t2))))
  424. (make-type m #f (type-info t1)))
  425. (make-type m #f (type-info t2))))
  426. ; --------------------
  427. ; Value types.
  428. ; First, the ten indivisible number types.
  429. (define number-hierarchy
  430. '(:integer :rational :real :complex :number))
  431. (let loop ((names number-hierarchy)
  432. (exact bottom-type)
  433. (inexact bottom-type))
  434. (if (null? names)
  435. (begin (set-type-name! exact ':exact)
  436. (set-type-name! inexact ':inexact))
  437. (let* ((exact (join-type exact (new-atomic-type)))
  438. (inexact (join-type inexact (new-atomic-type))))
  439. (set-type-name! (join-type exact inexact)
  440. (car names))
  441. (loop (cdr names)
  442. exact
  443. inexact))))
  444. (define integer-type (name->type ':integer))
  445. (define rational-type (name->type ':rational))
  446. (define real-type (name->type ':real))
  447. (define complex-type (name->type ':complex))
  448. (define number-type (name->type ':number))
  449. (define exact-type (name->type ':exact))
  450. (define inexact-type (name->type ':inexact))
  451. (define exact-integer-type (meet-type integer-type exact-type))
  452. (set-type-name! exact-integer-type ':exact-integer)
  453. (define inexact-real-type (meet-type real-type inexact-type))
  454. (set-type-name! inexact-real-type ':inexact-real)
  455. ; Next, all the others.
  456. (define boolean-type (named-atomic-type ':boolean))
  457. (define pair-type (named-atomic-type ':pair))
  458. (define null-type (named-atomic-type ':null))
  459. (define record-type (named-atomic-type ':record))
  460. (define any-procedure-type (named-atomic-type ':procedure))
  461. ; ???
  462. ; (define procedure-nonbottom-type (new-atomic-type))
  463. ; (define procedure-bottom-type (new-atomic-type))
  464. ; (define mask/procedure (meet procedure-nonbottom-type procedure-bottom-type))
  465. ; OTHER-VALUE-TYPE is a catchall for all the other ones we don't
  466. ; anticipate (for now including string, vector, char, etc.).
  467. (define other-value-type (named-atomic-type ':other))
  468. (define mask/other (type-mask other-value-type))
  469. (define (make-other-type id)
  470. (let ((t (make-type mask/other #f id)))
  471. (set-type-name! t id)
  472. t))
  473. (define char-type (make-other-type ':char))
  474. (define unspecific-type (make-other-type ':unspecific))
  475. (define string-type (make-other-type ':string))
  476. (define symbol-type (make-other-type ':symbol))
  477. (define vector-type (make-other-type ':vector))
  478. (define escape-type (make-other-type ':escape))
  479. (define structure-type (make-other-type ':structure))
  480. ; --------------------
  481. ; Procedures.
  482. (define mask/procedure (type-mask any-procedure-type))
  483. (define (procedure-type dom cod r?)
  484. (make-procedure-type mask/procedure dom cod r?))
  485. (define (make-procedure-type m dom cod r?)
  486. (make-type m
  487. #f
  488. (if (and (not r?)
  489. (same-type? dom value-type)
  490. (same-type? cod value-type))
  491. #f ;LUB of all procedure types
  492. (list dom cod r?))))
  493. (define (procedure-type-domain t)
  494. (let ((info (type-info t)))
  495. (if (pair? info)
  496. (car info)
  497. any-values-type)))
  498. (define (procedure-type-codomain t)
  499. (let ((info (type-info t)))
  500. (if (pair? info)
  501. (cadr info)
  502. any-values-type)))
  503. (define (restrictive? t)
  504. (let ((info (type-info t)))
  505. (if (pair? info)
  506. (caddr info)
  507. #f)))
  508. ; --------------------
  509. ; Conversion to and from S-expression.
  510. (define (sexp->type x r?)
  511. (cond ((symbol? x)
  512. (name->type x))
  513. ((pair? x)
  514. (case (car x)
  515. ((some-values)
  516. (sexp->values-type (cdr x) #t r?))
  517. ((proc procedure-type)
  518. (let ((r? (if (or (null? (cdddr x))
  519. (eq? (cadddr x) r?))
  520. r?
  521. (not r?))))
  522. (procedure-type (sexp->values-type (cadr x) #t (not r?))
  523. (sexp->type (caddr x) r?)
  524. r?)))
  525. ((meet)
  526. (if (null? (cdr x))
  527. bottom-type
  528. (let ((l (map (lambda (x) (sexp->type x r?)) (cdr x))))
  529. (reduce meet-type (car l) (cdr l)))))
  530. ((join)
  531. (let ((l (map (lambda (x) (sexp->type x r?)) (cdr x))))
  532. (reduce join-type (car l) (cdr l))))
  533. ((mask->type)
  534. (mask->type (cadr x)))
  535. ((variable)
  536. (variable-type (sexp->type (cadr x) r?)))
  537. (else (assertion-violation 'sexp->type "unrecognized type" x))))
  538. (else (assertion-violation 'sexp->type "unrecognized type" x))))
  539. (define (sexp->values-type l req? r?)
  540. (cond ((null? l)
  541. empty-rail-type)
  542. ((eq? (car l) '&rest)
  543. (make-rest-type (sexp->type (cadr l) r?)))
  544. ((eq? (car l) '&opt)
  545. (sexp->values-type (cdr l) #f r?))
  546. ((eq? (car l) 'rail-type)
  547. (sexp->values-type (cdr l) req? r?))
  548. (else
  549. (let ((t (sexp->type (car l) r?)))
  550. (rail-type (if req? t (make-optional-type t))
  551. (sexp->values-type (cdr l)
  552. req?
  553. r?))))))
  554. ; Convert type to S-expression
  555. (define (type->sexp t r?)
  556. (if (variable-type? t)
  557. `(variable ,(type->sexp (variable-value-type t) r?))
  558. (if (> (bitwise-and (type-mask t) mask/&rest) 0)
  559. (if (same-type? t any-values-type)
  560. ':values
  561. `(some-values ,@(rail-type->sexp t r?)))
  562. (let ((j (disjoin-type t)))
  563. (cond ((null? j) ':error)
  564. ((null? (cdr j))
  565. (atomic-type->sexp (car j) r?))
  566. (else
  567. `(join ,@(map (lambda (t)
  568. (atomic-type->sexp t r?))
  569. j))))))))
  570. (define (atomic-type->sexp t r?)
  571. (let ((m (type-mask t)))
  572. (cond ((and (not (type-info t))
  573. (table-ref mask->name-table m)))
  574. ((= m mask/other)
  575. (or (type-info t) ':value)) ;not quite
  576. ((= m mask/procedure)
  577. (let ((r (restrictive? t)))
  578. `(proc ,(rail-type->sexp (procedure-type-domain t)
  579. (not r))
  580. ,(type->sexp (procedure-type-codomain t) r)
  581. ,@(if (eq? r r?)
  582. '()
  583. `(,r)))))
  584. ((type-info t)
  585. `(ill-formed ,(type-mask t) ,(type-info t)))
  586. ((subtype? t exact-type)
  587. `(meet :exact
  588. ,(type->sexp (mask->type (let ((m (type-mask t)))
  589. (bitwise-ior m (arithmetic-shift m 1))))
  590. #t)))
  591. ((subtype? t inexact-type)
  592. `(meet :inexact
  593. ,(type->sexp (mask->type (let ((m (type-mask t)))
  594. (bitwise-ior m (arithmetic-shift m -1))))
  595. #t)))
  596. ;; ((meet? t number-type) ...)
  597. (else
  598. `(mask->type ,(type-mask t))))))
  599. (define (rail-type->sexp t r?)
  600. (let recur ((t t) (prev-req? #t) (r? r?))
  601. (cond ((empty-rail-type? t) '())
  602. ((rest-type? t)
  603. `(&rest ,(type->sexp (head-type-really t) r?)))
  604. ((optional-type? t)
  605. (let ((tail (cons (type->sexp (head-type-really t) r?)
  606. (recur (tail-type t) #f r?))))
  607. (if prev-req?
  608. `(&opt ,@tail)
  609. tail)))
  610. (else
  611. (cons (type->sexp (head-type t) r?)
  612. (recur (tail-type t) #t r?))))))
  613. ; Decompose a type into components
  614. (define (disjoin-type t)
  615. (cond ((bottom-type? t) '())
  616. ((and (not (type-info t))
  617. (table-ref mask->name-table (type-mask t)))
  618. (list t))
  619. ((meet? t other-value-type)
  620. (cons (meet-type t other-value-type)
  621. (disjoin-rest t mask/other)))
  622. ((meet? t any-procedure-type)
  623. (cons (meet-type t any-procedure-type)
  624. (disjoin-rest t mask/procedure)))
  625. ((meet? t number-type)
  626. (cons (meet-type t number-type)
  627. (disjoin-rest t mask/number)))
  628. (else
  629. (do ((i 1 (arithmetic-shift i 1)))
  630. ((> (bitwise-and (type-mask t) i) 0)
  631. (cons (mask->type i)
  632. (disjoin-rest t i)))))))
  633. (define (disjoin-rest t mask)
  634. (disjoin-type (mask->type (bitwise-and (type-mask t)
  635. (bitwise-not mask)))))
  636. (define mask/number (type-mask number-type))
  637. ; --------------------
  638. ; obsolescent? see lambda and values reconstructors in recon.scm
  639. (define (make-some-values-type types)
  640. (if (null? types)
  641. empty-rail-type
  642. (rail-type (car types) (make-some-values-type (cdr types)))))
  643. (define-syntax proc
  644. (syntax-rules ()
  645. ((proc (?type ...) ?cod)
  646. (procedure-type (some-values ?type ...) ?cod #t))
  647. ((proc (?type ...) ?cod ?r)
  648. (procedure-type (some-values ?type ...) ?cod ?r))))
  649. (define-syntax some-values
  650. (syntax-rules (&opt &rest)
  651. ((some-values) empty-rail-type)
  652. ((some-values &opt) empty-rail-type)
  653. ((some-values ?t) ?t)
  654. ((some-values &rest ?t) (make-rest-type ?t))
  655. ((some-values &opt &rest ?t) (make-rest-type ?t))
  656. ((some-values &opt ?t1 . ?ts)
  657. (rail-type (make-optional-type ?t1)
  658. (some-values &opt . ?ts)))
  659. ((some-values ?t1 . ?ts)
  660. (rail-type ?t1 (some-values . ?ts)))))
  661. (define (procedure-type? t)
  662. (= (type-mask t) mask/procedure))
  663. (define (fixed-arity-procedure-type? t)
  664. (and (procedure-type? t)
  665. (let loop ((d (procedure-type-domain t)))
  666. (cond ((empty-rail-type? d) #t)
  667. ((optional-type? d) #f)
  668. (else (loop (tail-type d)))))))
  669. (define (procedure-type-arity t)
  670. (do ((d (procedure-type-domain t) (tail-type d))
  671. (i 0 (+ i 1)))
  672. ((empty-rail-type? d) i)
  673. (if (optional-type? d)
  674. (assertion-violation 'procedure-type-arity "this shouldn't happen" t d))))
  675. (define (procedure-type-argument-types t)
  676. (let recur ((d (procedure-type-domain t)))
  677. (cond ((empty-rail-type? d) '())
  678. ((optional-type? d)
  679. (assertion-violation 'procedure-type-argument-types "lossage" t))
  680. (else
  681. (cons (head-type d)
  682. (recur (tail-type d)))))))
  683. ;----------------
  684. ; Odd types - variable types and the undeclared type
  685. ;
  686. ; These were elsewhere (syntax.scm) and should be here. If I could understand
  687. ; the above code I could make these be `real' types.
  688. (define (variable-type type)
  689. (list 'variable type))
  690. (define (variable-type? type)
  691. (and (pair? type) (eq? (car type) 'variable)))
  692. (define variable-value-type cadr)
  693. ; Usual type for Scheme variables.
  694. (define usual-variable-type (variable-type value-type))
  695. ; cf. EXPORT macro
  696. (define undeclared-type ':undeclared)
  697. ;----------------
  698. ; Used in two places:
  699. ; 1. GET-LOCATION checks to see if the context of use (either variable
  700. ; reference or assignment) is compatible with the declared type.
  701. ; 2. CHECK-STRUCTURE checks to see if the reconstructed type is compatible
  702. ; with any type declared in the interface.
  703. (define (compatible-types? have-type want-type)
  704. (if (variable-type? want-type)
  705. (and (variable-type? have-type)
  706. (same-type? (variable-value-type have-type)
  707. (variable-value-type want-type)))
  708. (meet? (if (variable-type? have-type)
  709. (variable-value-type have-type)
  710. have-type)
  711. want-type)))