eval.scm 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. ;;; -*- mode: scheme; coding: utf-8; -*-
  2. ;;;; Copyright (C) 2009-2015, 2018, 2019 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 (annotate src proc)
  97. (set-procedure-property! proc 'source-override src)
  98. proc)
  99. (define-syntax-rule (lambda@ src formals body bodies ...)
  100. (annotate src (lambda formals body bodies ...)))
  101. (define-syntax-rule (lazy src (arg ...) exp)
  102. (letrec ((proc (lambda (arg ...)
  103. (set! proc exp)
  104. (proc arg ...))))
  105. (lambda@ src (arg ...)
  106. (proc arg ...))))
  107. (define (compile-lexical-ref src depth width)
  108. (case depth
  109. ((0) (lambda@ src (env) (env-ref env 0 width)))
  110. ((1) (lambda@ src (env) (env-ref env 1 width)))
  111. ((2) (lambda@ src (env) (env-ref env 2 width)))
  112. (else (lambda@ src (env) (env-ref env depth width)))))
  113. (define (primitive=? name loc module var)
  114. "Return true if VAR is the same as the primitive bound to NAME."
  115. (match loc
  116. ((mode . loc)
  117. (and (match loc
  118. ((mod name* . public?) (eq? name* name))
  119. (_ (eq? loc name)))
  120. ;; `module' can be #f if the module system was not yet
  121. ;; booted when the environment was captured.
  122. (or (not module)
  123. (eq? var (module-local-variable the-root-module name)))))))
  124. (define (compile-top-call src cenv loc args)
  125. (let* ((module (env-toplevel cenv))
  126. (var (%resolve-variable loc module)))
  127. (define-syntax-rule (maybe-primcall (prim ...) arg ...)
  128. (let ((arg (compile arg))
  129. ...)
  130. (cond
  131. ((primitive=? 'prim loc module var)
  132. (lambda@ src (env) (prim (arg env) ...)))
  133. ...
  134. (else (lambda@ src (env) ((variable-ref var) (arg env) ...))))))
  135. (match args
  136. (()
  137. (lambda@ src (env) ((variable-ref var))))
  138. ((a)
  139. (maybe-primcall (1+ 1- car cdr lognot vector-length
  140. variable-ref string-length struct-vtable)
  141. a))
  142. ((a b)
  143. (maybe-primcall (+ - * / ash logand logior logxor
  144. cons vector-ref struct-ref variable-set!)
  145. a b))
  146. ((a b c)
  147. (maybe-primcall (vector-set! struct-set!) a b c))
  148. ((a b c . args)
  149. (let ((a (compile a))
  150. (b (compile b))
  151. (c (compile c))
  152. (args (let lp ((args args))
  153. (if (null? args)
  154. '()
  155. (cons (compile (car args)) (lp (cdr args)))))))
  156. (lambda@ src (env)
  157. (apply (variable-ref var) (a env) (b env) (c env)
  158. (let lp ((args args))
  159. (if (null? args)
  160. '()
  161. (cons ((car args) env) (lp (cdr args))))))))))))
  162. (define (compile-call src f args)
  163. (match f
  164. ((,(typecode box-ref) _ . (,(typecode resolve) _ . loc))
  165. (lazy src (env) (compile-top-call src env loc args)))
  166. (_
  167. (match args
  168. (()
  169. (let ((f (compile f)))
  170. (lambda@ src (env) ((f env)))))
  171. ((a)
  172. (let ((f (compile f))
  173. (a (compile a)))
  174. (lambda@ src (env) ((f env) (a env)))))
  175. ((a b)
  176. (let ((f (compile f))
  177. (a (compile a))
  178. (b (compile b)))
  179. (lambda@ src (env) ((f env) (a env) (b env)))))
  180. ((a b c)
  181. (let ((f (compile f))
  182. (a (compile a))
  183. (b (compile b))
  184. (c (compile c)))
  185. (lambda@ src (env) ((f env) (a env) (b env) (c env)))))
  186. ((a b c . args)
  187. (let ((f (compile f))
  188. (a (compile a))
  189. (b (compile b))
  190. (c (compile c))
  191. (args (let lp ((args args))
  192. (if (null? args)
  193. '()
  194. (cons (compile (car args)) (lp (cdr args)))))))
  195. (lambda@ src (env)
  196. (apply (f env) (a env) (b env) (c env)
  197. (let lp ((args args))
  198. (if (null? args)
  199. '()
  200. (cons ((car args) env) (lp (cdr args)))))))))))))
  201. (define (compile-box-ref src box)
  202. (match box
  203. ((,(typecode resolve) _ . loc)
  204. (lazy src (cenv)
  205. (let ((var (%resolve-variable loc (env-toplevel cenv))))
  206. (lambda@ src (env) (variable-ref var)))))
  207. ((,(typecode lexical-ref) _ depth . width)
  208. (lambda@ src (env)
  209. (variable-ref (env-ref env depth width))))
  210. (_
  211. (let ((box (compile box)))
  212. (lambda@ src (env)
  213. (variable-ref (box env)))))))
  214. (define (compile-resolve src cenv loc)
  215. (let ((var (%resolve-variable loc (env-toplevel cenv))))
  216. (lambda@ src (env) var)))
  217. (define (compile-top-branch src cenv loc args consequent alternate)
  218. (let* ((module (env-toplevel cenv))
  219. (var (%resolve-variable loc module))
  220. (consequent (compile consequent))
  221. (alternate (compile alternate)))
  222. (define (generic-top-branch)
  223. (let ((test (compile-top-call src cenv loc args)))
  224. (lambda@ src (env)
  225. (if (test env) (consequent env) (alternate env)))))
  226. (define-syntax-rule (maybe-primcall (prim ...) arg ...)
  227. (cond
  228. ((primitive=? 'prim loc module var)
  229. (let ((arg (compile arg))
  230. ...)
  231. (lambda@ src (env)
  232. (if (prim (arg env) ...)
  233. (consequent env)
  234. (alternate env)))))
  235. ...
  236. (else (generic-top-branch))))
  237. (match args
  238. ((a)
  239. (maybe-primcall (null? nil? pair? struct? string? vector? symbol?
  240. keyword? variable? bitvector? char? zero? not)
  241. a))
  242. ((a b)
  243. (maybe-primcall (eq? eqv? equal? = < > <= >= logtest logbit?)
  244. a b))
  245. (_
  246. (generic-top-branch)))))
  247. (define (compile-if src test consequent alternate)
  248. (match test
  249. ((,(typecode call) _
  250. (,(typecode box-ref) _ . (,(typecode resolve) _ . loc))
  251. . args)
  252. (lazy src (env) (compile-top-branch src env loc args consequent alternate)))
  253. (_
  254. (let ((test (compile test))
  255. (consequent (compile consequent))
  256. (alternate (compile alternate)))
  257. (lambda@ src (env)
  258. (if (test env) (consequent env) (alternate env)))))))
  259. (define (compile-quote src x)
  260. (lambda@ src (env) x))
  261. (define (compile-let src inits body)
  262. (let ((body (compile body))
  263. (width (vector-length inits)))
  264. (case width
  265. ((0) (lambda@ src (env)
  266. (body (make-env* env))))
  267. ((1)
  268. (let ((a (compile (vector-ref inits 0))))
  269. (lambda@ src (env)
  270. (body (make-env* env (a env))))))
  271. ((2)
  272. (let ((a (compile (vector-ref inits 0)))
  273. (b (compile (vector-ref inits 1))))
  274. (lambda@ src (env)
  275. (body (make-env* env (a env) (b env))))))
  276. ((3)
  277. (let ((a (compile (vector-ref inits 0)))
  278. (b (compile (vector-ref inits 1)))
  279. (c (compile (vector-ref inits 2))))
  280. (lambda@ src (env)
  281. (body (make-env* env (a env) (b env) (c env))))))
  282. ((4)
  283. (let ((a (compile (vector-ref inits 0)))
  284. (b (compile (vector-ref inits 1)))
  285. (c (compile (vector-ref inits 2)))
  286. (d (compile (vector-ref inits 3))))
  287. (lambda@ src (env)
  288. (body (make-env* env (a env) (b env) (c env) (d env))))))
  289. (else
  290. (let lp ((n width)
  291. (k (lambda@ src (env)
  292. (make-env width #f env))))
  293. (if (zero? n)
  294. (lambda@ src (env)
  295. (body (k env)))
  296. (lp (1- n)
  297. (let ((init (compile (vector-ref inits (1- n)))))
  298. (lambda@ src (env)
  299. (let* ((x (init env))
  300. (new-env (k env)))
  301. (env-set! new-env 0 (1- n) x)
  302. new-env))))))))))
  303. (define (compile-fixed-lambda src body nreq)
  304. (case nreq
  305. ((0) (lambda@ src (env)
  306. (lambda@ src ()
  307. (body (make-env* env)))))
  308. ((1) (lambda@ src (env)
  309. (lambda@ src (a)
  310. (body (make-env* env a)))))
  311. ((2) (lambda@ src (env)
  312. (lambda@ src (a b)
  313. (body (make-env* env a b)))))
  314. ((3) (lambda@ src (env)
  315. (lambda@ src (a b c)
  316. (body (make-env* env a b c)))))
  317. ((4) (lambda@ src (env)
  318. (lambda@ src (a b c d)
  319. (body (make-env* env a b c d)))))
  320. ((5) (lambda@ src (env)
  321. (lambda@ src (a b c d e)
  322. (body (make-env* env a b c d e)))))
  323. ((6) (lambda@ src (env)
  324. (lambda@ src (a b c d e f)
  325. (body (make-env* env a b c d e f)))))
  326. ((7) (lambda@ src (env)
  327. (lambda@ src (a b c d e f g)
  328. (body (make-env* env a b c d e f g)))))
  329. (else
  330. (lambda@ src (env)
  331. (lambda@ src (a b c d e f g . more)
  332. (let ((env (make-env nreq #f env)))
  333. (env-set! env 0 0 a)
  334. (env-set! env 0 1 b)
  335. (env-set! env 0 2 c)
  336. (env-set! env 0 3 d)
  337. (env-set! env 0 4 e)
  338. (env-set! env 0 5 f)
  339. (env-set! env 0 6 g)
  340. (let lp ((n 7) (args more))
  341. (cond
  342. ((= n nreq)
  343. (unless (null? args)
  344. (scm-error 'wrong-number-of-args
  345. "eval" "Wrong number of arguments"
  346. '() #f))
  347. (body env))
  348. ((null? args)
  349. (scm-error 'wrong-number-of-args
  350. "eval" "Wrong number of arguments"
  351. '() #f))
  352. (else
  353. (env-set! env 0 n (car args))
  354. (lp (1+ n) (cdr args)))))))))))
  355. (define (compile-rest-lambda src body nreq rest?)
  356. (case nreq
  357. ((0) (lambda@ src (env)
  358. (lambda@ src rest
  359. (body (make-env* env rest)))))
  360. ((1) (lambda@ src (env)
  361. (lambda@ src (a . rest)
  362. (body (make-env* env a rest)))))
  363. ((2) (lambda@ src (env)
  364. (lambda@ src (a b . rest)
  365. (body (make-env* env a b rest)))))
  366. ((3) (lambda@ src (env)
  367. (lambda@ src (a b c . rest)
  368. (body (make-env* env a b c rest)))))
  369. (else
  370. (lambda@ src (env)
  371. (lambda@ src (a b c . more)
  372. (let ((env (make-env (1+ nreq) #f env)))
  373. (env-set! env 0 0 a)
  374. (env-set! env 0 1 b)
  375. (env-set! env 0 2 c)
  376. (let lp ((n 3) (args more))
  377. (cond
  378. ((= n nreq)
  379. (env-set! env 0 n args)
  380. (body env))
  381. ((null? args)
  382. (scm-error 'wrong-number-of-args
  383. "eval" "Wrong number of arguments"
  384. '() #f))
  385. (else
  386. (env-set! env 0 n (car args))
  387. (lp (1+ n) (cdr args)))))))))))
  388. (define (compile-opt-lambda src body nreq rest? nopt ninits unbound make-alt)
  389. (lambda@ src (env)
  390. (define alt (and make-alt (make-alt env)))
  391. (lambda@ src args
  392. (let ((nargs (length args)))
  393. (cond
  394. ((or (< nargs nreq) (and (not rest?) (> nargs (+ nreq nopt))))
  395. (if alt
  396. (apply alt args)
  397. ((scm-error 'wrong-number-of-args
  398. "eval" "Wrong number of arguments"
  399. '() #f))))
  400. (else
  401. (let* ((nvals (+ nreq (if rest? 1 0) ninits))
  402. (env (make-env nvals unbound env)))
  403. (define (bind-req args)
  404. (let lp ((i 0) (args args))
  405. (cond
  406. ((< i nreq)
  407. ;; Bind required arguments.
  408. (env-set! env 0 i (car args))
  409. (lp (1+ i) (cdr args)))
  410. (else
  411. (bind-opt args)))))
  412. (define (bind-opt args)
  413. (let lp ((i nreq) (args args))
  414. (cond
  415. ((and (< i (+ nreq nopt)) (< i nargs))
  416. (env-set! env 0 i (car args))
  417. (lp (1+ i) (cdr args)))
  418. (else
  419. (bind-rest args)))))
  420. (define (bind-rest args)
  421. (when rest?
  422. (env-set! env 0 (+ nreq nopt) args))
  423. (body env))
  424. (bind-req args))))))))
  425. (define (compile-kw-lambda src body nreq rest? nopt kw ninits unbound make-alt)
  426. (define allow-other-keys? (car kw))
  427. (define keywords (cdr kw))
  428. (lambda@ src (env)
  429. (define alt (and make-alt (make-alt env)))
  430. (lambda@ src args
  431. (define (npositional args)
  432. (let lp ((n 0) (args args))
  433. (if (or (null? args)
  434. (and (>= n nreq) (keyword? (car args))))
  435. n
  436. (lp (1+ n) (cdr args)))))
  437. (let ((nargs (length args)))
  438. (cond
  439. ((or (< nargs nreq)
  440. (and alt (not rest?) (> (npositional args) (+ nreq nopt))))
  441. (if alt
  442. (apply alt args)
  443. ((scm-error 'wrong-number-of-args
  444. "eval" "Wrong number of arguments"
  445. '() #f))))
  446. (else
  447. (let* ((nvals (+ nreq (if rest? 1 0) ninits))
  448. (env (make-env nvals unbound env)))
  449. (define (bind-req args)
  450. (let lp ((i 0) (args args))
  451. (cond
  452. ((< i nreq)
  453. ;; Bind required arguments.
  454. (env-set! env 0 i (car args))
  455. (lp (1+ i) (cdr args)))
  456. (else
  457. (bind-opt args)))))
  458. (define (bind-opt args)
  459. (let lp ((i nreq) (args args))
  460. (cond
  461. ((and (< i (+ nreq nopt)) (< i nargs)
  462. (not (keyword? (car args))))
  463. (env-set! env 0 i (car args))
  464. (lp (1+ i) (cdr args)))
  465. (else
  466. (bind-rest args)))))
  467. (define (bind-rest args)
  468. (when rest?
  469. (env-set! env 0 (+ nreq nopt) args))
  470. (bind-kw args))
  471. (define (bind-kw args)
  472. (let lp ((args args))
  473. (cond
  474. ((pair? args)
  475. (cond
  476. ((keyword? (car args))
  477. (let ((k (car args))
  478. (args (cdr args)))
  479. (cond
  480. ((assq k keywords)
  481. => (lambda (kw-pair)
  482. ;; Found a known keyword; set its value.
  483. (if (pair? args)
  484. (let ((v (car args))
  485. (args (cdr args)))
  486. (env-set! env 0 (cdr kw-pair) v)
  487. (lp args))
  488. ((scm-error 'keyword-argument-error
  489. "eval"
  490. "Keyword argument has no value"
  491. '() (list k))))))
  492. ;; Otherwise unknown keyword.
  493. (allow-other-keys?
  494. (lp (if (pair? args) (cdr args) args)))
  495. (else
  496. ((scm-error 'keyword-argument-error
  497. "eval" "Unrecognized keyword"
  498. '() (list k)))))))
  499. (rest?
  500. ;; Be lenient parsing rest args.
  501. (lp (cdr args)))
  502. (else
  503. ((scm-error 'keyword-argument-error
  504. "eval" "Invalid keyword"
  505. '() (list (car args)))))))
  506. (else
  507. (body env)))))
  508. (bind-req args))))))))
  509. (define (compute-arity alt nreq rest? nopt kw)
  510. (let lp ((alt alt) (nreq nreq) (nopt nopt) (rest? rest?))
  511. (if (not alt)
  512. (let ((arglist (list nreq
  513. nopt
  514. (if kw (cdr kw) '())
  515. (and kw (car kw))
  516. (and rest? '_))))
  517. (values arglist nreq nopt rest?))
  518. (let* ((spec (cddr alt))
  519. (nreq* (car spec))
  520. (rest?* (if (null? (cdr spec)) #f (cadr spec)))
  521. (tail (and (pair? (cdr spec)) (pair? (cddr spec)) (cddr spec)))
  522. (nopt* (if tail (car tail) 0))
  523. (alt* (and tail (car (cddddr tail)))))
  524. (if (or (< nreq* nreq)
  525. (and (= nreq* nreq)
  526. (if rest?
  527. (and rest?* (> nopt* nopt))
  528. (or rest?* (> nopt* nopt)))))
  529. (lp alt* nreq* nopt* rest?*)
  530. (lp alt* nreq nopt rest?))))))
  531. (define (compile-general-lambda src body nreq rest? nopt kw ninits unbound alt)
  532. (call-with-values
  533. (lambda ()
  534. (compute-arity alt nreq rest? nopt kw))
  535. (lambda (arglist min-nreq min-nopt min-rest?)
  536. (define make-alt
  537. (match alt
  538. (#f #f)
  539. ((body meta nreq . tail)
  540. (compile-lambda src body meta nreq tail))))
  541. (define make-closure
  542. (if kw
  543. (compile-kw-lambda src body nreq rest? nopt kw ninits unbound make-alt)
  544. (compile-opt-lambda src body nreq rest? nopt ninits unbound make-alt)))
  545. (lambda@ src (env)
  546. (let ((proc (make-closure env)))
  547. (set-procedure-property! proc 'arglist arglist)
  548. (set-procedure-minimum-arity! proc min-nreq min-nopt min-rest?)
  549. proc)))))
  550. (define (compile-lambda src body meta nreq tail)
  551. (define (set-procedure-meta meta proc)
  552. (match meta
  553. (() proc)
  554. (((prop . val) . meta)
  555. (set-procedure-meta meta
  556. (lambda@ src (env)
  557. (let ((proc (proc env)))
  558. (set-procedure-property! proc prop val)
  559. proc))))))
  560. (let ((body (lazy src (env) (compile body))))
  561. (set-procedure-meta
  562. meta
  563. (match tail
  564. (() (compile-fixed-lambda src body nreq))
  565. ((rest? . tail)
  566. (match tail
  567. (() (compile-rest-lambda src body nreq rest?))
  568. ((nopt kw ninits unbound alt)
  569. (compile-general-lambda src body nreq rest? nopt kw
  570. ninits unbound alt))))))))
  571. (define (compile-capture-env src locs body)
  572. (let ((body (compile body)))
  573. (lambda@ src (env)
  574. (let* ((len (vector-length locs))
  575. (new-env (make-env len #f (env-toplevel env))))
  576. (let lp ((n 0))
  577. (when (< n len)
  578. (match (vector-ref locs n)
  579. ((depth . width)
  580. (env-set! new-env 0 n (env-ref env depth width))))
  581. (lp (1+ n))))
  582. (body new-env)))))
  583. (define (compile-seq src head tail)
  584. (let ((head (compile head))
  585. (tail (compile tail)))
  586. (lambda@ src (env)
  587. (head env)
  588. (tail env))))
  589. (define (compile-box-set! src box val)
  590. (let ((box (compile box))
  591. (val (compile val)))
  592. (lambda@ src (env)
  593. (let ((val (val env)))
  594. (variable-set! (box env) val)))))
  595. (define (compile-lexical-set! src depth width x)
  596. (let ((x (compile x)))
  597. (lambda@ src (env)
  598. (env-set! env depth width (x env)))))
  599. (define (compile-call-with-values src producer consumer)
  600. (let ((producer (compile producer))
  601. (consumer (compile consumer)))
  602. (lambda@ src (env)
  603. (call-with-values (producer env)
  604. (consumer env)))))
  605. (define (compile-apply src f args)
  606. (let ((f (compile f))
  607. (args (compile args)))
  608. (lambda@ src (env)
  609. (apply (f env) (args env)))))
  610. (define (compile-capture-module src x)
  611. (let ((x (compile x)))
  612. (lambda@ src (env)
  613. (x (current-module)))))
  614. (define (compile-call-with-prompt src tag thunk handler)
  615. (let ((tag (compile tag))
  616. (thunk (compile thunk))
  617. (handler (compile handler)))
  618. (lambda@ src (env)
  619. (call-with-prompt (tag env) (thunk env) (handler env)))))
  620. (define (compile-call/cc src proc)
  621. (let ((proc (compile proc)))
  622. (lambda@ src (env)
  623. (call/cc (proc env)))))
  624. (define (compile exp)
  625. (match exp
  626. ((,(typecode lexical-ref) src depth . width)
  627. (compile-lexical-ref src depth width))
  628. ((,(typecode call) src f . args)
  629. (compile-call src f args))
  630. ((,(typecode box-ref) src . box)
  631. (compile-box-ref src box))
  632. ((,(typecode resolve) src . loc)
  633. (lazy src (env) (compile-resolve src env loc)))
  634. ((,(typecode if) src test consequent . alternate)
  635. (compile-if src test consequent alternate))
  636. ((,(typecode quote) src . x)
  637. (compile-quote src x))
  638. ((,(typecode let) src inits . body)
  639. (compile-let src inits body))
  640. ((,(typecode lambda) src body meta nreq . tail)
  641. (compile-lambda src body meta nreq tail))
  642. ((,(typecode capture-env) src locs . body)
  643. (compile-capture-env src locs body))
  644. ((,(typecode seq) src head . tail)
  645. (compile-seq src head tail))
  646. ((,(typecode box-set!) src box . val)
  647. (compile-box-set! src box val))
  648. ((,(typecode lexical-set!) src (depth . width) . x)
  649. (compile-lexical-set! src depth width x))
  650. ((,(typecode call-with-values) src producer . consumer)
  651. (compile-call-with-values src producer consumer))
  652. ((,(typecode apply) src f args)
  653. (compile-apply src f args))
  654. ((,(typecode capture-module) src . x)
  655. (compile-capture-module src x))
  656. ((,(typecode call-with-prompt) src tag thunk . handler)
  657. (compile-call-with-prompt src tag thunk handler))
  658. ((,(typecode call/cc) src . proc)
  659. (compile-call/cc src proc))))
  660. (let ((eval (compile
  661. (memoize-expression
  662. (if (macroexpanded? exp)
  663. exp
  664. ((module-transformer (current-module)) exp)))))
  665. (env #f))
  666. (eval env)))
  667. ;;; Local Variables:
  668. ;;; eval: (put 'lambda@ 'scheme-indent-function 2)
  669. ;;; End: