2006/01/16

いっけん仕事で使うスクリプトのように見えてただの道楽シリーズ。けっして就業時間中は遊んでません。つーか、ほんとに日中は(時間的精神的な)余裕なさすぎで、あちらこちらに迷惑をかけている。この場を借りてお詫びします。

で、今日の成果は、なんとなく階層化された文章の見出しに連番をふる gauche スクリプト。
numbering.scm

おなじことをするプログラムは、むかしはPerlで書いて、それからRubyでも書いたけど、いずれも上位レベルの見出しの現在値を保持するのに大域変数を使っていた。大域変数を使わないようにするには継続を使うんだろうなあと知ってはいたけれど、"Seasoned Schemer" を読んで、ようやく何をどうやって継続すればいいのかイメージがわいた。ここでは、現在までのレベルの見出し情報を次の行の処理に継続させている。

(define (numbering file)
(with-input-from-file file
(lambda ()
(letrec
((Ns (lambda (ctrs)
(let ((line (read-line)))
(cond
((eof-object? line)
'())
((leveled? line)
(let ((ctr-lv (length ctrs))
(lin-lv (level-of line)))
(cond
((< ctr-lv lin-lv)
(let ((ctrs (deeper ctrs)))
(cons (put-head line ctrs)
(Ns ctrs))))
((> ctr-lv lin-lv)
(let ((ctrs (add1 (chop ctrs lin-lv))))
(cons (put-head line ctrs)
(Ns ctrs))))
((equal? ctr-lv lin-lv)
(let ((ctrs (add1 ctrs)))
(cons (put-head line ctrs)
(Ns ctrs)))))))
(else (cons line
(Ns ctrs))))))))
(Ns '())))))

No comments :