run.scm 7.4 KB

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