; file reversal
(define (read-line . port)
(define (eat p c)
(if (and (not (eof-object? (peek-char p)))
(char=? (peek-char p) c))
(read-char p)))
(let ((p (if (null? port) (current-input-port) (car port))))
(let loop ((c (read-char p)) (line '()))
(cond ((eof-object? c) (if (null? line) c (list->string (reverse line))))
((char=? #\newline c) (eat p #\return) (list->string (reverse line)))
((char=? #\return c) (eat p #\newline) (list->string (reverse line)))
(else (loop (read-char p) (cons c line)))))))
; read up to max-lines from current input, return lines
(define (read-lines max-lines)
(let loop ((x (read-line)) (xs (list)) (k max-lines))
(if (or (zero? k) (eof-object? x))
(reverse xs)
(loop (read-line) (cons x xs) (- k 1)))))
(define (temp num)
(string-append
"./file-reversal."
(number->string (get-process-id))
"."
(number->string num)))
(define max-lines 10000)
(define (read-into-temps)
(let loop ((file-num 1))
(let ((lines (read-lines max-lines)))
(if (null? lines) (- file-num 1)
(let ((temp-file-name (temp file-num)))
(with-output-to-file temp-file-name
(lambda ()
(do ((lines lines (cdr lines)))
((null? lines))
(display (car lines)) (newline))))
(loop (+ file-num 1)))))))
(define (write-output num-files)
(let loop ((num num-files))
(when (positive? num)
(with-input-from-file (temp num)
(lambda ()
(do ((lines (reverse (read-lines -1)) (cdr lines)))
((null? lines))
(display (car lines)) (newline))))
(loop (- num 1)))))
(define (reverse-file in-file out-file)
(with-input-from-file in-file (lambda ()
(with-output-to-file out-file (lambda ()
(write-output (read-into-temps)))))))
(reverse-file "bible.txt" "txt.elbib")