front-end.scm 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/prescheme/front-end.scm
  8. (define-module (ps-compiler prescheme front-end)
  9. #:use-module (prescheme scheme48)
  10. #:use-module ((prescheme bcomp node) #:select (node?) #:prefix bcomp-)
  11. #:use-module ((prescheme bcomp schemify) #:select (schemify) #:prefix bcomp-)
  12. #:use-module (ps-compiler node variable)
  13. #:use-module (ps-compiler prescheme expand)
  14. #:use-module (ps-compiler prescheme flatten)
  15. #:use-module (ps-compiler prescheme form)
  16. #:use-module (ps-compiler prescheme infer-early)
  17. #:use-module (ps-compiler prescheme inference)
  18. #:use-module (ps-compiler prescheme linking)
  19. #:use-module ((ps-compiler prescheme record) #:select (reset-record-data!))
  20. #:use-module (ps-compiler prescheme type)
  21. #:use-module (ps-compiler prescheme type-scheme)
  22. #:use-module (ps-compiler prescheme type-var)
  23. #:use-module (ps-compiler util util)
  24. #:export (prescheme-front-end))
  25. (define (prescheme-front-end package-ids spec-files copy no-copy shadow)
  26. (receive (packages exports lookup)
  27. (package-specs->packages+exports package-ids spec-files)
  28. (let ((forms (flatten-definitions (scan-packages packages))))
  29. (annotate-forms! (car package-ids) lookup exports copy no-copy shadow)
  30. (receive (forms producer)
  31. (sort-forms forms)
  32. (format #t "Checking types~%")
  33. (let ((sorted (let loop ((forms '()))
  34. (cond ((producer)
  35. => (lambda (f)
  36. (type-check-form f)
  37. (loop (cons f forms))))
  38. (else
  39. (reverse forms))))))
  40. ;; (format #t "Adding coercions~%")
  41. ;; (add-type-coercions (form-reducer forms))
  42. sorted)))))
  43. (define (form-reducer forms)
  44. (lambda (proc init)
  45. (let loop ((forms forms) (value init))
  46. (if (null? forms)
  47. value
  48. (loop (cdr forms)
  49. (proc (form-name (car forms))
  50. (form-value (car forms))
  51. value))))))
  52. (define (test id files)
  53. (reset-node-id)
  54. (reset-record-data!)
  55. (prescheme-front-end id files '() '() '()))
  56. (define (annotate-forms! package-id lookup exports copy no-copy shadow)
  57. (mark-forms! exports
  58. lookup
  59. (lambda (f) (set-form-exported?! f #t))
  60. "exported")
  61. (mark-forms! copy
  62. lookup
  63. (lambda (f) (set-form-integrate! f 'yes))
  64. "to be copied")
  65. (mark-forms! no-copy
  66. lookup
  67. (lambda (f) (set-form-integrate! f 'no))
  68. "not to be copied")
  69. (for-each (lambda (data)
  70. (let ((owner (package-lookup lookup (caar data) (cadar data))))
  71. (if owner
  72. (mark-forms! (cdr data)
  73. lookup
  74. (lambda (f)
  75. (set-form-shadowed! owner
  76. (cons (form-var f)
  77. (form-shadowed owner))))
  78. (format #f "shadowed in ~S" (car data)))
  79. (format #t "Warning: no definition for ~S, cannot shadow ~S~%"
  80. (car data) (cdr data)))))
  81. shadow))
  82. (define (mark-forms! specs lookup marker mark)
  83. (let ((lose (lambda (p n)
  84. (format #t "Warning: no definition for ~S, cannot mark as ~A~%"
  85. (list p n) mark))))
  86. (for-each (lambda (spec)
  87. (let ((package-id (car spec))
  88. (ids (cdr spec)))
  89. (for-each (lambda (id)
  90. (cond ((package-lookup lookup package-id id)
  91. => marker)
  92. (else
  93. (lose package-id id))))
  94. ids)))
  95. specs)))
  96. (define (package-lookup lookup package-id id)
  97. (let ((var (lookup package-id id)))
  98. (and (variable? var)
  99. (maybe-variable->form var))))
  100. ;; Two possibilities:
  101. ;; 1. The variable is settable but the thunk gives it no particular value.
  102. ;; 2. A real value is or needs to be present, so we relate the type of
  103. ;; the variable with the type of the value.
  104. ;; thunk's value may be a STOB and not a lambda.
  105. (define (type-check-form form)
  106. ;; (format #t " ~S: " (variable-name (form-var form)))
  107. (let* ((value (form-value form))
  108. (var (form-var form))
  109. (name (form-name form))
  110. (value-type (cond ((bcomp-node? value)
  111. (infer-definition-type value (source-proc form)))
  112. ((variable? value)
  113. (get-package-variable-type value))
  114. (else
  115. (bug "unknown kind of form value ~S" value)))))
  116. (set-form-value-type! form value-type)
  117. (cond ((not (variable-set!? var))
  118. (let ((type (cond ((eq? type/unknown (variable-type var))
  119. (let ((type (schemify-type value-type 0)))
  120. (set-variable-type! var type)
  121. type))
  122. (else
  123. (unify! value-type (get-package-variable-type var) form)
  124. value-type))))
  125. (if (not (type-scheme? type))
  126. (make-nonpolymorphic! type)) ;; lock down any related uvars
  127. ;;(format #t "~S~%" (instantiate type))
  128. ))
  129. ((not (or (eq? type/unit value-type)
  130. (eq? type/null value-type)))
  131. (make-nonpolymorphic! value-type) ; no polymorphism allowed (so it
  132. ;; is not checked for, so there may be depth 0 uvars in the type)
  133. ;; (format #t " ~S~%" (instantiate value-type))
  134. (unify! value-type (get-package-variable-type var) form))
  135. ((eq? type/unknown (variable-type var))
  136. (get-package-variable-type var)))))
  137. (define (source-proc form)
  138. (lambda (port)
  139. (write-one-line port
  140. 70
  141. (lambda (port)
  142. (format port "~S = ~S"
  143. (form-name form)
  144. (bcomp-schemify
  145. (form-value form)))))))