2010/12/08

SERIES で scan-file 系を実装するとき

今夜も Common Lisp の SERIES.

SERIES で scan-file 系は encapsulated と defS のどちらを使って実装すべきなんだろうか?

producing は with-open-file(unwind-protect) のために使えないと思うから、 encapsulated と defS のどちらかを使うんだろうと思うのだけれど。

あっ、defS の方の最後の ,external-format のところ、これでいいのか分からない。

(defun scan-line2-wrap (file name external-format body)
`(with-open-file (,file ,name :external-format ,external-format) ,body))

(defmacro scan-line2 (name &optional (external-format :default))
(let ((file (gensym)))
`(encapsulated #'(lambda (body)
(scan-line2-wrap ',file ',name ',external-format body))
(scan-fn t
(lambda () (read-line ,file nil))
(lambda (_) (declare (ignore _)) (read-line ,file nil))
#'null))))

;;(scan-line2 "~/.sbclrc")
;;(scan-line2 "~/.sbclrc" :utf-8)
;;(collect (scan-line2 "~/.sbclrc"))
;;(collect (scan-line2 "~/.sbclrc" :utf-8))


(series::defS scan-line (name &optional (external-format :default))
"(scan-line file-name &key (external-format :default))"
(series::fragl
((name) (external-format)) ((items t))
((items t)
(lastcons cons (list nil))
(lst list))
()
((setq lst lastcons)
(with-open-file (f name :direction :input :external-format external-format)
(loop
(cl:let ((item (read-line f nil)))
(unless item
(return nil))
(setq lastcons (setf (cdr lastcons) (cons item nil))))))
(setq lst (cdr lst)))
((if (null lst) (go series::end))
(setq items (car lst))
(setq lst (cdr lst)))
()
()
:context)
:optimizer
(series::apply-literal-frag
(cl:let ((file (series::new-var 'file)))
`((((external-format)) ((items t))
((items t))
()
()
((unless (setq items (read-line ,file nil))
(go series::end)))
()
((#'(lambda (code)
(list 'with-open-file
'(,file ,name :direction :input :external-format ,external-format)
code)) :loop))
:context)
,external-format))))

0 件のコメント: