tree-il.scm 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. ;;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
  2. ;;;;
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;;;
  17. (define-module (language tree-il)
  18. #:use-module (srfi srfi-1)
  19. #:use-module (srfi srfi-11)
  20. #:use-module (system base pmatch)
  21. #:use-module (system base syntax)
  22. #:export (tree-il-src
  23. <void> void? make-void void-src
  24. <const> const? make-const const-src const-exp
  25. <primitive-ref> primitive-ref? make-primitive-ref primitive-ref-src primitive-ref-name
  26. <lexical-ref> lexical-ref? make-lexical-ref lexical-ref-src lexical-ref-name lexical-ref-gensym
  27. <lexical-set> lexical-set? make-lexical-set lexical-set-src lexical-set-name lexical-set-gensym lexical-set-exp
  28. <module-ref> module-ref? make-module-ref module-ref-src module-ref-mod module-ref-name module-ref-public?
  29. <module-set> module-set? make-module-set module-set-src module-set-mod module-set-name module-set-public? module-set-exp
  30. <toplevel-ref> toplevel-ref? make-toplevel-ref toplevel-ref-src toplevel-ref-name
  31. <toplevel-set> toplevel-set? make-toplevel-set toplevel-set-src toplevel-set-name toplevel-set-exp
  32. <toplevel-define> toplevel-define? make-toplevel-define toplevel-define-src toplevel-define-name toplevel-define-exp
  33. <conditional> conditional? make-conditional conditional-src conditional-test conditional-consequent conditional-alternate
  34. <application> application? make-application application-src application-proc application-args
  35. <sequence> sequence? make-sequence sequence-src sequence-exps
  36. <lambda> lambda? make-lambda lambda-src lambda-meta lambda-body
  37. <lambda-case> lambda-case? make-lambda-case lambda-case-src
  38. lambda-case-req lambda-case-opt lambda-case-rest lambda-case-kw
  39. lambda-case-inits lambda-case-gensyms
  40. lambda-case-body lambda-case-alternate
  41. <let> let? make-let let-src let-names let-gensyms let-vals let-body
  42. <letrec> letrec? make-letrec letrec-src letrec-in-order? letrec-names letrec-gensyms letrec-vals letrec-body
  43. <fix> fix? make-fix fix-src fix-names fix-gensyms fix-vals fix-body
  44. <let-values> let-values? make-let-values let-values-src let-values-exp let-values-body
  45. <dynwind> dynwind? make-dynwind dynwind-src dynwind-winder dynwind-body dynwind-unwinder
  46. <dynlet> dynlet? make-dynlet dynlet-src dynlet-fluids dynlet-vals dynlet-body
  47. <dynref> dynref? make-dynref dynref-src dynref-fluid
  48. <dynset> dynset? make-dynset dynset-src dynset-fluid dynset-exp
  49. <prompt> prompt? make-prompt prompt-src prompt-tag prompt-body prompt-handler
  50. <abort> abort? make-abort abort-src abort-tag abort-args abort-tail
  51. parse-tree-il
  52. unparse-tree-il
  53. tree-il->scheme
  54. tree-il-fold
  55. make-tree-il-folder
  56. post-order!
  57. pre-order!))
  58. (define (print-tree-il exp port)
  59. (format port "#<tree-il ~S>" (unparse-tree-il exp)))
  60. (define-syntax borrow-core-vtables
  61. (lambda (x)
  62. (syntax-case x ()
  63. ((_)
  64. (let lp ((n 0) (out '()))
  65. (if (< n (vector-length %expanded-vtables))
  66. (lp (1+ n)
  67. (let* ((vtable (vector-ref %expanded-vtables n))
  68. (stem (struct-ref vtable (+ vtable-offset-user 0)))
  69. (fields (struct-ref vtable (+ vtable-offset-user 2)))
  70. (sfields (map
  71. (lambda (f) (datum->syntax x f))
  72. fields))
  73. (type (datum->syntax x (symbol-append '< stem '>)))
  74. (ctor (datum->syntax x (symbol-append 'make- stem)))
  75. (pred (datum->syntax x (symbol-append stem '?))))
  76. (let lp ((n 0) (fields fields)
  77. (out (cons*
  78. #`(define (#,ctor #,@sfields)
  79. (make-struct #,type 0 #,@sfields))
  80. #`(define (#,pred x)
  81. (and (struct? x)
  82. (eq? (struct-vtable x) #,type)))
  83. #`(struct-set! #,type vtable-index-printer
  84. print-tree-il)
  85. #`(define #,type
  86. (vector-ref %expanded-vtables #,n))
  87. out)))
  88. (if (null? fields)
  89. out
  90. (lp (1+ n)
  91. (cdr fields)
  92. (let ((acc (datum->syntax
  93. x (symbol-append stem '- (car fields)))))
  94. (cons #`(define #,acc
  95. (make-procedure-with-setter
  96. (lambda (x) (struct-ref x #,n))
  97. (lambda (x v) (struct-set! x #,n v))))
  98. out)))))))
  99. #`(begin #,@(reverse out))))))))
  100. (borrow-core-vtables)
  101. ;; (<void>)
  102. ;; (<const> exp)
  103. ;; (<primitive-ref> name)
  104. ;; (<lexical-ref> name gensym)
  105. ;; (<lexical-set> name gensym exp)
  106. ;; (<module-ref> mod name public?)
  107. ;; (<module-set> mod name public? exp)
  108. ;; (<toplevel-ref> name)
  109. ;; (<toplevel-set> name exp)
  110. ;; (<toplevel-define> name exp)
  111. ;; (<conditional> test consequent alternate)
  112. ;; (<application> proc args)
  113. ;; (<sequence> exps)
  114. ;; (<lambda> meta body)
  115. ;; (<lambda-case> req opt rest kw inits gensyms body alternate)
  116. ;; (<let> names gensyms vals body)
  117. ;; (<letrec> in-order? names gensyms vals body)
  118. ;; (<dynlet> fluids vals body)
  119. (define-type (<tree-il> #:common-slots (src) #:printer print-tree-il)
  120. (<fix> names gensyms vals body)
  121. (<let-values> exp body)
  122. (<dynwind> winder body unwinder)
  123. (<dynref> fluid)
  124. (<dynset> fluid exp)
  125. (<prompt> tag body handler)
  126. (<abort> tag args tail))
  127. (define (location x)
  128. (and (pair? x)
  129. (let ((props (source-properties x)))
  130. (and (pair? props) props))))
  131. (define (parse-tree-il exp)
  132. (let ((loc (location exp))
  133. (retrans (lambda (x) (parse-tree-il x))))
  134. (pmatch exp
  135. ((void)
  136. (make-void loc))
  137. ((apply ,proc . ,args)
  138. (make-application loc (retrans proc) (map retrans args)))
  139. ((if ,test ,consequent ,alternate)
  140. (make-conditional loc (retrans test) (retrans consequent) (retrans alternate)))
  141. ((primitive ,name) (guard (symbol? name))
  142. (make-primitive-ref loc name))
  143. ((lexical ,name) (guard (symbol? name))
  144. (make-lexical-ref loc name name))
  145. ((lexical ,name ,sym) (guard (symbol? name) (symbol? sym))
  146. (make-lexical-ref loc name sym))
  147. ((set! (lexical ,name) ,exp) (guard (symbol? name))
  148. (make-lexical-set loc name name (retrans exp)))
  149. ((set! (lexical ,name ,sym) ,exp) (guard (symbol? name) (symbol? sym))
  150. (make-lexical-set loc name sym (retrans exp)))
  151. ((@ ,mod ,name) (guard (and-map symbol? mod) (symbol? name))
  152. (make-module-ref loc mod name #t))
  153. ((set! (@ ,mod ,name) ,exp) (guard (and-map symbol? mod) (symbol? name))
  154. (make-module-set loc mod name #t (retrans exp)))
  155. ((@@ ,mod ,name) (guard (and-map symbol? mod) (symbol? name))
  156. (make-module-ref loc mod name #f))
  157. ((set! (@@ ,mod ,name) ,exp) (guard (and-map symbol? mod) (symbol? name))
  158. (make-module-set loc mod name #f (retrans exp)))
  159. ((toplevel ,name) (guard (symbol? name))
  160. (make-toplevel-ref loc name))
  161. ((set! (toplevel ,name) ,exp) (guard (symbol? name))
  162. (make-toplevel-set loc name (retrans exp)))
  163. ((define ,name ,exp) (guard (symbol? name))
  164. (make-toplevel-define loc name (retrans exp)))
  165. ((lambda ,meta ,body)
  166. (make-lambda loc meta (retrans body)))
  167. ((lambda-case ((,req ,opt ,rest ,kw ,inits ,gensyms) ,body) ,alternate)
  168. (make-lambda-case loc req opt rest kw
  169. (map retrans inits) gensyms
  170. (retrans body)
  171. (and=> alternate retrans)))
  172. ((lambda-case ((,req ,opt ,rest ,kw ,inits ,gensyms) ,body))
  173. (make-lambda-case loc req opt rest kw
  174. (map retrans inits) gensyms
  175. (retrans body)
  176. #f))
  177. ((const ,exp)
  178. (make-const loc exp))
  179. ((begin . ,exps)
  180. (make-sequence loc (map retrans exps)))
  181. ((let ,names ,gensyms ,vals ,body)
  182. (make-let loc names gensyms (map retrans vals) (retrans body)))
  183. ((letrec ,names ,gensyms ,vals ,body)
  184. (make-letrec loc #f names gensyms (map retrans vals) (retrans body)))
  185. ((letrec* ,names ,gensyms ,vals ,body)
  186. (make-letrec loc #t names gensyms (map retrans vals) (retrans body)))
  187. ((fix ,names ,gensyms ,vals ,body)
  188. (make-fix loc names gensyms (map retrans vals) (retrans body)))
  189. ((let-values ,exp ,body)
  190. (make-let-values loc (retrans exp) (retrans body)))
  191. ((dynwind ,winder ,body ,unwinder)
  192. (make-dynwind loc (retrans winder) (retrans body) (retrans unwinder)))
  193. ((dynlet ,fluids ,vals ,body)
  194. (make-dynlet loc (map retrans fluids) (map retrans vals) (retrans body)))
  195. ((dynref ,fluid)
  196. (make-dynref loc (retrans fluid)))
  197. ((dynset ,fluid ,exp)
  198. (make-dynset loc (retrans fluid) (retrans exp)))
  199. ((prompt ,tag ,body ,handler)
  200. (make-prompt loc (retrans tag) (retrans body) (retrans handler)))
  201. ((abort ,tag ,args ,tail)
  202. (make-abort loc (retrans tag) (map retrans args) (retrans tail)))
  203. (else
  204. (error "unrecognized tree-il" exp)))))
  205. (define (unparse-tree-il tree-il)
  206. (record-case tree-il
  207. ((<void>)
  208. '(void))
  209. ((<application> proc args)
  210. `(apply ,(unparse-tree-il proc) ,@(map unparse-tree-il args)))
  211. ((<conditional> test consequent alternate)
  212. `(if ,(unparse-tree-il test) ,(unparse-tree-il consequent) ,(unparse-tree-il alternate)))
  213. ((<primitive-ref> name)
  214. `(primitive ,name))
  215. ((<lexical-ref> name gensym)
  216. `(lexical ,name ,gensym))
  217. ((<lexical-set> name gensym exp)
  218. `(set! (lexical ,name ,gensym) ,(unparse-tree-il exp)))
  219. ((<module-ref> mod name public?)
  220. `(,(if public? '@ '@@) ,mod ,name))
  221. ((<module-set> mod name public? exp)
  222. `(set! (,(if public? '@ '@@) ,mod ,name) ,(unparse-tree-il exp)))
  223. ((<toplevel-ref> name)
  224. `(toplevel ,name))
  225. ((<toplevel-set> name exp)
  226. `(set! (toplevel ,name) ,(unparse-tree-il exp)))
  227. ((<toplevel-define> name exp)
  228. `(define ,name ,(unparse-tree-il exp)))
  229. ((<lambda> meta body)
  230. `(lambda ,meta ,(unparse-tree-il body)))
  231. ((<lambda-case> req opt rest kw inits gensyms body alternate)
  232. `(lambda-case ((,req ,opt ,rest ,kw ,(map unparse-tree-il inits) ,gensyms)
  233. ,(unparse-tree-il body))
  234. . ,(if alternate (list (unparse-tree-il alternate)) '())))
  235. ((<const> exp)
  236. `(const ,exp))
  237. ((<sequence> exps)
  238. `(begin ,@(map unparse-tree-il exps)))
  239. ((<let> names gensyms vals body)
  240. `(let ,names ,gensyms ,(map unparse-tree-il vals) ,(unparse-tree-il body)))
  241. ((<letrec> in-order? names gensyms vals body)
  242. `(,(if in-order? 'letrec* 'letrec) ,names ,gensyms
  243. ,(map unparse-tree-il vals) ,(unparse-tree-il body)))
  244. ((<fix> names gensyms vals body)
  245. `(fix ,names ,gensyms ,(map unparse-tree-il vals) ,(unparse-tree-il body)))
  246. ((<let-values> exp body)
  247. `(let-values ,(unparse-tree-il exp) ,(unparse-tree-il body)))
  248. ((<dynwind> body winder unwinder)
  249. `(dynwind ,(unparse-tree-il body)
  250. ,(unparse-tree-il winder) ,(unparse-tree-il unwinder)))
  251. ((<dynlet> fluids vals body)
  252. `(dynlet ,(map unparse-tree-il fluids) ,(map unparse-tree-il vals)
  253. ,(unparse-tree-il body)))
  254. ((<dynref> fluid)
  255. `(dynref ,(unparse-tree-il fluid)))
  256. ((<dynset> fluid exp)
  257. `(dynref ,(unparse-tree-il fluid) ,(unparse-tree-il exp)))
  258. ((<prompt> tag body handler)
  259. `(prompt ,(unparse-tree-il tag) ,(unparse-tree-il body) ,(unparse-tree-il handler)))
  260. ((<abort> tag args tail)
  261. `(abort ,(unparse-tree-il tag) ,(map unparse-tree-il args)
  262. ,(unparse-tree-il tail)))))
  263. (define (tree-il->scheme e)
  264. (record-case e
  265. ((<void>)
  266. '(if #f #f))
  267. ((<application> proc args)
  268. `(,(tree-il->scheme proc) ,@(map tree-il->scheme args)))
  269. ((<conditional> test consequent alternate)
  270. (if (void? alternate)
  271. `(if ,(tree-il->scheme test) ,(tree-il->scheme consequent))
  272. `(if ,(tree-il->scheme test) ,(tree-il->scheme consequent) ,(tree-il->scheme alternate))))
  273. ((<primitive-ref> name)
  274. name)
  275. ((<lexical-ref> gensym)
  276. gensym)
  277. ((<lexical-set> gensym exp)
  278. `(set! ,gensym ,(tree-il->scheme exp)))
  279. ((<module-ref> mod name public?)
  280. `(,(if public? '@ '@@) ,mod ,name))
  281. ((<module-set> mod name public? exp)
  282. `(set! (,(if public? '@ '@@) ,mod ,name) ,(tree-il->scheme exp)))
  283. ((<toplevel-ref> name)
  284. name)
  285. ((<toplevel-set> name exp)
  286. `(set! ,name ,(tree-il->scheme exp)))
  287. ((<toplevel-define> name exp)
  288. `(define ,name ,(tree-il->scheme exp)))
  289. ((<lambda> meta body)
  290. ;; fixme: put in docstring
  291. (tree-il->scheme body))
  292. ((<lambda-case> req opt rest kw inits gensyms body alternate)
  293. (cond
  294. ((and (not opt) (not kw) (not alternate))
  295. `(lambda ,(if rest (apply cons* gensyms) gensyms)
  296. ,(tree-il->scheme body)))
  297. ((and (not opt) (not kw))
  298. (let ((alt-expansion (tree-il->scheme alternate))
  299. (formals (if rest (apply cons* gensyms) gensyms)))
  300. (case (car alt-expansion)
  301. ((lambda)
  302. `(case-lambda (,formals ,(tree-il->scheme body))
  303. ,@(cdr alt-expansion)))
  304. ((lambda*)
  305. `(case-lambda* (,formals ,(tree-il->scheme body))
  306. ,(cdr alt-expansion)))
  307. ((case-lambda)
  308. `(case-lambda (,formals ,(tree-il->scheme body))
  309. ,@(cdr alt-expansion)))
  310. ((case-lambda*)
  311. `(case-lambda* (,formals ,(tree-il->scheme body))
  312. ,@(cdr alt-expansion))))))
  313. (else
  314. (let* ((alt-expansion (and alternate (tree-il->scheme alternate)))
  315. (nreq (length req))
  316. (nopt (if opt (length opt) 0))
  317. (restargs (if rest (list-ref gensyms (+ nreq nopt)) '()))
  318. (reqargs (list-head gensyms nreq))
  319. (optargs (if opt
  320. `(#:optional
  321. ,@(map list
  322. (list-head (list-tail gensyms nreq) nopt)
  323. (map tree-il->scheme
  324. (list-head inits nopt))))
  325. '()))
  326. (kwargs (if kw
  327. `(#:key
  328. ,@(map list
  329. (map caddr (cdr kw))
  330. (map tree-il->scheme
  331. (list-tail inits nopt))
  332. (map car (cdr kw)))
  333. ,@(if (car kw)
  334. '(#:allow-other-keys)
  335. '()))
  336. '()))
  337. (formals `(,@reqargs ,@optargs ,@kwargs . ,restargs)))
  338. (if (not alt-expansion)
  339. `(lambda* ,formals ,(tree-il->scheme body))
  340. (case (car alt-expansion)
  341. ((lambda lambda*)
  342. `(case-lambda* (,formals ,(tree-il->scheme body))
  343. ,(cdr alt-expansion)))
  344. ((case-lambda case-lambda*)
  345. `(case-lambda* (,formals ,(tree-il->scheme body))
  346. ,@(cdr alt-expansion)))))))))
  347. ((<const> exp)
  348. (if (and (self-evaluating? exp) (not (vector? exp)))
  349. exp
  350. (list 'quote exp)))
  351. ((<sequence> exps)
  352. `(begin ,@(map tree-il->scheme exps)))
  353. ((<let> gensyms vals body)
  354. `(let ,(map list gensyms (map tree-il->scheme vals)) ,(tree-il->scheme body)))
  355. ((<letrec> in-order? gensyms vals body)
  356. `(,(if in-order? 'letrec* 'letrec)
  357. ,(map list gensyms (map tree-il->scheme vals)) ,(tree-il->scheme body)))
  358. ((<fix> gensyms vals body)
  359. ;; not a typo, we really do translate back to letrec. use letrec* since it
  360. ;; doesn't matter, and the naive letrec* transformation does not require an
  361. ;; inner let.
  362. `(letrec* ,(map list gensyms (map tree-il->scheme vals)) ,(tree-il->scheme body)))
  363. ((<let-values> exp body)
  364. `(call-with-values (lambda () ,(tree-il->scheme exp))
  365. ,(tree-il->scheme (make-lambda #f '() body))))
  366. ((<dynwind> body winder unwinder)
  367. `(dynamic-wind ,(tree-il->scheme winder)
  368. (lambda () ,(tree-il->scheme body))
  369. ,(tree-il->scheme unwinder)))
  370. ((<dynlet> fluids vals body)
  371. `(with-fluids ,(map list
  372. (map tree-il->scheme fluids)
  373. (map tree-il->scheme vals))
  374. ,(tree-il->scheme body)))
  375. ((<dynref> fluid)
  376. `(fluid-ref ,(tree-il->scheme fluid)))
  377. ((<dynset> fluid exp)
  378. `(fluid-set! ,(tree-il->scheme fluid) ,(tree-il->scheme exp)))
  379. ((<prompt> tag body handler)
  380. `(call-with-prompt
  381. ,(tree-il->scheme tag)
  382. (lambda () ,(tree-il->scheme body))
  383. ,(tree-il->scheme handler)))
  384. ((<abort> tag args tail)
  385. `(apply abort ,(tree-il->scheme tag) ,@(map tree-il->scheme args)
  386. ,(tree-il->scheme tail)))))
  387. (define (tree-il-fold leaf down up seed tree)
  388. "Traverse TREE, calling LEAF on each leaf encountered, DOWN upon descent
  389. into a sub-tree, and UP when leaving a sub-tree. Each of these procedures is
  390. invoked as `(PROC TREE SEED)', where TREE is the sub-tree or leaf considered
  391. and SEED is the current result, intially seeded with SEED.
  392. This is an implementation of `foldts' as described by Andy Wingo in
  393. ``Applications of fold to XML transformation''."
  394. (let loop ((tree tree)
  395. (result seed))
  396. (if (or (null? tree) (pair? tree))
  397. (fold loop result tree)
  398. (record-case tree
  399. ((<lexical-set> exp)
  400. (up tree (loop exp (down tree result))))
  401. ((<module-set> exp)
  402. (up tree (loop exp (down tree result))))
  403. ((<toplevel-set> exp)
  404. (up tree (loop exp (down tree result))))
  405. ((<toplevel-define> exp)
  406. (up tree (loop exp (down tree result))))
  407. ((<conditional> test consequent alternate)
  408. (up tree (loop alternate
  409. (loop consequent
  410. (loop test (down tree result))))))
  411. ((<application> proc args)
  412. (up tree (loop (cons proc args) (down tree result))))
  413. ((<sequence> exps)
  414. (up tree (loop exps (down tree result))))
  415. ((<lambda> body)
  416. (up tree (loop body (down tree result))))
  417. ((<lambda-case> inits body alternate)
  418. (up tree (if alternate
  419. (loop alternate
  420. (loop body (loop inits (down tree result))))
  421. (loop body (loop inits (down tree result))))))
  422. ((<let> vals body)
  423. (up tree (loop body
  424. (loop vals
  425. (down tree result)))))
  426. ((<letrec> vals body)
  427. (up tree (loop body
  428. (loop vals
  429. (down tree result)))))
  430. ((<fix> vals body)
  431. (up tree (loop body
  432. (loop vals
  433. (down tree result)))))
  434. ((<let-values> exp body)
  435. (up tree (loop body (loop exp (down tree result)))))
  436. ((<dynwind> body winder unwinder)
  437. (up tree (loop unwinder
  438. (loop winder
  439. (loop body (down tree result))))))
  440. ((<dynlet> fluids vals body)
  441. (up tree (loop body
  442. (loop vals
  443. (loop fluids (down tree result))))))
  444. ((<dynref> fluid)
  445. (up tree (loop fluid (down tree result))))
  446. ((<dynset> fluid exp)
  447. (up tree (loop exp (loop fluid (down tree result)))))
  448. ((<prompt> tag body handler)
  449. (up tree
  450. (loop tag (loop body (loop handler
  451. (down tree result))))))
  452. ((<abort> tag args tail)
  453. (up tree (loop tail (loop args (loop tag (down tree result))))))
  454. (else
  455. (leaf tree result))))))
  456. (define-syntax make-tree-il-folder
  457. (syntax-rules ()
  458. ((_ seed ...)
  459. (lambda (tree down up seed ...)
  460. (define (fold-values proc exps seed ...)
  461. (if (null? exps)
  462. (values seed ...)
  463. (let-values (((seed ...) (proc (car exps) seed ...)))
  464. (fold-values proc (cdr exps) seed ...))))
  465. (let foldts ((tree tree) (seed seed) ...)
  466. (let*-values
  467. (((seed ...) (down tree seed ...))
  468. ((seed ...)
  469. (record-case tree
  470. ((<lexical-set> exp)
  471. (foldts exp seed ...))
  472. ((<module-set> exp)
  473. (foldts exp seed ...))
  474. ((<toplevel-set> exp)
  475. (foldts exp seed ...))
  476. ((<toplevel-define> exp)
  477. (foldts exp seed ...))
  478. ((<conditional> test consequent alternate)
  479. (let*-values (((seed ...) (foldts test seed ...))
  480. ((seed ...) (foldts consequent seed ...)))
  481. (foldts alternate seed ...)))
  482. ((<application> proc args)
  483. (let-values (((seed ...) (foldts proc seed ...)))
  484. (fold-values foldts args seed ...)))
  485. ((<sequence> exps)
  486. (fold-values foldts exps seed ...))
  487. ((<lambda> body)
  488. (foldts body seed ...))
  489. ((<lambda-case> inits body alternate)
  490. (let-values (((seed ...) (fold-values foldts inits seed ...)))
  491. (if alternate
  492. (let-values (((seed ...) (foldts body seed ...)))
  493. (foldts alternate seed ...))
  494. (foldts body seed ...))))
  495. ((<let> vals body)
  496. (let*-values (((seed ...) (fold-values foldts vals seed ...)))
  497. (foldts body seed ...)))
  498. ((<letrec> vals body)
  499. (let*-values (((seed ...) (fold-values foldts vals seed ...)))
  500. (foldts body seed ...)))
  501. ((<fix> vals body)
  502. (let*-values (((seed ...) (fold-values foldts vals seed ...)))
  503. (foldts body seed ...)))
  504. ((<let-values> exp body)
  505. (let*-values (((seed ...) (foldts exp seed ...)))
  506. (foldts body seed ...)))
  507. ((<dynwind> body winder unwinder)
  508. (let*-values (((seed ...) (foldts body seed ...))
  509. ((seed ...) (foldts winder seed ...)))
  510. (foldts unwinder seed ...)))
  511. ((<dynlet> fluids vals body)
  512. (let*-values (((seed ...) (fold-values foldts fluids seed ...))
  513. ((seed ...) (fold-values foldts vals seed ...)))
  514. (foldts body seed ...)))
  515. ((<dynref> fluid)
  516. (foldts fluid seed ...))
  517. ((<dynset> fluid exp)
  518. (let*-values (((seed ...) (foldts fluid seed ...)))
  519. (foldts exp seed ...)))
  520. ((<prompt> tag body handler)
  521. (let*-values (((seed ...) (foldts tag seed ...))
  522. ((seed ...) (foldts body seed ...)))
  523. (foldts handler seed ...)))
  524. ((<abort> tag args tail)
  525. (let*-values (((seed ...) (foldts tag seed ...))
  526. ((seed ...) (fold-values foldts args seed ...)))
  527. (foldts tail seed ...)))
  528. (else
  529. (values seed ...)))))
  530. (up tree seed ...)))))))
  531. (define (post-order! f x)
  532. (let lp ((x x))
  533. (record-case x
  534. ((<application> proc args)
  535. (set! (application-proc x) (lp proc))
  536. (set! (application-args x) (map lp args)))
  537. ((<conditional> test consequent alternate)
  538. (set! (conditional-test x) (lp test))
  539. (set! (conditional-consequent x) (lp consequent))
  540. (set! (conditional-alternate x) (lp alternate)))
  541. ((<lexical-set> name gensym exp)
  542. (set! (lexical-set-exp x) (lp exp)))
  543. ((<module-set> mod name public? exp)
  544. (set! (module-set-exp x) (lp exp)))
  545. ((<toplevel-set> name exp)
  546. (set! (toplevel-set-exp x) (lp exp)))
  547. ((<toplevel-define> name exp)
  548. (set! (toplevel-define-exp x) (lp exp)))
  549. ((<lambda> body)
  550. (set! (lambda-body x) (lp body)))
  551. ((<lambda-case> inits body alternate)
  552. (set! inits (map lp inits))
  553. (set! (lambda-case-body x) (lp body))
  554. (if alternate
  555. (set! (lambda-case-alternate x) (lp alternate))))
  556. ((<sequence> exps)
  557. (set! (sequence-exps x) (map lp exps)))
  558. ((<let> gensyms vals body)
  559. (set! (let-vals x) (map lp vals))
  560. (set! (let-body x) (lp body)))
  561. ((<letrec> gensyms vals body)
  562. (set! (letrec-vals x) (map lp vals))
  563. (set! (letrec-body x) (lp body)))
  564. ((<fix> gensyms vals body)
  565. (set! (fix-vals x) (map lp vals))
  566. (set! (fix-body x) (lp body)))
  567. ((<let-values> exp body)
  568. (set! (let-values-exp x) (lp exp))
  569. (set! (let-values-body x) (lp body)))
  570. ((<dynwind> body winder unwinder)
  571. (set! (dynwind-body x) (lp body))
  572. (set! (dynwind-winder x) (lp winder))
  573. (set! (dynwind-unwinder x) (lp unwinder)))
  574. ((<dynlet> fluids vals body)
  575. (set! (dynlet-fluids x) (map lp fluids))
  576. (set! (dynlet-vals x) (map lp vals))
  577. (set! (dynlet-body x) (lp body)))
  578. ((<dynref> fluid)
  579. (set! (dynref-fluid x) (lp fluid)))
  580. ((<dynset> fluid exp)
  581. (set! (dynset-fluid x) (lp fluid))
  582. (set! (dynset-exp x) (lp exp)))
  583. ((<prompt> tag body handler)
  584. (set! (prompt-tag x) (lp tag))
  585. (set! (prompt-body x) (lp body))
  586. (set! (prompt-handler x) (lp handler)))
  587. ((<abort> tag args tail)
  588. (set! (abort-tag x) (lp tag))
  589. (set! (abort-args x) (map lp args))
  590. (set! (abort-tail x) (lp tail)))
  591. (else #f))
  592. (or (f x) x)))
  593. (define (pre-order! f x)
  594. (let lp ((x x))
  595. (let ((x (or (f x) x)))
  596. (record-case x
  597. ((<application> proc args)
  598. (set! (application-proc x) (lp proc))
  599. (set! (application-args x) (map lp args)))
  600. ((<conditional> test consequent alternate)
  601. (set! (conditional-test x) (lp test))
  602. (set! (conditional-consequent x) (lp consequent))
  603. (set! (conditional-alternate x) (lp alternate)))
  604. ((<lexical-set> exp)
  605. (set! (lexical-set-exp x) (lp exp)))
  606. ((<module-set> exp)
  607. (set! (module-set-exp x) (lp exp)))
  608. ((<toplevel-set> exp)
  609. (set! (toplevel-set-exp x) (lp exp)))
  610. ((<toplevel-define> exp)
  611. (set! (toplevel-define-exp x) (lp exp)))
  612. ((<lambda> body)
  613. (set! (lambda-body x) (lp body)))
  614. ((<lambda-case> inits body alternate)
  615. (set! inits (map lp inits))
  616. (set! (lambda-case-body x) (lp body))
  617. (if alternate (set! (lambda-case-alternate x) (lp alternate))))
  618. ((<sequence> exps)
  619. (set! (sequence-exps x) (map lp exps)))
  620. ((<let> vals body)
  621. (set! (let-vals x) (map lp vals))
  622. (set! (let-body x) (lp body)))
  623. ((<letrec> vals body)
  624. (set! (letrec-vals x) (map lp vals))
  625. (set! (letrec-body x) (lp body)))
  626. ((<fix> vals body)
  627. (set! (fix-vals x) (map lp vals))
  628. (set! (fix-body x) (lp body)))
  629. ((<let-values> exp body)
  630. (set! (let-values-exp x) (lp exp))
  631. (set! (let-values-body x) (lp body)))
  632. ((<dynwind> body winder unwinder)
  633. (set! (dynwind-body x) (lp body))
  634. (set! (dynwind-winder x) (lp winder))
  635. (set! (dynwind-unwinder x) (lp unwinder)))
  636. ((<dynlet> fluids vals body)
  637. (set! (dynlet-fluids x) (map lp fluids))
  638. (set! (dynlet-vals x) (map lp vals))
  639. (set! (dynlet-body x) (lp body)))
  640. ((<dynref> fluid)
  641. (set! (dynref-fluid x) (lp fluid)))
  642. ((<dynset> fluid exp)
  643. (set! (dynset-fluid x) (lp fluid))
  644. (set! (dynset-exp x) (lp exp)))
  645. ((<prompt> tag body handler)
  646. (set! (prompt-tag x) (lp tag))
  647. (set! (prompt-body x) (lp body))
  648. (set! (prompt-handler x) (lp handler)))
  649. ((<abort> tag args tail)
  650. (set! (abort-tag x) (lp tag))
  651. (set! (abort-args x) (map lp args))
  652. (set! (abort-tail x) (lp tail)))
  653. (else #f))
  654. x)))