文字列の別表記
プログラミング言語によっては、文字列を複数の方法で表記出来ることがある。
例えば、rubyの場合は以下の様に表記することが可能だ。
"文字列" '文字列' %Q{文字列} # その他にもあったように思うけど、使わないので不明。
対して、common lispの場合は、ダブルクォート(#\")で囲む方法しかない。
大抵の場合はそれでも十分なのだが、たまに#\"や#\\をエスケープしないで多用したいことがある。
なので、そのためのリードマクロを書いてみる。
;; 文字列読み込み ;; numは、streamの最初の何文字を引用符として使用するかを指定 ;; ex. num=1,!string!; num=2,_!string!_ (defun read-quot (stream num) (let ((quots (loop for i from 1 to num collect #1=(read-char stream)))) (do ((acc (list #1#) (cons #1# acc))) ((every #'char= quots acc) (coerce (nreverse (nthcdr (length quots) acc)) 'string))))) ;; リードマクロ (set-dispatch-macro-character #\# #\q (lambda (stream chr num) (declare (ignore chr)) (read-quot stream (or num 1)))) ;; 実行例 > #q!c:\windows\system32\"file1"! --> "c:\\windows\\system32\\\"file1\"" > #2q__c:\windows\system32\f_i_l_e__ --> "c:\\windows\\system32\\f_i_l_e"
案外簡単にできた。
問題は、この表記をデフォルトではemacs(のlisp-mode)が文字列として認識してくれないことだろう。これは今回の例に限らず、マクロ・リードマクロ全般に付随する問題だけど..