This file is indexed.

/usr/share/scheme48-1.9/big/iterate.scm is in scheme48 1.9-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
; Part of Scheme 48 1.9.  See file COPYING for notices and license.

; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber, Robert Ransom

; This builds the macro call to make the folder and constructs the arguments
; for the resulting fold procedure.  The first three clauses add a loop variable
; and final expression if they are missing.
;
; I caved in and passed the body to the FOLDER macro instead of passing it in
; as a lambda to the procedure produced by the macro.

(define-syntax reduce
  (syntax-rules ()

    ; Single state, no loop variable
    ((reduce (fold-vars ...) (state-var) body maybe-final ...)
     (iterate loop (fold-vars ...) (state-var) (loop body) maybe-final ...))

    ; No state, no loop variable
    ((reduce (fold-vars ...) () body maybe-final ...)
     (iterate loop (fold-vars ...) ()
	      (begin body (loop))
	      maybe-final ...))

    ; Multiple state, no loop variable
    ((reduce (fold-vars ...) (state-vars ...) body maybe-final ...)
     (iterate loop (fold-vars ...) (state-vars ...)
	      (call-with-values (lambda () body) loop)
	      maybe-final ...))))

(define-syntax iterate
  (syntax-rules ()

    ; No final expression
    ((iterate loop (fold-vars ...) ((state-var init) ...) body)
     (iterate loop (fold-vars ...) ((state-var init) ...) body
	     (values state-var ...)))

    ; Weird degenerate case with no iteration variables.
    ((iterate loop () ((state-var init) ...) body final)
     (let loop ((state-var init) ...) body))

    ; All there
    ((iterate loop
	      ((type value-var args ...) ...)
	      ((state-var init) ...)
	      body
	      final)
     ((folder ((type value-var args ...) ...) (state-var ...) loop body)
      (lambda (state-var ...)
	final)
      args ... ...
      init ...))))

; The entrance to all the rest of this.  The first step is to make the lists
; of types, value variables (which will be bound to the elements of the
; sequences), and fold variables (which will be bound to the successive
; state values of the sequence producer).

(define-syntax folder
  (syntax-rules ()
    ((folder ((type value-var args ...) ...) (state-var ...) loop body)
     (var-loop ((type value-var args ...) ...)
	       #f () () () ()
	       (state-var ...) loop body))))

; If we have reached the end of the sequences we go on to FOLDER-LOOP to build
; the body of the loop.  Otherwise we make new variables to match the arguments
; to the next sequence and continue.

(define-syntax var-loop
  (syntax-rules ()
    ((var-loop () seen-synched? (type ...)
	       (value-var ...) ((fold-var init) ...) end-tests
	       (state-var ...)
	       body-loop
	       body)
     (folder-loop (type ...)
		  (let ((body-loop (lambda (state-var ...)
				     (loop fold-var ... state-var ...))))
		    body)
		  ()
		  ((fold-var init) ...)
		  end-tests
		  (state-var ...)
		  loop
		  final))
    ((var-loop ((type value-var args ...) more ...) stuff ...)
     (copy-vars (args ...) () (var-loop2 type value-var (more ...) stuff ...)))))

; This is the continuation to the COPY-VARS use above.  We add the variables
; to the end of the variables list and then get the SYNC value.

(define-syntax var-loop2
  (syntax-rules ()
    ((var-loop2 vars type value-var stuff ...)
     (type sync (var-loop3 (type value-var vars stuff ...))))))

; This is the continuation to the SYNC `call' in VAR-LOOP2.  We get the state
; variable names.

(define-syntax var-loop3
  (syntax-rules ()
    ((var-loop3 sync? (type value-var vars stuff ...))
     (type state-vars vars (var-loop4 (type sync? value-var vars stuff ...))))))

; This is the end of the VAR-LOOP body.  We dispatch on whether TYPE, which
; has just been queried for its info, is synchronized and whether it is the
; first or a subsequent synchronized type.  In all cases we add the various
; code fragments obtained from TYPE to the appropriate lists and then go back
; to the top of the loop.

(define-syntax var-loop4
  (syntax-rules ()
    ; TYPE is the first synchronized type we have seen.
    ((var-loop4 ((fold-var init) ...)
		(type
		 #t
		 value-var
		 vars
		 more-types
		 #f
		 (types ...) (value-vars ...) (fold-init ...) end-tests
		 stuff ...))
     (var-loop more-types
	       #t
	       ((type #t #f (fold-var ...) value-var vars)
		types ...)
	       (value-vars ... value-var)
	       (fold-init ... (fold-var init) ...)
	       end-tests
	       stuff ...))
    ; TYPE is a synchronized type but not the first we have seen.
    ((var-loop4 ((fold-var init) ...)
		(type
		 #t
		 value-var
		 vars
		 more-types
		 #t
		 (types ...) (value-vars ...) (fold-init ...)
		 end-tests
		 stuff ...))
     (var-loop more-types
	       #t
	       ((type #t #t (fold-var ...) value-var vars)
		types ...)
	       (value-vars ... value-var)
	       (fold-init ... (fold-var init) ...)
	       ((type done vars (fold-var ...)) . end-tests)
	       stuff ...))
    ; TYPE is not synchronized.
    ((var-loop4 ((fold-var init) ...)
		(type
		 #f
		 value-var
		 vars
		 more-types
		 seen-synched?
		 (types ...) (value-vars ...) (fold-init ...) end-tests
		 stuff ...))
     (var-loop more-types
	       seen-synched?
	       ((type #f seen-synched? (fold-var ...) value-var vars)
		types ...)
	       (value-vars ... value-var)
	       (fold-init ... (fold-var init) ...)
	       end-tests
	       stuff ...))))

; A loop to produce a list of fresh variables.  The new variables are tacked
; onto the end of the body.

(define-syntax copy-vars
  (syntax-rules ()
    ((copy-vars () vars (cont stuff ...))
     (cont vars stuff ...))
    ((copy-vars (x y ...) (vars ...) cont)
     (copy-vars (y ...) (vars ... a) cont))))

; Here we build up the body of the loop.  When all the sequences are done we
; are done.
;
; For each sequence we do (type step stuff ...) to build the body and
; (type init vars ...) to get the initial value of the fold variable for
; that sequence.  Here `step' and `init' are keywords.
;
; The actual arguments to (type step stuff ...) are:
;  vars ...		; variables bound to the sequence's arguments
;  fold-var		; variable bound to the last state and to be bound to the
;			;  next state
;  value-var		; variable to be bound to the next element
;  loop-body-exp	; this expression continues the loop
;  final-exp		; this expression ends the loop

(define-syntax folder-loop
  (syntax-rules ()
    ((folder-loop ()			; no more sequences
		  loop-body		; body so far
		  (args ...)		; complete list of sequence arguments
		  ((fold-var init) ...) ; fold variables and their initial values
		  end-tests		; end test for first synchronized seq.
		  (state-var ...)	; the user's state variables
		  loop			; loop variable
		  final)		; final argument variable
     (lambda (final args ... state-var ...)
       (let loop ((fold-var init) ... (state-var state-var) ...)
	 loop-body)))
    ; Not synchronized
    ((folder-loop ((type #f synched? fold-vars value-var (vars ...)) more ...)
		  loop-body
		  args
		  fold-var-inits end-tests state-vars
		  loop final)
     (folder-loop (more ...)
		  (type step (vars ...) fold-vars value-var
			loop-body (final . state-vars))
		  (vars ... . args)
		  fold-var-inits end-tests state-vars
		  loop final))
    ; Synchronized, not first such
    ((folder-loop ((type #t #t fold-vars value-var (vars ...)) more ...)
		  loop-body
		  args
		  fold-var-inits end-tests state-vars
		  loop final)
     (folder-loop (more ...)
		  (type step (vars ...) fold-vars value-var
			loop-body
			(begin (assertion-violation 'folder
						    "synchronized sequence ended early")
			       (values)))
		  (vars ... . args)
		  fold-var-inits end-tests state-vars
		  loop final))
    ; First synchronized sequence
    ((folder-loop ((type #t #f fold-vars value-var (vars ...)) more ...)
		  loop-body
		  args
		  fold-var-inits end-tests state-vars
		  loop final)
     (folder-loop (more ...)
		  (type step (vars ...) fold-vars value-var
			loop-body (if (and . end-tests)
				      (final . state-vars)
				      (begin (assertion-violation 'folder
								  "synchronized sequence ended early")
					     (values))))
		  (vars ... . args)
		  fold-var-inits end-stests state-vars
		  loop final))))
		 
; Iterators

; (list* var list)
; (list-spine* var list)
; (list-spine-cycle-safe* var list on-cycle-thunk)
; (vector* var vector)
; (string* var string)
; (count* var start [end [step]])
; (bits* var integer [step-size])
; (input* var input-port reader)        ; (reader port) -> value or eof-object
; (stream* var function initial-state)  ; (function state) -> [value new-state]
;   A new-state of #F means that the previous value was the final one.

(define-syntax list*
  (syntax-rules (sync state-vars step)
    ((list* sync (next more))
     (next #f more))
    ((list* state-vars (start-list) (next more))
     (next ((list-var start-list)) more))
    ((list* step (start-list) (list-var) value-var loop-body final-exp)
     (if (null? list-var)
         final-exp
         (let ((value-var (car list-var))
               (list-var (cdr list-var)))
           loop-body)))))

(define-syntax list%
  (syntax-rules (sync done)
    ((list% sync (next more))
     (next #t more))
    ((list% done (start-list) (list-var))
     (null? list-var))
    ((list% stuff ...)
     (list* stuff ...))))

(define-syntax list-spine*
  (syntax-rules (sync state-vars step)
    ((list-spine* sync (next more))
     (next #f more))
    ((list-spine* state-vars (start-list) (next more))
     (next ((list-var start-list)) more))
    ((list-spine* step (start-list) (list-var)
		  value-var loop-body final-exp)
     (if (null? list-var)
	 final-exp
	 (let ((value-var list-var)
	       (list-var (cdr list-var)))
	   loop-body)))))

(define-syntax list-spine%
  (syntax-rules (sync done)
    ((list-spine% sync (next more))
     (next #t more))
    ((list-spine% done (start-list) (list-var))
     (null? list-var))
    ((list-spine% stuff ...)
     (list-spine* stuff ...))))

(define-syntax list-spine-cycle-safe*
  (syntax-rules (sync state-vars step)
    ((list-spine-cycle-safe* sync (next more))
     (next #f more))
    ((list-spine-cycle-safe* state-vars
                             (start-list on-cycle-thunk)
                             (next more))
     (next ((list-var start-list)
            (lag-var start-list)
            (move-lag? #f))
           more))
    ((list-spine-cycle-safe* step
                             (start-list on-cycle-thunk)
                             (list-var lag-var move-lag?)
                             spine-var loop-body final-exp)
     (if (null? list-var)
         final-exp
         (let ((spine-var list-var)
               (list-var (cdr list-var))
               (lag-var (if move-lag?
                            (cdr lag-var)
                            lag-var))
               (move-lag? (not move-lag?)))
           (if (eq? list-var lag-var)
               (on-cycle-thunk)
               loop-body))))))

(define-syntax list-spine-cycle-safe%
  (syntax-rules (sync done)
    ((list-spine-cycle-safe% sync (next more))
     (next #t more))
    ((list-spine-cycle-safe% done
			     (start-list on-cycle-thunk)
			     (list-var lag-var move-lag?))
     (null? list-var))
    ((list-spine-cycle-safe% stuff ...)
     (list-spine-cycle-safe* stuff ...))))

(define-syntax vector*
  (syntax-rules (sync state-vars step)
    ((vector* sync (next more))
     (next #f more))
    ((vector* state-vars (vector) (next more))
     (next ((i 0)) more))
    ((vector* step (vector) (i) value-var loop-body final-exp)
     (if (= i (vector-length vector))
	 final-exp
	 (let ((value-var (vector-ref vector i))
	       (i (+ i 1)))
	   loop-body)))))

(define-syntax vector%
  (syntax-rules (sync done)
    ((vector% sync (next more))
     (next #t more))
    ((vector% done (vector) (i))
     (= i (vector-length vector)))
    ((vector% stuff ...)
     (vector* stuff ...))))

(define-syntax string*
  (syntax-rules (sync state-vars step)
    ((string* sync (next more))
     (next #f more))
    ((string* state-vars (string) (next more))
     (next ((i 0)) more))
    ((string* step (string) (i) value-var loop-body final-exp)
     (if (= i (string-length string))
	 final-exp
	 (let ((value-var (string-ref string i))
	       (i (+ i 1)))
	   loop-body)))))

(define-syntax string%
  (syntax-rules (sync done)
    ((string% sync (next more))
     (next #t more))
    ((string% done (string) (i))
     (= i (string-length string)))
    ((string% stuff ...)
     (string* stuff ...))))

(define-syntax count*
  (syntax-rules (sync state-vars step)
    ((count* sync (next more))
     (next #f more))
    ((count* state-vars (start args ...) (next more))
     (next ((i start)) more))
    ((count* step (start) (i) value-var loop-body final-exp)
     (let ((value-var i)
	   (i (+ i 1)))
       loop-body))
    ((count* step (start end) (i) value-var loop-body final-exp)
     (count* step (start end 1) (i) value-var loop-body final-exp))
; This doesn't work because we don't see the original arguments, just variables
; bound to them.
;    ((count* step (start #f increment) (i) value-var loop-body final-exp)
;     (let ((value-var i)
;	   (i (+ i increment)))
;       loop-body))
    ((count* step (start end increment) (i) value-var loop-body final-exp)
     (if (= i end)
	 final-exp
	 (let ((value-var i)
	       (i (+ i increment)))
	   loop-body)))))

; Synchronized, so we don't allow the unbounded version.

(define-syntax count%
  (syntax-rules (sync done state-vars step)
    ((count% sync (next more))
     (next #t more))
    ((count% done (start end increment ...) (i))
     (= end i))
    ((count% state-vars (start args ...) (next more))
     (next ((i start)) more))
    ((count% step (start end) (i) value-var loop-body final-exp)
     (count% step (start end 1) (i) value-var loop-body final-exp))
    ((count% step (start end increment) (i) value-var loop-body final-exp)
     (if (= i end)
	 final-exp
	 (let ((value-var i)
	       (i (+ i increment)))
	   loop-body)))))

; I would really like to be able to lift the mask calculation out of the loop.
; There could be yet another clause in iterators that returned (VAR VAL) clauses
; to be added to a LET around the loop.

(define-syntax bits*
  (syntax-rules (sync state-vars step)
    ((bits* sync (next more))
     (next #f more))
    ((bits* state-vars (bit-set args ...) (next more))
     (next ((i bit-set)) more))
    ((bits* step (bit-set) (i) value-var loop-body final-exp)
     (if (= i 0)
	 final-exp
	 (let ((value-var (odd? i))
	       (i (arithmetic-shift i -1)))
	   loop-body)))
    ((bits* step (bit-set size) (i) value-var loop-body final-exp)
     (if (= i 0)
	 final-exp
	 (let ((value-var (bitwise-and i (- (arithmetic-shift 1 size) 1)))
	       (i (arithmetic-shift i (- size))))
	   loop-body)))))

; This one is unlikely to be used much, because the termination test is
; so data dependent.

(define-syntax bits%
  (syntax-rules (sync done state-vars step)
    ((bits% sync (next more))
     (next #t more))
    ((bits% done values (i))
     (= i 0))
    ((bits% more ...)
     (bits* more ...))))

(define-syntax input*
  (syntax-rules (sync state-vars step)
    ((input* sync (next more))
     (next #f more))
    ((input* state-vars (port reader) (next more))
     (next () more))
    ((input* step (port reader) () value-var loop-body final-exp)
     (let ((value-var (reader port)))
       (if (eof-object? value-var)
	   final-exp
	   loop-body)))))

(define-syntax input%
  (syntax-rules (sync done)
    ((input% sync (next more))
     (next #t more))
    ((input% done (port reader) ())
     (eof-object? (peek-char port)))
    ((input% more ...)
     (input* more ...))))

(define-syntax stream*
  (syntax-rules (sync state-vars step)
    ((stream* sync (next more))
     (next #f more))
    ((stream* state-vars (function start-state) (next more))
     (next ((state start-state)) more))
    ((stream* step (function start-state) (state) value-var loop-body final-exp)
     (call-with-values
       (lambda ()
	 (function state))
       (lambda (value-var state)
	 (if state
	     loop-body
	     final-exp))))))

(define-syntax stream%
  (syntax-rules (sync done)
    ((stream% sync (next more))
     (next #t more))
    ((stream% done (function start-state) (state))
     (call-with-values
       (lambda ()
	 (function state))
       (lambda (value-var state)
	 (not state))))
    ((stream% more ...)
     (stream* more ...))))