複数行の文字列を作成する
そろそろこの題目から抜けだしたかったのですが
どうやら前回の修正でも駄目らしいですorz
ヒアドキュメントを正確に実装するならば
終端を示す文字列は
- 行頭にある
- その行はその終端を表す文字列のみである
という条件を満たす必要があるらしいです。
確かにRubyで実際にやってみるとそうなりますね。
s = <<EOS This is test. Ruby, the Object Oriented Script Language. EOSs
とか
s = <<EOS This is test. Ruby, the Object Oriented Script Language. sEOS
と入力してみると、エラーでsに文字列は代入されません。
s = <<EOS This is test. Ruby, the Object Oriented Script Language. EOSs EOS
こういう入力ですとOKなので、先程の条件通りですね。
では、上記の条件に合わせてリードマクロを変更します。
(defun |#<-reader| (stream sub-char numarg) (declare (ignore sub-car numarg)) (let (chars) (do ((curr (read-char stream) (read-char stream))) ((char= #\newline curr)) (push curr chars)) (let* ((pattern (coerce (nreverse chars) 'string)) (pointer pattern) (output)) (do ((curr (read-line stream) (read-line stream))) ((null curr)) (if (string= pattern curr) (return)) (setq output (concatenate 'string output curr (make-string 1 :initial-element #\newline)))) (string-right-trim '(#\Newline) output ) ))) (set-dispatch-macro-character #\# #\< #'|#<-reader|)
ではLet's Try。
(setq hoge #<END this is test string END ) "this is test string"
こんどこそ完成ですね!
ちなみにヒアドキュメントの条件を満たしていない場合にはリーダが動作しつづけてEOFまで読んでしまいエラーになります。
自分で追加した構文にも係らず言語自体のエラーを出してくれるのは有り難いですね。