base.scm 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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/primop/base.scm
  8. (define-module (ps-compiler prescheme primop base)
  9. #:use-module (prescheme scheme48)
  10. #:use-module (ps-compiler node arch)
  11. #:use-module (ps-compiler node node)
  12. #:use-module (ps-compiler node node-util)
  13. #:use-module (ps-compiler node let-nodes)
  14. #:use-module (ps-compiler node primop)
  15. #:use-module (ps-compiler node variable)
  16. #:use-module (ps-compiler param)
  17. #:use-module (ps-compiler prescheme primop primop)
  18. #:use-module (ps-compiler prescheme type)
  19. #:use-module (ps-compiler simp call)
  20. #:use-module (ps-compiler simp let)
  21. #:use-module (ps-compiler simp simplify)
  22. #:use-module (ps-compiler util util))
  23. (define (simplify-letrec1 call)
  24. (let* ((cont (call-arg call 0))
  25. (next (lambda-body cont))
  26. (var (car (lambda-variables cont))))
  27. (if (not (and (calls-this-primop? next 'letrec2)
  28. (= 1 (length (variable-refs var)))
  29. (eq? next (node-parent (car (variable-refs var))))
  30. (= 1 (node-index (car (variable-refs var))))))
  31. (error "badly formed LETREC ~S ~S" call (node-parent call)))
  32. (simplify-args call 0)
  33. (check-letrec-scoping call cont next)
  34. (if (every? unused? (cdr (lambda-variables cont)))
  35. (replace-body call (detach-body (lambda-body (call-arg next 0)))))))
  36. (define (check-letrec-scoping letrec1 binder letrec2)
  37. (let ((values (sub-vector->list (call-args letrec2) 2))
  38. (body (call-arg letrec2 0)))
  39. (for-each (lambda (n) (set-node-flag! n 'okay)) values)
  40. (set-node-flag! body 'okay)
  41. (for-each (lambda (var)
  42. (for-each (lambda (ref)
  43. (set-node-flag! (marked-ancestor ref) 'lose))
  44. (variable-refs var)))
  45. (cdr (lambda-variables binder)))
  46. (let ((non-recur (filter (lambda (p)
  47. (eq? (node-flag (car p)) 'okay))
  48. (map cons values (cdr (lambda-variables binder))))))
  49. (for-each (lambda (n) (set-node-flag! n #f)) values)
  50. (set-node-flag! body #f)
  51. (if (not (null? non-recur))
  52. (letrec->let (map car non-recur)
  53. (map cdr non-recur)
  54. letrec1 binder letrec2)))))
  55. (define (letrec->let vals vars letrec1 binder letrec2)
  56. (for-each detach vals)
  57. (remove-null-arguments letrec2
  58. (- (vector-length (call-args letrec2))
  59. (length vals)))
  60. (set-lambda-variables!
  61. binder
  62. (filter (lambda (v) (not (memq v vars)))
  63. (lambda-variables binder)))
  64. (move-body letrec1
  65. (lambda (letrec1)
  66. (let-nodes ((call (let 1 l1 . vals))
  67. (l1 vars letrec1))
  68. call))))
  69. ;; (return (lambda (a) ...) x)
  70. ;; =>
  71. ;; (let (lambda (a) ...) x)
  72. (define (simplify-ps-return call)
  73. (let ((cont (call-arg call 0))
  74. (value (call-arg call 1)))
  75. (cond ((not (lambda-node? cont))
  76. (default-simplifier call))
  77. (else
  78. (set-call-primop! call (get-primop (enum primop-enum let)))
  79. (set-call-exits! call 1)
  80. (set-node-simplified?! call #f)))))
  81. (make-primop 'dispatch #f #f default-simplifier (lambda (call) 1) #f)
  82. (make-primop 'let #f #f simplify-let (lambda (call) 1) #f)
  83. (make-primop 'letrec1 #f #f (lambda (call)
  84. (simplify-letrec1 call)) (lambda (call) 1) #f)
  85. (make-primop 'letrec2 #f #f default-simplifier (lambda (call) 1) #f)
  86. (make-primop 'undefined-value #t #f default-simplifier
  87. (lambda (call) 1)
  88. (lambda (call) type/null))
  89. (make-primop 'undefined-effect #t #f default-simplifier
  90. (lambda (call) 1)
  91. (lambda (call) type/null))
  92. (make-primop 'global-ref #t 'read default-simplifier
  93. (lambda (call) 1)
  94. (lambda (call)
  95. (variable-type (reference-variable (call-arg call 0)))))
  96. ;;(make-primop 'allocate #f #f 'allocate simplify-allocation (lambda (call) 1))
  97. (make-primop 'global-set! #f 'write default-simplifier
  98. (lambda (call) 1) #f)
  99. (make-proc-primop 'call 'write simplify-known-call
  100. (lambda (call) 1) 1)
  101. (make-proc-primop 'tail-call 'write simplify-known-tail-call
  102. (lambda (call) 1) 1)
  103. (make-proc-primop 'return #f simplify-ps-return (lambda (call) 1) 0)
  104. (make-proc-primop 'jump #f simplify-jump (lambda (call) 1) 0)
  105. (make-proc-primop 'throw #f default-simplifier (lambda (call) 1) 0)
  106. ;; This delays simplifying the arguments until we see if the procedure
  107. ;; is a lambda-node.
  108. (define (simplify-unknown-call call)
  109. (simplify-arg call 1) ;; simplify the procedure
  110. (let ((proc (call-arg call 1)))
  111. (cond ((lambda-node? proc)
  112. (determine-lambda-protocol proc (list proc))
  113. (mark-changed proc))
  114. ((and (reference-node? proc)
  115. (variable-simplifier (reference-variable proc)))
  116. => (lambda (proc)
  117. (proc call)))
  118. (else
  119. (simplify-args call 0))))) ;; simplify all arguments
  120. (make-proc-primop 'unknown-call 'write simplify-unknown-call
  121. (lambda (call) 1) 1)
  122. (make-proc-primop 'unknown-tail-call 'write simplify-unknown-call
  123. (lambda (call) 1) 1)
  124. (make-proc-primop 'unknown-return #f default-simplifier
  125. (lambda (call) 1) 0)
  126. (define (simplify-unspecific call)
  127. (let ((node (make-undefined-literal)))
  128. (set-literal-type! node type/null)
  129. (replace call node)))
  130. (define-scheme-primop unspecific #f type/null simplify-unspecific)
  131. (define-scheme-primop uninitialized-value type/null)
  132. (define-scheme-primop null-pointer? type/boolean)
  133. (define-polymorphic-scheme-primop null-pointer
  134. (lambda (call)
  135. (literal-value (call-arg call 0))))
  136. (define-scheme-primop eq? type/boolean) ;; should have a simplifier
  137. ;;(define (exp->type exp)
  138. ;; (if (quote-exp? exp)
  139. ;; (real-exp->type (quote-exp-value exp))
  140. ;; (error "can't turn ~S into a type" exp)))
  141. ;;
  142. ;;(define (real-exp->type exp)
  143. ;; (let ((lose (lambda () (error "can't turn ~S into a type" exp))))
  144. ;; (let label ((exp exp))
  145. ;; (cond ((pair? exp)
  146. ;; (case (car exp)
  147. ;; ((pointer)
  148. ;; (make-pointer-type (label (cadr exp))))
  149. ;; ((arrow)
  150. ;; (make-arrow-type (map label (cadr exp)) (caddr exp)))
  151. ;; (else
  152. ;; (lose))))
  153. ;; ((and (symbol? exp)
  154. ;; (lookup-type exp))
  155. ;; => identity)
  156. ;; (else
  157. ;; (lose))))))
  158. (define-scheme-cond-primop test simplify-test expand-test simplify-test?)
  159. ;;(define-primitive-expander 'unspecific 0
  160. ;; (lambda (source args cenv)
  161. ;; (make-quote-exp the-undefined-value type/unknown)))