57.upstream.scm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. ;;; Copyright (C) André van Tonder (2004). All Rights Reserved.
  2. ;;; Permission is hereby granted, free of charge, to any person obtaining a copy
  3. ;;; of this software and associated documentation files (the "Software"), to
  4. ;;; deal in the Software without restriction, including without limitation the
  5. ;;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  6. ;;; sell copies of the Software, and to permit persons to whom the Software is
  7. ;;; furnished to do so, subject to the following conditions:
  8. ;;; The above copyright notice and this permission notice shall be included in
  9. ;;; all copies or substantial portions of the Software.
  10. ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. ;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. ;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. ;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  14. ;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  15. ;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  16. ;;; IN THE SOFTWARE.
  17. ;============================================================================================
  18. ; IMPLEMENTATION:
  19. ;
  20. ; Andre van Tonder, 2004.
  21. ;
  22. ;============================================================================================
  23. (define-syntax define-record-type
  24. (syntax-rules ()
  25. ((define-record-type . body)
  26. (parse-declaration #f . body))))
  27. (define-syntax define-record-scheme
  28. (syntax-rules ()
  29. ((define-record-scheme . body)
  30. (parse-declaration #t . body))))
  31. (define-syntax parse-declaration
  32. (syntax-rules ()
  33. ((parse-declaration is-scheme? (name super ...) constructor-clause predicate field-clause ...)
  34. (build-record 0 constructor-clause (super ...) (field-clause ...) name predicate is-scheme?))
  35. ((parse-declaration is-scheme? (name super ...) constructor-clause)
  36. (parse-declaration is-scheme? (name super ...) constructor-clause #f))
  37. ((parse-declaration is-scheme? (name super ...))
  38. (parse-declaration is-scheme? (name super ...) #f #f))
  39. ((parse-declaration is-scheme? name . rest)
  40. (parse-declaration is-scheme? (name) . rest))))
  41. (define-syntax record-update!
  42. (syntax-rules ()
  43. ((record-update! record name (label exp) ...)
  44. (meta
  45. `(let ((r record))
  46. ((meta ,(name ("setter") label)) r exp)
  47. ...
  48. r)))))
  49. (define-syntax record-update
  50. (syntax-rules ()
  51. ((record-update record name (label exp) ...)
  52. (name ("is-scheme?")
  53. (meta
  54. `(let ((new ((meta ,(name ("copier"))) record)))
  55. (record-update! new name (label exp) ...)))
  56. (record-compose (name record) (name (label exp) ...))))))
  57. (define-syntax record-compose
  58. (syntax-rules ()
  59. ((record-compose (export-name (label exp) ...))
  60. (export-name (label exp) ...))
  61. ((record-compose (import-name record) ... (export-name (label exp) ...))
  62. (help-compose 1 (import-name record) ... (export-name (label exp) ...)))))
  63. (define-syntax help-compose
  64. (syntax-rules ()
  65. ((help-compose 1 (import-name record) import ... (export-name (label exp) ...))
  66. (meta
  67. `(help-compose 2
  68. (meta ,(intersection
  69. (meta ,(export-name ("labels")))
  70. (meta ,(remove-from (meta ,(import-name ("labels")))
  71. (label ...)
  72. if-free=))
  73. if-free=))
  74. (import-name record)
  75. import ...
  76. (export-name (label exp) ...))))
  77. ((help-compose 2 (copy-label ...) (import-name record) import ... (export-name . bindings))
  78. (meta
  79. `(let ((r record))
  80. (record-compose import ...
  81. (export-name (copy-label ((meta ,(import-name ("getter") copy-label)) r))
  82. ...
  83. . bindings)))))))
  84. (define-syntax build-record
  85. (syntax-rules ()
  86. ((build-record 0 (constructor . pos-labels) . rest) ; extract positional labels from constructor clause
  87. (build-record 1 (constructor . pos-labels) pos-labels . rest)) ;
  88. ((build-record 0 constructor . rest) ;
  89. (build-record 1 (constructor . #f) () . rest)) ;
  90. ((build-record 1 constructor-clause (pos-label ...) (super ...)
  91. ((label . accessors) ...) . rest)
  92. (meta
  93. `(build-record 2
  94. constructor-clause
  95. (meta ,(union (meta ,(super ("labels"))) ; compute union of labels from supers,
  96. ... ; constructor clause and field clauses
  97. (pos-label ...)
  98. (label ...)
  99. top:if-free=))
  100. ((label . accessors) ...)
  101. (meta ,(union (meta ,(super ("supers"))) ; compute transitive union of supers
  102. ...
  103. top:if-free=))
  104. . rest)))
  105. ((build-record 2 (constructor . pos-labels) labels . rest) ; insert default constructor labels if not given
  106. (syntax-if pos-labels
  107. (build-record 3 (constructor . pos-labels) labels . rest)
  108. (build-record 3 (constructor . labels) labels . rest)))
  109. ((build-record 3 constructor-clause labels ((label . accessors) ...) . rest)
  110. (meta
  111. `(build-record 4
  112. (meta ,(remove-from labels ; separate the labels that do not appear in a
  113. (label ...) ; field clause for next step
  114. top:if-free=))
  115. ((label . accessors) ...)
  116. constructor-clause
  117. labels
  118. . rest)))
  119. ((build-record 4
  120. (undeclared-label ...)
  121. (field-clause ...)
  122. (constructor . pos-labels)
  123. labels
  124. supers
  125. name
  126. predicate
  127. is-scheme?)
  128. (meta
  129. `(build-record 5 ; generate identifiers for constructor, predicate
  130. is-scheme? ; getters and setters as needed
  131. name
  132. supers
  133. supers
  134. labels
  135. (meta ,(to-identifier constructor))
  136. (meta ,(add-temporaries pos-labels)) ; needed for constructor below
  137. (meta ,(to-identifier predicate))
  138. (meta ,(augment-field field-clause))
  139. ...
  140. (undeclared-label (meta ,(generate-identifier))
  141. (meta ,(generate-identifier)))
  142. ...)))
  143. ((build-record 5
  144. is-scheme?
  145. name
  146. (super ...)
  147. supers
  148. (label ...)
  149. constructor
  150. ((pos-label pos-temp) ...)
  151. predicate
  152. (field-label getter setter)
  153. ...)
  154. (begin
  155. (syntax-if is-scheme?
  156. (begin
  157. (define-generic (predicate x) (lambda (x) #f))
  158. (define-generic (getter x))
  159. ...
  160. (define-generic (setter x v))
  161. ...
  162. (define-generic (copy x)))
  163. (begin
  164. (srfi-9:define-record-type internal-name
  165. (maker field-label ...)
  166. predicate
  167. (field-label getter setter) ...)
  168. (define constructor
  169. (lambda (pos-temp ...)
  170. (populate 1 maker (field-label ...) (pos-label pos-temp) ...)))
  171. (extend-predicates supers predicate)
  172. (extend-accessors supers field-label predicate getter setter)
  173. ...
  174. (define (copy x)
  175. (maker (getter x) ...))
  176. (extend-copiers supers copy predicate)
  177. (define-method (show (r predicate))
  178. (list 'name
  179. (list 'field-label (getter r))
  180. ...))))
  181. (define-syntax name
  182. (syntax-rules (field-label ...)
  183. ((name ("is-scheme?") sk fk) (syntax-if is-scheme? sk fk))
  184. ((name ("predicate") k) (syntax-apply k predicate))
  185. ((name ("supers") k) (syntax-apply k (super ... name)))
  186. ((name ("labels") k) (syntax-apply k (label ...)))
  187. ((name ("pos-labels") k) (syntax-apply k (pos-label ...)))
  188. ((name ("getter") field-label k) (syntax-apply k getter))
  189. ...
  190. ((name ("getter") other k) (syntax-apply k #f))
  191. ((name ("setter") field-label k) (syntax-apply k setter))
  192. ...
  193. ((name ("setter") other k) (syntax-apply k #f))
  194. ((name ("copier") k) (syntax-apply k copy))
  195. ((name . bindings) (populate 1 maker (field-label ...) . bindings))))))))
  196. (define-syntax to-identifier
  197. (syntax-rules ()
  198. ((to-identifier #f k) (syntax-apply k generated-identifier))
  199. ((to-identifier id k) (syntax-apply k id))))
  200. (define-syntax augment-field
  201. (syntax-rules ()
  202. ((augment-field (label) k) (syntax-apply k (label generated-getter generated-setter)))
  203. ((augment-field (label getter) k) (meta `(label (meta ,(to-identifier getter)) generated-setter) k))
  204. ((augment-field (label getter setter) k) (meta `(label (meta ,(to-identifier getter))
  205. (meta ,(to-identifier setter))) k))))
  206. (define-syntax extend-predicates
  207. (syntax-rules ()
  208. ((extend-predicates (super ...) predicate)
  209. (begin
  210. (meta
  211. `(define-method (meta ,(super ("predicate")))
  212. (predicate)
  213. (x)
  214. any?))
  215. ...))))
  216. (define-syntax extend-copiers
  217. (syntax-rules ()
  218. ((extend-copiers (super ...) copy predicate)
  219. (begin
  220. (meta
  221. `(define-method (meta ,(super ("copier")))
  222. (predicate)
  223. (x)
  224. copy))
  225. ...))))
  226. (define-syntax extend-accessors
  227. (syntax-rules ()
  228. ((extend-accessors (super ...) label predicate selector modifier)
  229. (meta
  230. `(begin
  231. (syntax-if (meta ,(super ("getter") label))
  232. (define-method (meta ,(super ("getter") label))
  233. (predicate)
  234. (x)
  235. selector)
  236. (begin))
  237. ...
  238. (syntax-if (meta ,(super ("setter") label))
  239. (define-method (meta ,(super ("setter") label))
  240. (predicate any?)
  241. (x v)
  242. modifier)
  243. (begin))
  244. ...)))))
  245. (define-syntax populate
  246. (syntax-rules ()
  247. ((populate 1 maker labels . bindings)
  248. (meta
  249. `(populate 2 maker
  250. (meta ,(order labels bindings ('<undefined>))))))
  251. ((populate 2 maker ((label exp) ...))
  252. (maker exp ...))))
  253. (define-syntax order
  254. (syntax-rules ()
  255. ((order (label ...) ((label* . binding) ...) default k)
  256. (meta
  257. `(if-empty? (meta ,(remove-from (label* ...)
  258. (label ...)
  259. if-free=))
  260. (order "emit" (label ...) ((label* . binding) ...) default k)
  261. (syntax-error "Illegal labels in" ((label* . binding) ...)
  262. "Legal labels are" (label ...)))))
  263. ((order "emit" (label ...) bindings default k)
  264. (meta
  265. `((label . (meta ,(syntax-lookup label
  266. bindings
  267. if-free=
  268. default)))
  269. ...)
  270. k))))
  271. ;============================================================================================
  272. ; Simple generic functions:
  273. (define-syntax define-generic
  274. (syntax-rules ()
  275. ((define-generic (name arg ...))
  276. (define-generic (name arg ...)
  277. (lambda (arg ...) (error "Inapplicable method:" 'name
  278. "Arguments:" (show arg) ... ))))
  279. ((define-generic (name arg ...) proc)
  280. (define name (make-generic (arg ...) proc)))))
  281. (define-syntax define-method
  282. (syntax-rules ()
  283. ((define-method (generic (arg pred?) ...) . body)
  284. (define-method generic (pred? ...) (arg ...) (lambda (arg ...) . body)))
  285. ((define-method generic (pred? ...) (arg ...) procedure)
  286. (let ((next ((generic) 'get-proc))
  287. (proc procedure))
  288. (((generic) 'set-proc)
  289. (lambda (arg ...)
  290. (if (and (pred? arg) ...)
  291. (proc arg ...)
  292. (next arg ...))))))))
  293. (define-syntax make-generic
  294. (syntax-rules ()
  295. ((make-generic (arg arg+ ...) default-proc)
  296. (let ((proc default-proc))
  297. (case-lambda
  298. ((arg arg+ ...)
  299. (proc arg arg+ ...))
  300. (()
  301. (lambda (msg)
  302. (case msg
  303. ((get-proc) proc)
  304. ((set-proc) (lambda (new)
  305. (set! proc new)))))))))))
  306. (define-generic (show x)
  307. (lambda (x) x))
  308. (define (any? x) #t)
  309. ;============================================================================================
  310. ; Syntax utilities:
  311. (define-syntax syntax-error
  312. (syntax-rules ()))
  313. (define-syntax syntax-apply
  314. (syntax-rules ()
  315. ((syntax-apply (f . args) exp ...)
  316. (f exp ... . args))))
  317. (define-syntax syntax-cons
  318. (syntax-rules ()
  319. ((syntax-cons x rest k)
  320. (syntax-apply k (x . rest)))))
  321. (define-syntax syntax-cons-after
  322. (syntax-rules ()
  323. ((syntax-cons-after rest x k)
  324. (syntax-apply k (x . rest)))))
  325. (define-syntax if-empty?
  326. (syntax-rules ()
  327. ((if-empty? () sk fk) sk)
  328. ((if-empty? (h . t) sk fk) fk)))
  329. (define-syntax add-temporaries
  330. (syntax-rules ()
  331. ((add-temporaries lst k) (add-temporaries lst () k))
  332. ((add-temporaries () lst-temps k) (syntax-apply k lst-temps))
  333. ((add-temporaries (h . t) (done ...) k) (add-temporaries t (done ... (h temp)) k))))
  334. (define-syntax if-free=
  335. (syntax-rules ()
  336. ((if-free= x y kt kf)
  337. (let-syntax
  338. ((test (syntax-rules (x)
  339. ((test x kt* kf*) kt*)
  340. ((test z kt* kf*) kf*))))
  341. (test y kt kf)))))
  342. (define-syntax top:if-free=
  343. (syntax-rules ()
  344. ((top:if-free= x y kt kf)
  345. (begin
  346. (define-syntax if-free=:test
  347. (syntax-rules (x)
  348. ((if-free=:test x kt* kf*) kt*)
  349. ((if-free=:test z kt* kf*) kf*)))
  350. (if-free=:test y kt kf)))))
  351. (define-syntax meta
  352. (syntax-rules (meta quasiquote unquote)
  353. ((meta `(meta ,(function argument ...)) k)
  354. (meta `(argument ...) (syntax-apply-to function k)))
  355. ((meta `(a . b) k)
  356. (meta `a (descend-right b k)))
  357. ((meta `whatever k) (syntax-apply k whatever))
  358. ((meta `arg)
  359. (meta `arg (syntax-id)))))
  360. (define-syntax syntax-apply-to
  361. (syntax-rules ()
  362. ((syntax-apply-to (argument ...) function k)
  363. (function argument ... k))))
  364. (define-syntax descend-right
  365. (syntax-rules ()
  366. ((descend-right evaled b k)
  367. (meta `b (syntax-cons-after evaled k)))))
  368. (define-syntax syntax-id
  369. (syntax-rules ()
  370. ((syntax-id arg) arg)))
  371. (define-syntax remove-duplicates
  372. (syntax-rules ()
  373. ((remove-duplicates lst compare? k)
  374. (remove-duplicates lst () compare? k))
  375. ((remove-duplicates () done compare? k)
  376. (syntax-apply k done))
  377. ((remove-duplicates (h . t) (d ...) compare? k)
  378. (if-member? h (d ...) compare?
  379. (remove-duplicates t (d ...) compare? k)
  380. (remove-duplicates t (d ... h) compare? k)))))
  381. (define-syntax syntax-filter
  382. (syntax-rules ()
  383. ((syntax-filter () (if-p? arg ...) k)
  384. (syntax-apply k ()))
  385. ((syntax-filter (h . t) (if-p? arg ...) k)
  386. (if-p? h arg ...
  387. (syntax-filter t (if-p? arg ...) (syntax-cons-after h k))
  388. (syntax-filter t (if-p? arg ...) k)))))
  389. (define-syntax if-member?
  390. (syntax-rules ()
  391. ((if-member? x () compare? sk fk)
  392. fk)
  393. ((if-member? x (h . t) compare? sk fk)
  394. (compare? x h
  395. sk
  396. (if-member? x t compare? sk fk)))))
  397. (define-syntax union
  398. (syntax-rules ()
  399. ((union (x ...) ... compare? k)
  400. (remove-duplicates (x ... ...) compare? k))))
  401. (define-syntax intersection
  402. (syntax-rules ()
  403. ((intersection list1 list2 compare? k)
  404. (syntax-filter list1 (if-member? list2 compare?) k))))
  405. (define-syntax remove-from
  406. (syntax-rules ()
  407. ((remove-from list1 list2 compare? k)
  408. (syntax-filter list1 (if-not-member? list2 compare?) k))))
  409. (define-syntax if-not-member?
  410. (syntax-rules ()
  411. ((if-not-member? x list compare? sk fk)
  412. (if-member? x list compare? fk sk))))
  413. (define-syntax generate-identifier
  414. (syntax-rules ()
  415. ((generate-identifier k) (syntax-apply k generated-identifier))))
  416. (define-syntax syntax-if
  417. (syntax-rules ()
  418. ((syntax-if #f sk fk) fk)
  419. ((syntax-if other sk fk) sk)))
  420. (define-syntax syntax-lookup
  421. (syntax-rules ()
  422. ((syntax-lookup label () compare fail k)
  423. (syntax-apply k fail))
  424. ((syntax-lookup label ((label* . value) . bindings) compare fail k)
  425. (compare label label*
  426. (syntax-apply k value)
  427. (syntax-lookup label bindings compare fail k)))))