iterate.scm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom
  3. ; This builds the macro call to make the folder and constructs the arguments
  4. ; for the resulting fold procedure. The first three clauses add a loop variable
  5. ; and final expression if they are missing.
  6. ;
  7. ; I caved in and passed the body to the FOLDER macro instead of passing it in
  8. ; as a lambda to the procedure produced by the macro.
  9. (define-syntax reduce
  10. (syntax-rules ()
  11. ; Single state, no loop variable
  12. ((reduce (fold-vars ...) (state-var) body maybe-final ...)
  13. (iterate loop (fold-vars ...) (state-var) (loop body) maybe-final ...))
  14. ; No state, no loop variable
  15. ((reduce (fold-vars ...) () body maybe-final ...)
  16. (iterate loop (fold-vars ...) ()
  17. (begin body (loop))
  18. maybe-final ...))
  19. ; Multiple state, no loop variable
  20. ((reduce (fold-vars ...) (state-vars ...) body maybe-final ...)
  21. (iterate loop (fold-vars ...) (state-vars ...)
  22. (call-with-values (lambda () body) loop)
  23. maybe-final ...))))
  24. (define-syntax iterate
  25. (syntax-rules ()
  26. ; No final expression
  27. ((iterate loop (fold-vars ...) ((state-var init) ...) body)
  28. (iterate loop (fold-vars ...) ((state-var init) ...) body
  29. (values state-var ...)))
  30. ; Weird degenerate case with no iteration variables.
  31. ((iterate loop () ((state-var init) ...) body final)
  32. (let loop ((state-var init) ...) body))
  33. ; All there
  34. ((iterate loop
  35. ((type value-var args ...) ...)
  36. ((state-var init) ...)
  37. body
  38. final)
  39. ((folder ((type value-var args ...) ...) (state-var ...) loop body)
  40. (lambda (state-var ...)
  41. final)
  42. args ... ...
  43. init ...))))
  44. ; The entrance to all the rest of this. The first step is to make the lists
  45. ; of types, value variables (which will be bound to the elements of the
  46. ; sequences), and fold variables (which will be bound to the successive
  47. ; state values of the sequence producer).
  48. (define-syntax folder
  49. (syntax-rules ()
  50. ((folder ((type value-var args ...) ...) (state-var ...) loop body)
  51. (var-loop ((type value-var args ...) ...)
  52. #f () () () ()
  53. (state-var ...) loop body))))
  54. ; If we have reached the end of the sequences we go on to FOLDER-LOOP to build
  55. ; the body of the loop. Otherwise we make new variables to match the arguments
  56. ; to the next sequence and continue.
  57. (define-syntax var-loop
  58. (syntax-rules ()
  59. ((var-loop () seen-synched? (type ...)
  60. (value-var ...) ((fold-var init) ...) end-tests
  61. (state-var ...)
  62. body-loop
  63. body)
  64. (folder-loop (type ...)
  65. (let ((body-loop (lambda (state-var ...)
  66. (loop fold-var ... state-var ...))))
  67. body)
  68. ()
  69. ((fold-var init) ...)
  70. end-tests
  71. (state-var ...)
  72. loop
  73. final))
  74. ((var-loop ((type value-var args ...) more ...) stuff ...)
  75. (copy-vars (args ...) () (var-loop2 type value-var (more ...) stuff ...)))))
  76. ; This is the continuation to the COPY-VARS use above. We add the variables
  77. ; to the end of the variables list and then get the SYNC value.
  78. (define-syntax var-loop2
  79. (syntax-rules ()
  80. ((var-loop2 vars type value-var stuff ...)
  81. (type sync (var-loop3 (type value-var vars stuff ...))))))
  82. ; This is the continuation to the SYNC `call' in VAR-LOOP2. We get the state
  83. ; variable names.
  84. (define-syntax var-loop3
  85. (syntax-rules ()
  86. ((var-loop3 sync? (type value-var vars stuff ...))
  87. (type state-vars vars (var-loop4 (type sync? value-var vars stuff ...))))))
  88. ; This is the end of the VAR-LOOP body. We dispatch on whether TYPE, which
  89. ; has just been queried for its info, is synchronized and whether it is the
  90. ; first or a subsequent synchronized type. In all cases we add the various
  91. ; code fragments obtained from TYPE to the appropriate lists and then go back
  92. ; to the top of the loop.
  93. (define-syntax var-loop4
  94. (syntax-rules ()
  95. ; TYPE is the first synchronized type we have seen.
  96. ((var-loop4 ((fold-var init) ...)
  97. (type
  98. #t
  99. value-var
  100. vars
  101. more-types
  102. #f
  103. (types ...) (value-vars ...) (fold-init ...) end-tests
  104. stuff ...))
  105. (var-loop more-types
  106. #t
  107. ((type #t #f (fold-var ...) value-var vars)
  108. types ...)
  109. (value-vars ... value-var)
  110. (fold-init ... (fold-var init) ...)
  111. end-tests
  112. stuff ...))
  113. ; TYPE is a synchronized type but not the first we have seen.
  114. ((var-loop4 ((fold-var init) ...)
  115. (type
  116. #t
  117. value-var
  118. vars
  119. more-types
  120. #t
  121. (types ...) (value-vars ...) (fold-init ...)
  122. end-tests
  123. stuff ...))
  124. (var-loop more-types
  125. #t
  126. ((type #t #t (fold-var ...) value-var vars)
  127. types ...)
  128. (value-vars ... value-var)
  129. (fold-init ... (fold-var init) ...)
  130. ((type done vars (fold-var ...)) . end-tests)
  131. stuff ...))
  132. ; TYPE is not synchronized.
  133. ((var-loop4 ((fold-var init) ...)
  134. (type
  135. #f
  136. value-var
  137. vars
  138. more-types
  139. seen-synched?
  140. (types ...) (value-vars ...) (fold-init ...) end-tests
  141. stuff ...))
  142. (var-loop more-types
  143. seen-synched?
  144. ((type #f seen-synched? (fold-var ...) value-var vars)
  145. types ...)
  146. (value-vars ... value-var)
  147. (fold-init ... (fold-var init) ...)
  148. end-tests
  149. stuff ...))))
  150. ; A loop to produce a list of fresh variables. The new variables are tacked
  151. ; onto the end of the body.
  152. (define-syntax copy-vars
  153. (syntax-rules ()
  154. ((copy-vars () vars (cont stuff ...))
  155. (cont vars stuff ...))
  156. ((copy-vars (x y ...) (vars ...) cont)
  157. (copy-vars (y ...) (vars ... a) cont))))
  158. ; Here we build up the body of the loop. When all the sequences are done we
  159. ; are done.
  160. ;
  161. ; For each sequence we do (type step stuff ...) to build the body and
  162. ; (type init vars ...) to get the initial value of the fold variable for
  163. ; that sequence. Here `step' and `init' are keywords.
  164. ;
  165. ; The actual arguments to (type step stuff ...) are:
  166. ; vars ... ; variables bound to the sequence's arguments
  167. ; fold-var ; variable bound to the last state and to be bound to the
  168. ; ; next state
  169. ; value-var ; variable to be bound to the next element
  170. ; loop-body-exp ; this expression continues the loop
  171. ; final-exp ; this expression ends the loop
  172. (define-syntax folder-loop
  173. (syntax-rules ()
  174. ((folder-loop () ; no more sequences
  175. loop-body ; body so far
  176. (args ...) ; complete list of sequence arguments
  177. ((fold-var init) ...) ; fold variables and their initial values
  178. end-tests ; end test for first synchronized seq.
  179. (state-var ...) ; the user's state variables
  180. loop ; loop variable
  181. final) ; final argument variable
  182. (lambda (final args ... state-var ...)
  183. (let loop ((fold-var init) ... (state-var state-var) ...)
  184. loop-body)))
  185. ; Not synchronized
  186. ((folder-loop ((type #f synched? fold-vars value-var (vars ...)) more ...)
  187. loop-body
  188. args
  189. fold-var-inits end-tests state-vars
  190. loop final)
  191. (folder-loop (more ...)
  192. (type step (vars ...) fold-vars value-var
  193. loop-body (final . state-vars))
  194. (vars ... . args)
  195. fold-var-inits end-tests state-vars
  196. loop final))
  197. ; Synchronized, not first such
  198. ((folder-loop ((type #t #t fold-vars value-var (vars ...)) more ...)
  199. loop-body
  200. args
  201. fold-var-inits end-tests state-vars
  202. loop final)
  203. (folder-loop (more ...)
  204. (type step (vars ...) fold-vars value-var
  205. loop-body
  206. (begin (assertion-violation 'folder
  207. "synchronized sequence ended early")
  208. (values)))
  209. (vars ... . args)
  210. fold-var-inits end-tests state-vars
  211. loop final))
  212. ; First synchronized sequence
  213. ((folder-loop ((type #t #f fold-vars value-var (vars ...)) more ...)
  214. loop-body
  215. args
  216. fold-var-inits end-tests state-vars
  217. loop final)
  218. (folder-loop (more ...)
  219. (type step (vars ...) fold-vars value-var
  220. loop-body (if (and . end-tests)
  221. (final . state-vars)
  222. (begin (assertion-violation 'folder
  223. "synchronized sequence ended early")
  224. (values))))
  225. (vars ... . args)
  226. fold-var-inits end-stests state-vars
  227. loop final))))
  228. ; Iterators
  229. ; (list* var list)
  230. ; (list-spine* var list)
  231. ; (list-spine-cycle-safe* var list on-cycle-thunk)
  232. ; (vector* var vector)
  233. ; (string* var string)
  234. ; (count* var start [end [step]])
  235. ; (bits* var integer [step-size])
  236. ; (input* var input-port reader) ; (reader port) -> value or eof-object
  237. ; (stream* var function initial-state) ; (function state) -> [value new-state]
  238. ; A new-state of #F means that the previous value was the final one.
  239. (define-syntax list*
  240. (syntax-rules (sync state-vars step)
  241. ((list* sync (next more))
  242. (next #f more))
  243. ((list* state-vars (start-list) (next more))
  244. (next ((list-var start-list)) more))
  245. ((list* step (start-list) (list-var) value-var loop-body final-exp)
  246. (if (null? list-var)
  247. final-exp
  248. (let ((value-var (car list-var))
  249. (list-var (cdr list-var)))
  250. loop-body)))))
  251. (define-syntax list%
  252. (syntax-rules (sync done)
  253. ((list% sync (next more))
  254. (next #t more))
  255. ((list% done (start-list) (list-var))
  256. (null? list-var))
  257. ((list% stuff ...)
  258. (list* stuff ...))))
  259. (define-syntax list-spine*
  260. (syntax-rules (sync state-vars step)
  261. ((list-spine* sync (next more))
  262. (next #f more))
  263. ((list-spine* state-vars (start-list) (next more))
  264. (next ((list-var start-list)) more))
  265. ((list-spine* step (start-list) (list-var)
  266. value-var loop-body final-exp)
  267. (if (null? list-var)
  268. final-exp
  269. (let ((value-var list-var)
  270. (list-var (cdr list-var)))
  271. loop-body)))))
  272. (define-syntax list-spine%
  273. (syntax-rules (sync done)
  274. ((list-spine% sync (next more))
  275. (next #t more))
  276. ((list-spine% done (start-list) (list-var))
  277. (null? list-var))
  278. ((list-spine% stuff ...)
  279. (list-spine* stuff ...))))
  280. (define-syntax list-spine-cycle-safe*
  281. (syntax-rules (sync state-vars step)
  282. ((list-spine-cycle-safe* sync (next more))
  283. (next #f more))
  284. ((list-spine-cycle-safe* state-vars
  285. (start-list on-cycle-thunk)
  286. (next more))
  287. (next ((list-var start-list)
  288. (lag-var start-list)
  289. (move-lag? #f))
  290. more))
  291. ((list-spine-cycle-safe* step
  292. (start-list on-cycle-thunk)
  293. (list-var lag-var move-lag?)
  294. spine-var loop-body final-exp)
  295. (if (null? list-var)
  296. final-exp
  297. (let ((spine-var list-var)
  298. (list-var (cdr list-var))
  299. (lag-var (if move-lag?
  300. (cdr lag-var)
  301. lag-var))
  302. (move-lag? (not move-lag?)))
  303. (if (eq? list-var lag-var)
  304. (on-cycle-thunk)
  305. loop-body))))))
  306. (define-syntax list-spine-cycle-safe%
  307. (syntax-rules (sync done)
  308. ((list-spine-cycle-safe% sync (next more))
  309. (next #t more))
  310. ((list-spine-cycle-safe% done
  311. (start-list on-cycle-thunk)
  312. (list-var lag-var move-lag?))
  313. (null? list-var))
  314. ((list-spine-cycle-safe% stuff ...)
  315. (list-spine-cycle-safe* stuff ...))))
  316. (define-syntax vector*
  317. (syntax-rules (sync state-vars step)
  318. ((vector* sync (next more))
  319. (next #f more))
  320. ((vector* state-vars (vector) (next more))
  321. (next ((i 0)) more))
  322. ((vector* step (vector) (i) value-var loop-body final-exp)
  323. (if (= i (vector-length vector))
  324. final-exp
  325. (let ((value-var (vector-ref vector i))
  326. (i (+ i 1)))
  327. loop-body)))))
  328. (define-syntax vector%
  329. (syntax-rules (sync done)
  330. ((vector% sync (next more))
  331. (next #t more))
  332. ((vector% done (vector) (i))
  333. (= i (vector-length vector)))
  334. ((vector% stuff ...)
  335. (vector* stuff ...))))
  336. (define-syntax string*
  337. (syntax-rules (sync state-vars step)
  338. ((string* sync (next more))
  339. (next #f more))
  340. ((string* state-vars (string) (next more))
  341. (next ((i 0)) more))
  342. ((string* step (string) (i) value-var loop-body final-exp)
  343. (if (= i (string-length string))
  344. final-exp
  345. (let ((value-var (string-ref string i))
  346. (i (+ i 1)))
  347. loop-body)))))
  348. (define-syntax string%
  349. (syntax-rules (sync done)
  350. ((string% sync (next more))
  351. (next #t more))
  352. ((string% done (string) (i))
  353. (= i (string-length string)))
  354. ((string% stuff ...)
  355. (string* stuff ...))))
  356. (define-syntax count*
  357. (syntax-rules (sync state-vars step)
  358. ((count* sync (next more))
  359. (next #f more))
  360. ((count* state-vars (start args ...) (next more))
  361. (next ((i start)) more))
  362. ((count* step (start) (i) value-var loop-body final-exp)
  363. (let ((value-var i)
  364. (i (+ i 1)))
  365. loop-body))
  366. ((count* step (start end) (i) value-var loop-body final-exp)
  367. (count* step (start end 1) (i) value-var loop-body final-exp))
  368. ; This doesn't work because we don't see the original arguments, just variables
  369. ; bound to them.
  370. ; ((count* step (start #f increment) (i) value-var loop-body final-exp)
  371. ; (let ((value-var i)
  372. ; (i (+ i increment)))
  373. ; loop-body))
  374. ((count* step (start end increment) (i) value-var loop-body final-exp)
  375. (if (= i end)
  376. final-exp
  377. (let ((value-var i)
  378. (i (+ i increment)))
  379. loop-body)))))
  380. ; Synchronized, so we don't allow the unbounded version.
  381. (define-syntax count%
  382. (syntax-rules (sync done state-vars step)
  383. ((count% sync (next more))
  384. (next #t more))
  385. ((count% done (start end increment ...) (i))
  386. (= end i))
  387. ((count% state-vars (start args ...) (next more))
  388. (next ((i start)) more))
  389. ((count% step (start end) (i) value-var loop-body final-exp)
  390. (count% step (start end 1) (i) value-var loop-body final-exp))
  391. ((count% step (start end increment) (i) value-var loop-body final-exp)
  392. (if (= i end)
  393. final-exp
  394. (let ((value-var i)
  395. (i (+ i increment)))
  396. loop-body)))))
  397. ; I would really like to be able to lift the mask calculation out of the loop.
  398. ; There could be yet another clause in iterators that returned (VAR VAL) clauses
  399. ; to be added to a LET around the loop.
  400. (define-syntax bits*
  401. (syntax-rules (sync state-vars step)
  402. ((bits* sync (next more))
  403. (next #f more))
  404. ((bits* state-vars (bit-set args ...) (next more))
  405. (next ((i bit-set)) more))
  406. ((bits* step (bit-set) (i) value-var loop-body final-exp)
  407. (if (= i 0)
  408. final-exp
  409. (let ((value-var (odd? i))
  410. (i (arithmetic-shift i -1)))
  411. loop-body)))
  412. ((bits* step (bit-set size) (i) value-var loop-body final-exp)
  413. (if (= i 0)
  414. final-exp
  415. (let ((value-var (bitwise-and i (- (arithmetic-shift 1 size) 1)))
  416. (i (arithmetic-shift i (- size))))
  417. loop-body)))))
  418. ; This one is unlikely to be used much, because the termination test is
  419. ; so data dependent.
  420. (define-syntax bits%
  421. (syntax-rules (sync done state-vars step)
  422. ((bits% sync (next more))
  423. (next #t more))
  424. ((bits% done values (i))
  425. (= i 0))
  426. ((bits% more ...)
  427. (bits* more ...))))
  428. (define-syntax input*
  429. (syntax-rules (sync state-vars step)
  430. ((input* sync (next more))
  431. (next #f more))
  432. ((input* state-vars (port reader) (next more))
  433. (next () more))
  434. ((input* step (port reader) () value-var loop-body final-exp)
  435. (let ((value-var (reader port)))
  436. (if (eof-object? value-var)
  437. final-exp
  438. loop-body)))))
  439. (define-syntax input%
  440. (syntax-rules (sync done)
  441. ((input% sync (next more))
  442. (next #t more))
  443. ((input% done (port reader) ())
  444. (eof-object? (peek-char port)))
  445. ((input% more ...)
  446. (input* more ...))))
  447. (define-syntax stream*
  448. (syntax-rules (sync state-vars step)
  449. ((stream* sync (next more))
  450. (next #f more))
  451. ((stream* state-vars (function start-state) (next more))
  452. (next ((state start-state)) more))
  453. ((stream* step (function start-state) (state) value-var loop-body final-exp)
  454. (call-with-values
  455. (lambda ()
  456. (function state))
  457. (lambda (value-var state)
  458. (if state
  459. loop-body
  460. final-exp))))))
  461. (define-syntax stream%
  462. (syntax-rules (sync done)
  463. ((stream% sync (next more))
  464. (next #t more))
  465. ((stream% done (function start-state) (state))
  466. (call-with-values
  467. (lambda ()
  468. (function state))
  469. (lambda (value-var state)
  470. (not state))))
  471. ((stream% more ...)
  472. (stream* more ...))))