eval.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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/eval.scm
  8. ;;;
  9. ;;; Evaluator for nodes.
  10. ;;;
  11. ;;; This doesn't handle n-ary procedures.
  12. ;;;
  13. ;;; (NAME-NODE-BINDING name-node) is used as an EQ? key in local environments,
  14. ;;; and passed as-is to the global-environment arguments.
  15. ;;;
  16. ;;; Exports:
  17. ;;; (EVAL-NODE node global-ref global-set! eval-primitive)
  18. ;;; CLOSURE? (CLOSURE-NODE closure) (CLOSURE-ENV closure)
  19. ;;; (UNSPECIFIC? thing)
  20. (define-module (ps-compiler prescheme eval)
  21. #:use-module (srfi srfi-9)
  22. #:use-module (prescheme scheme48)
  23. #:use-module (prescheme bcomp node)
  24. #:use-module (prescheme ps-defenum)
  25. #:use-module (ps-compiler prescheme external-value)
  26. #:use-module (ps-compiler prescheme type)
  27. #:export (eval-node
  28. closure? closure-node closure-env
  29. make-top-level-closure
  30. closure-temp set-closure-temp!
  31. apply-closure
  32. unspecific? constant?))
  33. (define (eval-node node global-ref global-set! eval-primitive)
  34. (eval node (make-env '()
  35. (make-eval-data global-ref
  36. global-set!
  37. eval-primitive))))
  38. (define-record-type :eval-data
  39. (make-eval-data global-ref global-set! eval-primitive)
  40. eval-data?
  41. (global-ref eval-data-global-ref)
  42. (global-set! eval-data-global-set!)
  43. (eval-primitive eval-data-eval-primitive))
  44. ;; Environments
  45. (define-record-type :env
  46. (make-env alist eval-data)
  47. env?
  48. (alist env-alist)
  49. (eval-data env-eval-data))
  50. (define (env-ref env name-node)
  51. (let ((cell (assq name-node (env-alist env))))
  52. (if cell
  53. (cdr cell)
  54. ((eval-data-global-ref (env-eval-data env)) name-node))))
  55. (define (env-set! env name-node value)
  56. (let ((cell (assq name-node (env-alist env))))
  57. (if cell
  58. (set-cdr! cell value)
  59. ((eval-data-global-set! (env-eval-data env))
  60. name-node
  61. value))))
  62. (define (extend-env env ids vals)
  63. (make-env (append (map cons ids vals)
  64. (env-alist env))
  65. (env-eval-data env)))
  66. (define (eval-primitive primitive args env)
  67. ((eval-data-eval-primitive (env-eval-data env)) primitive args))
  68. ;; Closures
  69. (define-record-type :closure
  70. (make-closure node env)
  71. closure?
  72. (node closure-node)
  73. (env real-closure-env)
  74. (temp closure-temp set-closure-temp!))
  75. (define (closure-env closure) ;; exported
  76. (env-alist (real-closure-env closure)))
  77. (define (make-top-level-closure exp)
  78. (make-closure exp the-empty-env))
  79. (define the-empty-env (make-env '() #f))
  80. ;; Main dispatch
  81. (define (eval node env)
  82. ((operator-table-ref evaluators (node-operator-id node))
  83. node
  84. env))
  85. ;; Particular operators
  86. (define evaluators
  87. (make-operator-table
  88. (lambda (node env)
  89. (error "no evaluator for node ~S" node))))
  90. (define (define-evaluator name proc)
  91. (operator-define! evaluators name #f proc))
  92. (define (eval-list nodes env)
  93. (map (lambda (node)
  94. (eval node env))
  95. nodes))
  96. (define-evaluator 'literal
  97. (lambda (node env)
  98. (node-form node)))
  99. (define-evaluator 'unspecific
  100. (lambda (node env)
  101. (unspecific)))
  102. (define-evaluator 'unassigned
  103. (lambda (node env)
  104. (unspecific)))
  105. (define-evaluator 'real-external
  106. (lambda (node env)
  107. (let* ((exp (node-form node))
  108. (type (expand-type-spec (cadr (node-form (caddr exp))))))
  109. (make-external-value (node-form (cadr exp))
  110. type))))
  111. (define-evaluator 'quote
  112. (lambda (node env)
  113. (cadr (node-form node))))
  114. (define-evaluator 'lambda
  115. (lambda (node env)
  116. (make-closure node env)))
  117. (define (apply-closure closure args)
  118. (let ((node (closure-node closure))
  119. (env (real-closure-env closure)))
  120. (eval (caddr (node-form node))
  121. (extend-env env (cadr (node-form node)) args))))
  122. (define-evaluator 'name
  123. (lambda (node env)
  124. (env-ref env node)))
  125. (define-evaluator 'set!
  126. (lambda (node env)
  127. (let ((exp (node-form node)))
  128. (env-set! env (cadr exp) (eval (caddr exp) env))
  129. (unspecific))))
  130. (define-evaluator 'call
  131. (lambda (node env)
  132. (eval-call (car (node-form node))
  133. (cdr (node-form node))
  134. env)))
  135. (define-evaluator 'goto
  136. (lambda (node env)
  137. (eval-call (cadr (node-form node))
  138. (cddr (node-form node))
  139. env)))
  140. (define (eval-call proc args env)
  141. (let ((proc (eval proc env))
  142. (args (eval-list args env)))
  143. (if (closure? proc)
  144. (apply-closure proc args)
  145. (eval-primitive proc args env))))
  146. (define-evaluator 'begin
  147. (lambda (node env)
  148. (let ((exps (cdr (node-form node))))
  149. (if (null? exps)
  150. (unspecific)
  151. (let loop ((exps exps))
  152. (cond ((null? (cdr exps))
  153. (eval (car exps) env))
  154. (else
  155. (eval (car exps) env)
  156. (loop (cdr exps)))))))))
  157. (define-evaluator 'if
  158. (lambda (node env)
  159. (let* ((form (node-form node))
  160. (test (cadr form))
  161. (arms (cddr form)))
  162. (cond ((eval test env)
  163. (eval (car arms) env))
  164. ((null? (cdr arms))
  165. (unspecific))
  166. (else
  167. (eval (cadr arms) env))))))
  168. (define-evaluator 'loophole
  169. (lambda (node env)
  170. (eval (caddr (node-form node)) env)))
  171. (define-evaluator 'letrec
  172. (lambda (node env)
  173. (let ((form (node-form node)))
  174. (let ((vars (map car (cadr form)))
  175. (vals (map cadr (cadr form)))
  176. (body (caddr form)))
  177. (let ((env (extend-env env
  178. vars
  179. (map (lambda (ignore)
  180. (unspecific))
  181. vars))))
  182. (for-each (lambda (var val)
  183. (env-set! env var (eval val env)))
  184. vars
  185. vals)
  186. (eval body env))))))
  187. (define (unspecific? x)
  188. (eq? x (unspecific)))
  189. ;; Used by our clients but not by us.
  190. (define (constant? x)
  191. (or (number? x)
  192. (symbol? x)
  193. (external-constant? x)
  194. (external-value? x)
  195. (boolean? x)))