eval.scm 5.0 KB

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