run.scm 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; These are the four entry points (cf. rts/eval.scm):
  4. ; EVAL
  5. (define (eval form package)
  6. (compile-and-run (list form) package #f))
  7. ; LOAD-INTO - load file into package.
  8. (define (load-into filename package)
  9. (compile-and-run (read-forms filename package #f)
  10. package
  11. filename))
  12. ; Evaluate forms as if they came from the given file.
  13. (define (eval-from-file forms package filename)
  14. (if filename
  15. ((fluid-cell-ref $note-file-package)
  16. filename package))
  17. (compile-and-run forms package filename))
  18. ; LOAD
  19. (define (load filename . package-option)
  20. (let ((package (if (null? package-option)
  21. (interaction-environment)
  22. (car package-option))))
  23. (load-into filename package)))
  24. ;----------------
  25. (define (compile-and-run forms package maybe-filename)
  26. (let* ((env (if maybe-filename
  27. (bind-source-file-name maybe-filename
  28. (package->environment package))
  29. (package->environment package)))
  30. (nodes (map (lambda (form)
  31. (expand-scanned-form form env))
  32. (scan-forms forms env))))
  33. (if (not (null? nodes))
  34. (run-nodes nodes env))))
  35. (define (run-nodes nodes env)
  36. (do ((nodes nodes (cdr nodes)))
  37. ((null? (cdr nodes))
  38. (run-node (car nodes) env))
  39. (run-node (car nodes) env)))
  40. (define (run-node node env)
  41. (cond ((define-node? node)
  42. (let* ((form (node-form node))
  43. (loc (binding-place (lookup env (cadr form))))
  44. (value (run (caddr form) env)))
  45. (set-location-defined?! loc #t)
  46. (set-contents! loc value)))
  47. ((not (define-syntax-node? node))
  48. (run node env))))
  49. ; Main dispatch for a single expression.
  50. (define (run node env)
  51. ((operator-table-ref interpreters (node-operator-id node))
  52. node
  53. env))
  54. (define interpreters
  55. (make-operator-table (lambda (node env)
  56. (run-call (node-form node) env))))
  57. (define (define-interpreter name type proc)
  58. (operator-define! interpreters name type proc))
  59. (define-interpreter 'name #f
  60. (lambda (node env)
  61. (let ((binding (name-node-binding node env)))
  62. (cond ((binding? binding)
  63. (if (and (compatible-types? (binding-type binding) value-type)
  64. (location? (binding-place binding)))
  65. (let ((loc (binding-place binding)))
  66. (if (location-defined? loc)
  67. (contents loc)
  68. (error "uninitialized variable" (schemify node env))))
  69. (assertion-violation 'name "invalid variable reference" (schemify node env))))
  70. ((unbound? binding)
  71. (assertion-violation 'name "unbound variable" (schemify node env)))
  72. (else
  73. (assertion-violation 'name "peculiar binding" node binding))))))
  74. (define (name-node-binding node env)
  75. (or (node-ref node 'binding)
  76. (lookup env (node-form node))))
  77. (define-interpreter 'literal #f
  78. (lambda (node env)
  79. (node-form node)))
  80. (define-interpreter 'call #f
  81. (lambda (node env)
  82. (run-call (node-form node) env)))
  83. (define (run-call exp env)
  84. (let ((proc (run (car exp) env))) ;Doing this first aids debugging
  85. (apply proc
  86. (map (lambda (arg-exp)
  87. (run arg-exp env))
  88. (cdr exp)))))
  89. (define-interpreter 'quote syntax-type
  90. (lambda (node env)
  91. (cadr (node-form node))))
  92. (define-interpreter 'lambda syntax-type
  93. (lambda (node env)
  94. (let ((exp (node-form node)))
  95. (make-interpreted-closure (cadr exp) (cddr exp) env))))
  96. (define (make-interpreted-closure formals body env)
  97. (lambda args
  98. (run-body body (bind-vars formals args env))))
  99. (define (run-body body env)
  100. (scan-body
  101. body
  102. env
  103. (lambda (defs exps)
  104. (if (null? defs)
  105. (run-begin exps env)
  106. (run-letrec (map (lambda (def) (cdr (node-form def))) defs)
  107. exps
  108. env)))))
  109. (define-interpreter 'begin syntax-type
  110. (lambda (node env)
  111. (let ((exp (node-form node)))
  112. (run-begin (cdr exp) env))))
  113. (define (run-begin exp-list env)
  114. (if (null? exp-list)
  115. (syntax-violation 'begin "null begin" `(begin ,@exp-list))
  116. (let loop ((exp-list exp-list))
  117. (if (null? (cdr exp-list))
  118. (run (car exp-list) env)
  119. (begin (run (car exp-list) env)
  120. (loop (cdr exp-list)))))))
  121. (define-interpreter 'set! syntax-type
  122. (lambda (node env)
  123. (let* ((exp (node-form node))
  124. (probe (name-node-binding (cadr exp) env)))
  125. (cond ((and (binding? probe)
  126. (location? (binding-place probe)))
  127. (if (and (location-defined? (binding-place probe))
  128. (variable-type? (binding-type probe)))
  129. (set-contents! (binding-place probe)
  130. (run (caddr exp) env))
  131. (assertion-violation 'set! "invalid assignment" (schemify node env))))
  132. ((unbound? probe) (assertion-violation 'set! "unbound variable" exp))
  133. (else (assertion-violation 'set! "peculiar assignment" exp))))))
  134. (define-interpreter 'if syntax-type
  135. (lambda (node env)
  136. (let ((exp (node-form node)))
  137. (if (null? (cdddr exp))
  138. (if (run (cadr exp) env)
  139. (run (caddr exp) env)) ;hack
  140. (if (run (cadr exp) env)
  141. (run (caddr exp) env)
  142. (run (cadddr exp) env))))))
  143. ; (reverse specs) in order to try to catch unportabilities
  144. (define-interpreter 'letrec syntax-type
  145. (lambda (node env)
  146. (let ((exp (node-form node)))
  147. (run-letrec (cadr exp) (cddr exp) env))))
  148. (define (run-letrec specs body env)
  149. (let* ((bindings (map (lambda (spec)
  150. (make-binding usual-variable-type
  151. (make-undefined-location (car spec))
  152. #f))
  153. specs))
  154. (env (bind (map car specs)
  155. bindings
  156. env)))
  157. (for-each (lambda (binding val)
  158. (let ((loc (binding-place binding)))
  159. (set-location-defined?! loc #t)
  160. (set-contents! loc val)))
  161. bindings
  162. (map (lambda (spec) (run (cadr spec) env)) specs))
  163. (run-body body env)))
  164. (let ((bad (lambda (node env)
  165. (assertion-violation 'definition
  166. "not valid in expression context" (node-form node)))))
  167. (define-interpreter 'define syntax-type bad)
  168. (define-interpreter 'define-syntax syntax-type bad))
  169. ; Primitive procedures
  170. (define-interpreter 'primitive-procedure syntax-type
  171. (lambda (node env)
  172. (let ((name (cadr (node-form node))))
  173. (or (table-ref primitive-procedures name)
  174. (lambda args
  175. (assertion-violation 'primitive-procedure
  176. "unimplemented primitive procedure" name))))))
  177. (define primitive-procedures (make-table))
  178. (define (define-a-primitive name proc)
  179. (table-set! primitive-procedures name proc)
  180. (define-interpreter name any-procedure-type
  181. (lambda (node env)
  182. (apply proc (map (lambda (arg) (run arg env))
  183. (cdr (node-form node)))))))
  184. (define-a-primitive 'unspecific
  185. (lambda () (if #f #f))) ;For COND
  186. (define-syntax define-some-primitives
  187. (syntax-rules ()
  188. ((define-some-primitives name ...)
  189. (begin (define-a-primitive 'name name) ...))))
  190. (define-some-primitives
  191. + - * quotient remainder = <
  192. eq? car cdr cons
  193. pair?
  194. vector? vector-ref string? string-ref
  195. symbol?
  196. char<? char=?)
  197. ; --------------------
  198. ; Environments
  199. (define (bind-var name arg env)
  200. (let ((loc (make-undefined-location name)))
  201. (set-location-defined?! loc #t)
  202. (set-contents! loc arg)
  203. (bind1 name (make-binding usual-variable-type loc #f) env)))
  204. (define (bind-vars names args env)
  205. (cond ((null? names)
  206. (if (null? args)
  207. env
  208. (assertion-violation 'bind-vars "too many arguments" args)))
  209. ((not (pair? names))
  210. (bind-var names args env))
  211. ((null? args)
  212. (assertion-violation 'bind-vars "too few arguments" names))
  213. (else
  214. (bind-var (car names) (car args)
  215. (bind-vars (cdr names) (cdr args) env)))))
  216. ; (scan-structures (list s) (lambda (p) #t) (lambda (stuff) #f))