eval.scm 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. ;;; -*- mode: scheme; coding: utf-8; -*-
  2. ;;;; Copyright (C) 2009-2015, 2018 Free Software Foundation, Inc.
  3. ;;;;
  4. ;;;; This library is free software; you can redistribute it and/or
  5. ;;;; modify it under the terms of the GNU Lesser General Public
  6. ;;;; License as published by the Free Software Foundation; either
  7. ;;;; version 3 of the License, or (at your option) any later version.
  8. ;;;;
  9. ;;;; This library is distributed in the hope that it will be useful,
  10. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;;; Lesser General Public License for more details.
  13. ;;;;
  14. ;;;; You should have received a copy of the GNU Lesser General Public
  15. ;;;; License along with this library; if not, write to the Free Software
  16. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. ;;;;
  18. ;;; Commentary:
  19. ;;; Scheme eval, written in Scheme.
  20. ;;;
  21. ;;; Expressions are first expanded, by the syntax expander (i.e.
  22. ;;; psyntax), then memoized into internal forms. The evaluator itself
  23. ;;; only operates on the internal forms ("memoized expressions").
  24. ;;;
  25. ;;; Environments are represented as a chain of vectors, linked through
  26. ;;; their first elements. The terminal element of an environment is the
  27. ;;; module that was current when the outer lexical environment was
  28. ;;; entered.
  29. ;;;
  30. ;;; Code:
  31. (define (primitive-eval exp)
  32. "Evaluate @var{exp} in the current module."
  33. (define-syntax env-toplevel
  34. (syntax-rules ()
  35. ((_ env)
  36. (let lp ((e env))
  37. (if (vector? e)
  38. (lp (vector-ref e 0))
  39. e)))))
  40. (define-syntax make-env
  41. (syntax-rules ()
  42. ((_ n init next)
  43. (let ((v (make-vector (1+ n) init)))
  44. (vector-set! v 0 next)
  45. v))))
  46. (define-syntax make-env*
  47. (syntax-rules ()
  48. ((_ next init ...)
  49. (vector next init ...))))
  50. (define-syntax env-ref
  51. (syntax-rules ()
  52. ((_ env depth width)
  53. (let lp ((e env) (d depth))
  54. (if (zero? d)
  55. (vector-ref e (1+ width))
  56. (lp (vector-ref e 0) (1- d)))))))
  57. (define-syntax env-set!
  58. (syntax-rules ()
  59. ((_ env depth width val)
  60. (let lp ((e env) (d depth))
  61. (if (zero? d)
  62. (vector-set! e (1+ width) val)
  63. (lp (vector-ref e 0) (1- d)))))))
  64. ;; This is a modified version of Oleg Kiselyov's "pmatch".
  65. (define-syntax-rule (match e cs ...)
  66. (let ((v e)) (expand-clauses v cs ...)))
  67. (define-syntax expand-clauses
  68. (syntax-rules ()
  69. ((_ v) ((error "unreachable")))
  70. ((_ v (pat e0 e ...) cs ...)
  71. (let ((fk (lambda () (expand-clauses v cs ...))))
  72. (expand-pattern v pat (let () e0 e ...) (fk))))))
  73. (define-syntax expand-pattern
  74. (syntax-rules (_ quote unquote ?)
  75. ((_ v _ kt kf) kt)
  76. ((_ v () kt kf) (if (null? v) kt kf))
  77. ((_ v (quote lit) kt kf)
  78. (if (equal? v (quote lit)) kt kf))
  79. ((_ v (unquote exp) kt kf)
  80. (if (equal? v exp) kt kf))
  81. ((_ v (x . y) kt kf)
  82. (if (pair? v)
  83. (let ((vx (car v)) (vy (cdr v)))
  84. (expand-pattern vx x (expand-pattern vy y kt kf) kf))
  85. kf))
  86. ((_ v (? pred var) kt kf)
  87. (if (pred v) (let ((var v)) kt) kf))
  88. ((_ v #f kt kf) (if (eqv? v #f) kt kf))
  89. ((_ v var kt kf) (let ((var v)) kt))))
  90. (define-syntax typecode
  91. (lambda (x)
  92. (syntax-case x ()
  93. ((_ type)
  94. (or (memoized-typecode (syntax->datum #'type))
  95. (error "not a typecode" (syntax->datum #'type)))))))
  96. (define-syntax-rule (lazy (arg ...) exp)
  97. (letrec ((proc (lambda (arg ...)
  98. (set! proc exp)
  99. (proc arg ...))))
  100. (lambda (arg ...)
  101. (proc arg ...))))
  102. (define (compile-lexical-ref depth width)
  103. (case depth
  104. ((0) (lambda (env) (env-ref env 0 width)))
  105. ((1) (lambda (env) (env-ref env 1 width)))
  106. ((2) (lambda (env) (env-ref env 2 width)))
  107. (else (lambda (env) (env-ref env depth width)))))
  108. (define (primitive=? name loc module var)
  109. "Return true if VAR is the same as the primitive bound to NAME."
  110. (match loc
  111. ((mode . loc)
  112. (and (match loc
  113. ((mod name* . public?) (eq? name* name))
  114. (_ (eq? loc name)))
  115. ;; `module' can be #f if the module system was not yet
  116. ;; booted when the environment was captured.
  117. (or (not module)
  118. (eq? var (module-local-variable the-root-module name)))))))
  119. (define (compile-top-call cenv loc args)
  120. (let* ((module (env-toplevel cenv))
  121. (var (%resolve-variable loc module)))
  122. (define-syntax-rule (maybe-primcall (prim ...) arg ...)
  123. (let ((arg (compile arg))
  124. ...)
  125. (cond
  126. ((primitive=? 'prim loc module var)
  127. (lambda (env) (prim (arg env) ...)))
  128. ...
  129. (else (lambda (env) ((variable-ref var) (arg env) ...))))))
  130. (match args
  131. (()
  132. (lambda (env) ((variable-ref var))))
  133. ((a)
  134. (maybe-primcall (1+ 1- car cdr lognot vector-length
  135. variable-ref string-length struct-vtable)
  136. a))
  137. ((a b)
  138. (maybe-primcall (+ - * / ash logand logior logxor
  139. cons vector-ref struct-ref variable-set!)
  140. a b))
  141. ((a b c)
  142. (maybe-primcall (vector-set! struct-set!) a b c))
  143. ((a b c . args)
  144. (let ((a (compile a))
  145. (b (compile b))
  146. (c (compile c))
  147. (args (let lp ((args args))
  148. (if (null? args)
  149. '()
  150. (cons (compile (car args)) (lp (cdr args)))))))
  151. (lambda (env)
  152. (apply (variable-ref var) (a env) (b env) (c env)
  153. (let lp ((args args))
  154. (if (null? args)
  155. '()
  156. (cons ((car args) env) (lp (cdr args))))))))))))
  157. (define (compile-call f args)
  158. (match f
  159. ((,(typecode box-ref) . (,(typecode resolve) . loc))
  160. (lazy (env) (compile-top-call env loc args)))
  161. (_
  162. (match args
  163. (()
  164. (let ((f (compile f)))
  165. (lambda (env) ((f env)))))
  166. ((a)
  167. (let ((f (compile f))
  168. (a (compile a)))
  169. (lambda (env) ((f env) (a env)))))
  170. ((a b)
  171. (let ((f (compile f))
  172. (a (compile a))
  173. (b (compile b)))
  174. (lambda (env) ((f env) (a env) (b env)))))
  175. ((a b c)
  176. (let ((f (compile f))
  177. (a (compile a))
  178. (b (compile b))
  179. (c (compile c)))
  180. (lambda (env) ((f env) (a env) (b env) (c env)))))
  181. ((a b c . args)
  182. (let ((f (compile f))
  183. (a (compile a))
  184. (b (compile b))
  185. (c (compile c))
  186. (args (let lp ((args args))
  187. (if (null? args)
  188. '()
  189. (cons (compile (car args)) (lp (cdr args)))))))
  190. (lambda (env)
  191. (apply (f env) (a env) (b env) (c env)
  192. (let lp ((args args))
  193. (if (null? args)
  194. '()
  195. (cons ((car args) env) (lp (cdr args)))))))))))))
  196. (define (compile-box-ref box)
  197. (match box
  198. ((,(typecode resolve) . loc)
  199. (lazy (cenv)
  200. (let ((var (%resolve-variable loc (env-toplevel cenv))))
  201. (lambda (env) (variable-ref var)))))
  202. ((,(typecode lexical-ref) depth . width)
  203. (lambda (env)
  204. (variable-ref (env-ref env depth width))))
  205. (_
  206. (let ((box (compile box)))
  207. (lambda (env)
  208. (variable-ref (box env)))))))
  209. (define (compile-resolve cenv loc)
  210. (let ((var (%resolve-variable loc (env-toplevel cenv))))
  211. (lambda (env) var)))
  212. (define (compile-top-branch cenv loc args consequent alternate)
  213. (let* ((module (env-toplevel cenv))
  214. (var (%resolve-variable loc module))
  215. (consequent (compile consequent))
  216. (alternate (compile alternate)))
  217. (define (generic-top-branch)
  218. (let ((test (compile-top-call cenv loc args)))
  219. (lambda (env)
  220. (if (test env) (consequent env) (alternate env)))))
  221. (define-syntax-rule (maybe-primcall (prim ...) arg ...)
  222. (cond
  223. ((primitive=? 'prim loc module var)
  224. (let ((arg (compile arg))
  225. ...)
  226. (lambda (env)
  227. (if (prim (arg env) ...)
  228. (consequent env)
  229. (alternate env)))))
  230. ...
  231. (else (generic-top-branch))))
  232. (match args
  233. ((a)
  234. (maybe-primcall (null? nil? pair? struct? string? vector? symbol?
  235. keyword? variable? bitvector? char? zero? not)
  236. a))
  237. ((a b)
  238. (maybe-primcall (eq? eqv? equal? = < > <= >= logtest logbit?)
  239. a b))
  240. (_
  241. (generic-top-branch)))))
  242. (define (compile-if test consequent alternate)
  243. (match test
  244. ((,(typecode call)
  245. (,(typecode box-ref) . (,(typecode resolve) . loc))
  246. . args)
  247. (lazy (env) (compile-top-branch env loc args consequent alternate)))
  248. (_
  249. (let ((test (compile test))
  250. (consequent (compile consequent))
  251. (alternate (compile alternate)))
  252. (lambda (env)
  253. (if (test env) (consequent env) (alternate env)))))))
  254. (define (compile-quote x)
  255. (lambda (env) x))
  256. (define (compile-let inits body)
  257. (let ((body (compile body))
  258. (width (vector-length inits)))
  259. (case width
  260. ((0) (lambda (env)
  261. (body (make-env* env))))
  262. ((1)
  263. (let ((a (compile (vector-ref inits 0))))
  264. (lambda (env)
  265. (body (make-env* env (a env))))))
  266. ((2)
  267. (let ((a (compile (vector-ref inits 0)))
  268. (b (compile (vector-ref inits 1))))
  269. (lambda (env)
  270. (body (make-env* env (a env) (b env))))))
  271. ((3)
  272. (let ((a (compile (vector-ref inits 0)))
  273. (b (compile (vector-ref inits 1)))
  274. (c (compile (vector-ref inits 2))))
  275. (lambda (env)
  276. (body (make-env* env (a env) (b env) (c env))))))
  277. ((4)
  278. (let ((a (compile (vector-ref inits 0)))
  279. (b (compile (vector-ref inits 1)))
  280. (c (compile (vector-ref inits 2)))
  281. (d (compile (vector-ref inits 3))))
  282. (lambda (env)
  283. (body (make-env* env (a env) (b env) (c env) (d env))))))
  284. (else
  285. (let lp ((n width)
  286. (k (lambda (env)
  287. (make-env width #f env))))
  288. (if (zero? n)
  289. (lambda (env)
  290. (body (k env)))
  291. (lp (1- n)
  292. (let ((init (compile (vector-ref inits (1- n)))))
  293. (lambda (env)
  294. (let* ((x (init env))
  295. (new-env (k env)))
  296. (env-set! new-env 0 (1- n) x)
  297. new-env))))))))))
  298. (define (compile-fixed-lambda body nreq)
  299. (case nreq
  300. ((0) (lambda (env)
  301. (lambda ()
  302. (body (make-env* env)))))
  303. ((1) (lambda (env)
  304. (lambda (a)
  305. (body (make-env* env a)))))
  306. ((2) (lambda (env)
  307. (lambda (a b)
  308. (body (make-env* env a b)))))
  309. ((3) (lambda (env)
  310. (lambda (a b c)
  311. (body (make-env* env a b c)))))
  312. ((4) (lambda (env)
  313. (lambda (a b c d)
  314. (body (make-env* env a b c d)))))
  315. ((5) (lambda (env)
  316. (lambda (a b c d e)
  317. (body (make-env* env a b c d e)))))
  318. ((6) (lambda (env)
  319. (lambda (a b c d e f)
  320. (body (make-env* env a b c d e f)))))
  321. ((7) (lambda (env)
  322. (lambda (a b c d e f g)
  323. (body (make-env* env a b c d e f g)))))
  324. (else
  325. (lambda (env)
  326. (lambda (a b c d e f g . more)
  327. (let ((env (make-env nreq #f env)))
  328. (env-set! env 0 0 a)
  329. (env-set! env 0 1 b)
  330. (env-set! env 0 2 c)
  331. (env-set! env 0 3 d)
  332. (env-set! env 0 4 e)
  333. (env-set! env 0 5 f)
  334. (env-set! env 0 6 g)
  335. (let lp ((n 7) (args more))
  336. (cond
  337. ((= n nreq)
  338. (unless (null? args)
  339. (scm-error 'wrong-number-of-args
  340. "eval" "Wrong number of arguments"
  341. '() #f))
  342. (body env))
  343. ((null? args)
  344. (scm-error 'wrong-number-of-args
  345. "eval" "Wrong number of arguments"
  346. '() #f))
  347. (else
  348. (env-set! env 0 n (car args))
  349. (lp (1+ n) (cdr args)))))))))))
  350. (define (compile-rest-lambda body nreq rest?)
  351. (case nreq
  352. ((0) (lambda (env)
  353. (lambda rest
  354. (body (make-env* env rest)))))
  355. ((1) (lambda (env)
  356. (lambda (a . rest)
  357. (body (make-env* env a rest)))))
  358. ((2) (lambda (env)
  359. (lambda (a b . rest)
  360. (body (make-env* env a b rest)))))
  361. ((3) (lambda (env)
  362. (lambda (a b c . rest)
  363. (body (make-env* env a b c rest)))))
  364. (else
  365. (lambda (env)
  366. (lambda (a b c . more)
  367. (let ((env (make-env (1+ nreq) #f env)))
  368. (env-set! env 0 0 a)
  369. (env-set! env 0 1 b)
  370. (env-set! env 0 2 c)
  371. (let lp ((n 3) (args more))
  372. (cond
  373. ((= n nreq)
  374. (env-set! env 0 n args)
  375. (body env))
  376. ((null? args)
  377. (scm-error 'wrong-number-of-args
  378. "eval" "Wrong number of arguments"
  379. '() #f))
  380. (else
  381. (env-set! env 0 n (car args))
  382. (lp (1+ n) (cdr args)))))))))))
  383. (define (compile-opt-lambda body nreq rest? nopt ninits unbound make-alt)
  384. (lambda (env)
  385. (define alt (and make-alt (make-alt env)))
  386. (lambda args
  387. (let ((nargs (length args)))
  388. (cond
  389. ((or (< nargs nreq) (and (not rest?) (> nargs (+ nreq nopt))))
  390. (if alt
  391. (apply alt args)
  392. ((scm-error 'wrong-number-of-args
  393. "eval" "Wrong number of arguments"
  394. '() #f))))
  395. (else
  396. (let* ((nvals (+ nreq (if rest? 1 0) ninits))
  397. (env (make-env nvals unbound env)))
  398. (define (bind-req args)
  399. (let lp ((i 0) (args args))
  400. (cond
  401. ((< i nreq)
  402. ;; Bind required arguments.
  403. (env-set! env 0 i (car args))
  404. (lp (1+ i) (cdr args)))
  405. (else
  406. (bind-opt args)))))
  407. (define (bind-opt args)
  408. (let lp ((i nreq) (args args))
  409. (cond
  410. ((and (< i (+ nreq nopt)) (< i nargs))
  411. (env-set! env 0 i (car args))
  412. (lp (1+ i) (cdr args)))
  413. (else
  414. (bind-rest args)))))
  415. (define (bind-rest args)
  416. (when rest?
  417. (env-set! env 0 (+ nreq nopt) args))
  418. (body env))
  419. (bind-req args))))))))
  420. (define (compile-kw-lambda body nreq rest? nopt kw ninits unbound make-alt)
  421. (define allow-other-keys? (car kw))
  422. (define keywords (cdr kw))
  423. (lambda (env)
  424. (define alt (and make-alt (make-alt env)))
  425. (lambda args
  426. (define (npositional args)
  427. (let lp ((n 0) (args args))
  428. (if (or (null? args)
  429. (and (>= n nreq) (keyword? (car args))))
  430. n
  431. (lp (1+ n) (cdr args)))))
  432. (let ((nargs (length args)))
  433. (cond
  434. ((or (< nargs nreq)
  435. (and alt (not rest?) (> (npositional args) (+ nreq nopt))))
  436. (if alt
  437. (apply alt args)
  438. ((scm-error 'wrong-number-of-args
  439. "eval" "Wrong number of arguments"
  440. '() #f))))
  441. (else
  442. (let* ((nvals (+ nreq (if rest? 1 0) ninits))
  443. (env (make-env nvals unbound env)))
  444. (define (bind-req args)
  445. (let lp ((i 0) (args args))
  446. (cond
  447. ((< i nreq)
  448. ;; Bind required arguments.
  449. (env-set! env 0 i (car args))
  450. (lp (1+ i) (cdr args)))
  451. (else
  452. (bind-opt args)))))
  453. (define (bind-opt args)
  454. (let lp ((i nreq) (args args))
  455. (cond
  456. ((and (< i (+ nreq nopt)) (< i nargs)
  457. (not (keyword? (car args))))
  458. (env-set! env 0 i (car args))
  459. (lp (1+ i) (cdr args)))
  460. (else
  461. (bind-rest args)))))
  462. (define (bind-rest args)
  463. (when rest?
  464. (env-set! env 0 (+ nreq nopt) args))
  465. (bind-kw args))
  466. (define (bind-kw args)
  467. (let lp ((args args))
  468. (cond
  469. ((pair? args)
  470. (cond
  471. ((keyword? (car args))
  472. (let ((k (car args))
  473. (args (cdr args)))
  474. (cond
  475. ((assq k keywords)
  476. => (lambda (kw-pair)
  477. ;; Found a known keyword; set its value.
  478. (if (pair? args)
  479. (let ((v (car args))
  480. (args (cdr args)))
  481. (env-set! env 0 (cdr kw-pair) v)
  482. (lp args))
  483. ((scm-error 'keyword-argument-error
  484. "eval"
  485. "Keyword argument has no value"
  486. '() (list k))))))
  487. ;; Otherwise unknown keyword.
  488. (allow-other-keys?
  489. (lp (if (pair? args) (cdr args) args)))
  490. (else
  491. ((scm-error 'keyword-argument-error
  492. "eval" "Unrecognized keyword"
  493. '() (list k)))))))
  494. (rest?
  495. ;; Be lenient parsing rest args.
  496. (lp (cdr args)))
  497. (else
  498. ((scm-error 'keyword-argument-error
  499. "eval" "Invalid keyword"
  500. '() (list (car args)))))))
  501. (else
  502. (body env)))))
  503. (bind-req args))))))))
  504. (define (compute-arity alt nreq rest? nopt kw)
  505. (let lp ((alt alt) (nreq nreq) (nopt nopt) (rest? rest?))
  506. (if (not alt)
  507. (let ((arglist (list nreq
  508. nopt
  509. (if kw (cdr kw) '())
  510. (and kw (car kw))
  511. (and rest? '_))))
  512. (values arglist nreq nopt rest?))
  513. (let* ((spec (cddr alt))
  514. (nreq* (car spec))
  515. (rest?* (if (null? (cdr spec)) #f (cadr spec)))
  516. (tail (and (pair? (cdr spec)) (pair? (cddr spec)) (cddr spec)))
  517. (nopt* (if tail (car tail) 0))
  518. (alt* (and tail (car (cddddr tail)))))
  519. (if (or (< nreq* nreq)
  520. (and (= nreq* nreq)
  521. (if rest?
  522. (and rest?* (> nopt* nopt))
  523. (or rest?* (> nopt* nopt)))))
  524. (lp alt* nreq* nopt* rest?*)
  525. (lp alt* nreq nopt rest?))))))
  526. (define (compile-general-lambda body nreq rest? nopt kw ninits unbound alt)
  527. (call-with-values
  528. (lambda ()
  529. (compute-arity alt nreq rest? nopt kw))
  530. (lambda (arglist min-nreq min-nopt min-rest?)
  531. (define make-alt
  532. (match alt
  533. (#f #f)
  534. ((body meta nreq . tail)
  535. (compile-lambda body meta nreq tail))))
  536. (define make-closure
  537. (if kw
  538. (compile-kw-lambda body nreq rest? nopt kw ninits unbound make-alt)
  539. (compile-opt-lambda body nreq rest? nopt ninits unbound make-alt)))
  540. (lambda (env)
  541. (let ((proc (make-closure env)))
  542. (set-procedure-property! proc 'arglist arglist)
  543. (set-procedure-minimum-arity! proc min-nreq min-nopt min-rest?)
  544. proc)))))
  545. (define (compile-lambda body meta nreq tail)
  546. (define (set-procedure-meta meta proc)
  547. (match meta
  548. (() proc)
  549. (((prop . val) . meta)
  550. (set-procedure-meta meta
  551. (lambda (env)
  552. (let ((proc (proc env)))
  553. (set-procedure-property! proc prop val)
  554. proc))))))
  555. (let ((body (lazy (env) (compile body))))
  556. (set-procedure-meta
  557. meta
  558. (match tail
  559. (() (compile-fixed-lambda body nreq))
  560. ((rest? . tail)
  561. (match tail
  562. (() (compile-rest-lambda body nreq rest?))
  563. ((nopt kw ninits unbound alt)
  564. (compile-general-lambda body nreq rest? nopt kw
  565. ninits unbound alt))))))))
  566. (define (compile-capture-env locs body)
  567. (let ((body (compile body)))
  568. (lambda (env)
  569. (let* ((len (vector-length locs))
  570. (new-env (make-env len #f (env-toplevel env))))
  571. (let lp ((n 0))
  572. (when (< n len)
  573. (match (vector-ref locs n)
  574. ((depth . width)
  575. (env-set! new-env 0 n (env-ref env depth width))))
  576. (lp (1+ n))))
  577. (body new-env)))))
  578. (define (compile-seq head tail)
  579. (let ((head (compile head))
  580. (tail (compile tail)))
  581. (lambda (env)
  582. (head env)
  583. (tail env))))
  584. (define (compile-box-set! box val)
  585. (let ((box (compile box))
  586. (val (compile val)))
  587. (lambda (env)
  588. (let ((val (val env)))
  589. (variable-set! (box env) val)))))
  590. (define (compile-lexical-set! depth width x)
  591. (let ((x (compile x)))
  592. (lambda (env)
  593. (env-set! env depth width (x env)))))
  594. (define (compile-call-with-values producer consumer)
  595. (let ((producer (compile producer))
  596. (consumer (compile consumer)))
  597. (lambda (env)
  598. (call-with-values (producer env)
  599. (consumer env)))))
  600. (define (compile-apply f args)
  601. (let ((f (compile f))
  602. (args (compile args)))
  603. (lambda (env)
  604. (apply (f env) (args env)))))
  605. (define (compile-capture-module x)
  606. (let ((x (compile x)))
  607. (lambda (env)
  608. (x (current-module)))))
  609. (define (compile-call-with-prompt tag thunk handler)
  610. (let ((tag (compile tag))
  611. (thunk (compile thunk))
  612. (handler (compile handler)))
  613. (lambda (env)
  614. (call-with-prompt (tag env) (thunk env) (handler env)))))
  615. (define (compile-call/cc proc)
  616. (let ((proc (compile proc)))
  617. (lambda (env)
  618. (call/cc (proc env)))))
  619. (define (compile exp)
  620. (match exp
  621. ((,(typecode lexical-ref) depth . width)
  622. (compile-lexical-ref depth width))
  623. ((,(typecode call) f . args)
  624. (compile-call f args))
  625. ((,(typecode box-ref) . box)
  626. (compile-box-ref box))
  627. ((,(typecode resolve) . loc)
  628. (lazy (env) (compile-resolve env loc)))
  629. ((,(typecode if) test consequent . alternate)
  630. (compile-if test consequent alternate))
  631. ((,(typecode quote) . x)
  632. (compile-quote x))
  633. ((,(typecode let) inits . body)
  634. (compile-let inits body))
  635. ((,(typecode lambda) body meta nreq . tail)
  636. (compile-lambda body meta nreq tail))
  637. ((,(typecode capture-env) locs . body)
  638. (compile-capture-env locs body))
  639. ((,(typecode seq) head . tail)
  640. (compile-seq head tail))
  641. ((,(typecode box-set!) box . val)
  642. (compile-box-set! box val))
  643. ((,(typecode lexical-set!) (depth . width) . x)
  644. (compile-lexical-set! depth width x))
  645. ((,(typecode call-with-values) producer . consumer)
  646. (compile-call-with-values producer consumer))
  647. ((,(typecode apply) f args)
  648. (compile-apply f args))
  649. ((,(typecode capture-module) . x)
  650. (compile-capture-module x))
  651. ((,(typecode call-with-prompt) tag thunk . handler)
  652. (compile-call-with-prompt tag thunk handler))
  653. ((,(typecode call/cc) . proc)
  654. (compile-call/cc proc))))
  655. (let ((eval (compile
  656. (memoize-expression
  657. (if (macroexpanded? exp)
  658. exp
  659. ((module-transformer (current-module)) exp)))))
  660. (env #f))
  661. (eval env)))