* Menu
- 2010-02-28 :
- 2010-01-20
- 2008-11-17 :
- 2008-07-18 :
- 2008-04-22 : (ni-view xyzzy:*packages*) の件
- Common Lisp : xmls & s-xml と日本語
- 2008-03-06 :
- Common Lisp : 文字列中のエスケープシーケンスを解釈する
- 2008-03-02 :
- memo : asdf を使う
- 2008-02-25 :
- 2008-02-04 :
- 2008-02-04 :
- xyzzy : *do-completion の動作がおかしいという話 2
- xyzzy lisp : ミニバッファの入力にエスケープシーケンス
* 2010-02-28 :
- debian squeeze でsbclインストール後のコア作成に失敗していた。
- 以下がエラーメッセージ。
; #<PACKAGE "ASDF1"> ; registering #<SYSTEM SB-GROVEL {B4F1921}> as SB-GROVEL ; ; compilation unit aborted ; caught 1 fatal ERROR condition Error running init-common-lisp-controller-v4: Lock on package SB-IMPL violated when interning NATIVE-FILE-KIND. See also: The SBCL Manual, Node "Package Locks"
- 以下のように修正して解決した。
--- /usr/share/common-lisp/source/common-lisp-controller/post-sysdef-install.lisp~ 2010-02-28 17:58:19.000000000 +0900 +++ /usr/share/common-lisp/source/common-lisp-controller/post-sysdef-install.lisp 2010-02-28 18:01:36.000000000 +0900 @@ -61,7 +61,7 @@ #+sbcl (defun get-owner-and-mode (directory) (when (eq :directory - (sb-impl::native-file-kind (namestring directory))) + (sb-unix::unix-file-kind (namestring directory))) ;; check who owns it (multiple-value-bind (res dev ino mode nlink uid gid rdev size atime mtime) (sb-unix:unix-stat (namestring directory))で、以下を実行。
$ sudo dpkg-reconfigure common-lisp-controller
- http://git.debian.org/?p=pkg-common-lisp/common-lisp-controller.git;a=commit;h=7e511abe9551237095f395c2f75bb7f7aa580094
- squeeze でインストールされるsbclは今のところ 1.0.25 なんだけど、sb-unix::unix-file-kindがリネームされるのはこれ以降のバージョンなんじゃなかろうか。
* 2010-01-20
- Scheme コードバトン (CL fork)
- やったことは以下の通り。
- untabify
- format指示子を大文字に揃える
- インデントを調整
- 辞書が存在しない時の動作を修正
- package-nameがprintされないようにして、オリジナルの辞書と似た感じの出力を目指した
- asdfのパッケージ化
- lispの関数は10行越えると、理解が大変になってくる。修行が足りないなぁ
- xyzzy lispでforkしようかと思っていたけれど、ABCLの動作と似た感じになるだろうから、微妙。
diff --git a/package.lisp b/package.lisp new file mode 100644 index 0000000..3667c7a --- /dev/null +++ b/package.lisp @@ -0,0 +1,13 @@ +;; -*- Mode: Lisp; Syntax: Common-Lisp -*- + +;;; Package Management +(in-package :cl-user) + +(defpackage :hige + (:use :cl) + #+ABCL (:shadow :y-or-n-p) + (:export #:pin + #:pon + #:pun + #:pan + #:pen)) diff --git a/scheme_baton.asd b/scheme_baton.asd new file mode 100644 index 0000000..b2d9ce6 --- /dev/null +++ b/scheme_baton.asd @@ -0,0 +1,4 @@ +(defsystem :scheme_baton + :serial t + :components ((:file "package") (:file "scheme_baton")) + ) diff --git a/scheme_baton.lisp b/scheme_baton.lisp index 27713dc..fc50ad7 100644 --- a/scheme_baton.lisp +++ b/scheme_baton.lisp @@ -53,6 +53,7 @@ ;; 8. masatoi (http://d.hatena.ne.jp/masatoi/): n択問題(hige:pen)を実装.英単語から意味を問うのと意味から英単語を問うのと選べる.named-let使いまくり. ;; 9. cranebird (http://d.hatena.ne.jp/cranebird/): CL と言えばマルチパラダイムなので CLOS を。with-系のマクロを追加。 ;; 10. smeghead (http://d.hatena.ne.jp/smeghead/): 単語のスコアを導入した。問題の単語表示時にスコアを表示するようにした。単語の一覧表示(hige:pun)にキーワード引数 score-thresholdを追加。 +;; 11. NANRI (http://raido.sakura.ne.jp/southly/rn/): デバッグとちょっとした整理。あと (asdf:oos 'asdf:load-op :scheme_baton) でロードできるようにした。 ;; ;; ================================================================================================================================================= ;; これより下がコードとその説明 - 変更・削除歓迎 @@ -79,18 +80,6 @@ ;; ■辞書ファイルの例 ;; http://gist.github.com/273424 -;;; Package Management -(in-package :cl-user) - -(defpackage :hige - (:use :cl) - #+ABCL (:shadow :y-or-n-p) - (:export #:pin - #:pon - #:pun - #:pan - #:pen)) - (in-package :hige) ;;quek-san's http://read-eval-print.blogspot.com/2009/04/abcl-java.html without cl-ppcre @@ -177,25 +166,25 @@ (format *debug-io* "done~%")) *dict*)) -(defmacro with-entries ((entry) &rest body) +(defmacro do-entries ((entry) &rest body) `(dolist (,entry (entries-of *dict*)) ,@body)) ;;; Top-Level Functions (defun pin () "Register new entries to the dictionary." - (unless *dict-file* - (ensure-directories-exist *dict-file*)) (with-dict () - (loop (add-entry (prompt-for-entry)) - (if (not (y-or-n-p "Another words to register? [yn]: ")) (return))))) + (loop + (add-entry (prompt-for-entry)) + (unless (y-or-n-p "Another words to register? [yn]: ") + (return))))) (defun pon () "Start self-study english vocabulary quiz." (with-dict () - (with-entries (e) + (do-entries (e) (p "~&~A (score: ~D): " (read-aloud (entry-word e)) (entry-score e)) - (ready?) + #-ABCL (ready?) #-ABCL (p "~&~A [Ynq]: " (entry-meaning e)) :again (case (query #+ABCL (entry-meaning e)) @@ -209,12 +198,12 @@ (defun pan () "Search the word user has input from the dictionary" (with-dict (:read-only t) - (let ((word (intern (prompt-read "Word to search") :hige))) + (let ((word (intern (prompt-read "Word to search") #.*package*))) (format t "~A" (or (search-dict word) "Not found."))))) (defun pun (&key score-threshold) - (if (and score-threshold - (not (numberp score-threshold))) + (when (and score-threshold + (not (numberp score-threshold))) (error "pun: score-threshold must be number.")) (setup-dict) (dump-dict :score-threshold score-threshold)) @@ -226,7 +215,7 @@ (with-dict () (when (> n-choice (length (entries-of *dict*))) ; 辞書の長さチェック (error "Dictionary size is too small .~%")) - (with-entries (e) + (do-entries (e) (p "~&~A (score: ~D): " (if meaning? (entry-meaning e) (read-aloud (entry-word e))) (entry-score e)) @@ -239,13 +228,15 @@ :do (p "~A.~A " i (if meaning? (entry-word item) (entry-meaning item)))) (p " [1-~Aq]: " n-choice) (nlet itr ((query (read *query-io* nil nil))) - (cond ((and (numberp query) (> query 0) (> (1+ n-choice) query)) + (cond ((and (numberp query) (< 0 query (1+ n-choice))) (if (= query correct-answer) (incf (entry-ok-count e)) (incf (entry-ng-count e)))) - ((and (symbolp query) (string= (symbol-name query) "Q")) (return)) - (t (p "~&Please type number of the choice or Q for quit.~%[1-3q]: ") - (itr (read *query-io* nil nil))))))))) + ((and (symbolp query) (string= (symbol-name query) "Q")) + (return)) + (t + (p "~&Please type number of the choice or Q for quit.~%[1-3q]: ") + (itr (read *query-io* nil nil))))))))) ;;; Auxiliary Functions (defun setup-dict (&key (fn #'sort-dict-standard) (file *dict-file*)) @@ -261,36 +252,51 @@ (mapcar #'(lambda (e) (make-entry :word (entry-word e) :meaning (entry-meaning e) - :ok-count (or (entry-ok-count e) 0) - :ng-count (or (entry-ng-count e) 0))) + :ok-count (or (ignore-errors (entry-ok-count e)) 0) + :ng-count (or (ignore-errors (entry-ng-count e)) 0))) entries)) +(defmacro with-dictionary-io-syntax (&body body) + `(with-standard-io-syntax + (let ((*readtable* (copy-readtable nil)) + (*package* #.*package*) ; 単語Symbolのホームは:higeパッケージです。 + (*read-eval* nil)) + (setf (readtable-case *readtable*) :preserve) ; 単語Symbolは大文字小文字を区別して扱います。 + ,@body))) + (defun read-dict (file) "Read dictionary data from a file." - (let ((*readtable* (copy-readtable nil)) - (*package* #.*package*)) ; 単語Symbolのホームは:higeパッケージです。 - (setf (readtable-case *readtable*) :preserve) ; 単語Symbolは大文字小文字を区別して扱います。 - (with-open-file (in file) - (normalize-dict - (loop :for word := (read in nil in) :until (eq word in) - :collect word))))) + (unless (probe-file file) + (return-from read-dict NIL)) + (with-open-file (in file) + (with-dictionary-io-syntax + (normalize-dict + (loop :for word := (read in nil in) :until (eq word in) + :collect word))))) (defun save-dict (&key (file *dict-file*)) "Save the dictionary data into a file." - (with-open-file (out file :direction :output :if-exists :supersede) - (with-standard-io-syntax - (dolist (word (entries-of *dict*)) (print word out))))) + (unless (probe-file file) + (ensure-directories-exist file)) + (with-open-file (out file + :direction :output + :if-exists :supersede + :if-does-not-exist :create) + (with-dictionary-io-syntax + (let ((*package* #.*package*)) + (dolist (word (entries-of *dict*)) (print word out)))))) (defun dump-dict (&key score-threshold) "Print the dictionary in CSV format." (let ((output (format nil "~{~{~A~^,~}~%~}" (if (null score-threshold) - (entries-of *dict*) ;score-thresholdが指定されない場合は全件 - (remove nil ;score-thresholdが指定された場合は絞り込む - (mapcar (lambda (e) - (if (<= (entry-score e) score-threshold) - e)) - (entries-of *dict*))))))) + (entries-of *dict*) ; score-thresholdが指定されない場合は全件 + (delete NIL ; score-thresholdが指定された場合は絞り込む + (mapcar (lambda (e) + (if (<= (entry-score e) score-threshold) + e + NIL)) + (entries-of *dict*))))))) #-ABCL (format t "~A" output) #+ABCL (|showMessageDialog| |javax.swing.JOptionPane| nil output))) @@ -324,7 +330,6 @@ (1 #\N) (2 #\Q))) - (defun prompt-read (prompt) #-ABCL (progn (p "~A: " prompt)
* 2008-11-17 :
- CLOCC の f2cl パッケージに BLAS と LAPACK があるのを見つけたので、試してみた。
- 結果: 動かなかった。
- sbcl の場合、FORTRANのソース内で変数名がTのところの、変数の型が違うとエラーが出る。
- でも、FORTRANのソースからトランスレートされたlispのソース内では「t$」になっていて、変数がTの所は見当たらず。(dlamach.f, dlamach.lisp)
- clisp の場合、ちょっと手を入れてロードまで成功。
- テストを動かしてみると何故か zero division error。
- よく分からないので放置。
* 2008-07-18 :
- いろいろと TODO を消化。
- 自宅で Windows 機に触る機会が減ってるから、いろいろと滞ってるな。
- CodeRepos にあるものを packaged-xyzzy に収録できたな。次回くらいに。
* 2008-04-22 : (ni-view xyzzy:*packages*) の件
- 974氏、多謝。直しました。
- なぜかはよく分かりませんが、302 Found が返ってきたものがあって read できないデータが保存されていました。
- 見れなくなるのはまずいので、readできないファイルができたら読み飛ばすようにでもしておきます。
* Common Lisp : xmls & s-xml と日本語
xmls で日本語を出力するには、write-escaped を修正する。
例えば以下のような感じ。
s-xml の場合は print-string-xml に手を入れればいいと思う。
が、どの範囲をそのまま出力するようにするかが悩ましい。
UTF-8で出力することが前提ならなら ASCII 以上は全部でも良いとは思うけど、文字コード・文字集合辺りはよく分からないなあ。(上のはASCII以上全部になっているし)
例えば以下のような感じ。
(in-package :xmls) (defun write-escaped (string stream) "Writes string to stream with all character entities escaped." (coerce string 'simple-base-string) (when (eq stream t) (setf stream *standard-output*)) (loop for char across string for esc = (if (< (char-code char) (length *char-escapes*)) (svref *char-escapes* (char-code char)) (string char)) do (write-sequence esc stream)))ただ、xmls で出力した xml はあんまり見慣れない書き方になるみたいなので使わない気がする。
s-xml の場合は print-string-xml に手を入れればいいと思う。
が、どの範囲をそのまま出力するようにするかが悩ましい。
UTF-8で出力することが前提ならなら ASCII 以上は全部でも良いとは思うけど、文字コード・文字集合辺りはよく分からないなあ。(上のはASCII以上全部になっているし)
* 2008-03-06 :
* Common Lisp : 文字列中のエスケープシーケンスを解釈する
とりあえずできた。REPL では動作確認できた。
要 cl-interpol。
SANO さんの情報がなかったらどうにか interpol-reader を使えないか、悩んでいたかも。サンクスです。
(ReadMore...)
要 cl-interpol。
SANO さんの情報がなかったらどうにか interpol-reader を使えないか、悩んでいたかも。サンクスです。
(ReadMore...)
* 2008-03-02 :
- (ni-view xyzzy:*packages*) を更新
- http://raido.sakura.ne.jp/southly/lisp/ni/view.lisp
- 各アプリごとのページが見れるようにした。
- エスケープシーケンスの情報が read 時点で落ちているな。Common Lisp にはないもんな。うまく読むにはどうしたら良いんだろ。
- その他 TODO
- hook を仕込んで情報の訂正・追加ができるようにする。
- rss & atom の出力
* memo : asdf を使う
さくらのサーバにインストールした clisp で asdf を使うための一連の作業をメモ。
clisp には asdf が付属していないのでソースを取得する。
ついでにコンパイルしておく。
ここからしばらく clisp での作業。
$HOME/local/lisp/ を lisp ファイル置き場にすることにしたので、ここをロードパスに追加する。
asdf.lisp をロード。
asdf:*central-registry* にパスを追加。$HOME/local/lisp/systems/ にした。
ここに *.asd ファイルへのシンボリックリンクを置くようにする。
この状態でGUESSを使えるようにする。
ソースをダウンロードして、展開、シンボリックリンクを張る。
clisp でロード。初回はコンパイルした上でロードしてくれる。
clisp での作業は初期化ファイルにでも書いておく。clispの場合は $HOME/.clisprc 辺り。
clisp には asdf が付属していないのでソースを取得する。
$ cd $HOME/local/lisp $ wget "http://cclan.cvs.sourceforge.net/*checkout*/cclan/asdf/asdf.lisp" $ clisp -c asdf.lisp
ついでにコンパイルしておく。
ここからしばらく clisp での作業。
$HOME/local/lisp/ を lisp ファイル置き場にすることにしたので、ここをロードパスに追加する。
[1]> (push (merge-pathnames "local/lisp/" (user-homedir-pathname)) custom:*load-paths*) (#P"/home/raido/local/lisp/" #P"./" "~/lisp/**/")
asdf.lisp をロード。
[2]> (load '#:asdf) ;; Loading file /home/raido/local/lisp/asdf.fas ... ;; Loaded file /home/raido/local/lisp/asdf.fas T
asdf:*central-registry* にパスを追加。$HOME/local/lisp/systems/ にした。
ここに *.asd ファイルへのシンボリックリンクを置くようにする。
[3]> (push (merge-pathnames "local/lisp/systems/" (user-homedir-pathname)) asdf:*central-registry*) (#P"/home/raido/local/lisp/systems/" *DEFAULT-PATHNAME-DEFAULTS*)
この状態でGUESSを使えるようにする。
ソースをダウンロードして、展開、シンボリックリンクを張る。
$ cd $HOME/local/src/lisp $ wget http://lispuser.net/files/guess.tar.gz $ tar xf guess.tar.gz $ cd ../../lisp/systems/ $ ln -s $HOME/local/src/lisp/guess_0.1.0/guess.asd .
clisp でロード。初回はコンパイルした上でロードしてくれる。
[4]> (asdf:oos 'asdf:load-op :guess) ; loading system definition from /home/raido/local/lisp/systems/guess.asd into #<PACKAGE ASDF0> ;; Loading file /home/raido/local/lisp/systems/guess.asd ... ; registering #<SYSTEM :GUESS #x20538B31> as GUESS ;; Loaded file /home/raido/local/lisp/systems/guess.asd ;; Compiling file /home/raido/local/src/lisp/guess_0.1.0/guess.lisp ... ;; Wrote file /home/raido/local/src/lisp/guess_0.1.0/guess.fas ;; Loading file /home/raido/local/src/lisp/guess_0.1.0/guess.fas ... ;; Loaded file /home/raido/local/src/lisp/guess_0.1.0/guess.fas 0 errors, 0 warnings NIL以上。
clisp での作業は初期化ファイルにでも書いておく。clispの場合は $HOME/.clisprc 辺り。
(push (merge-pathnames "local/lisp/" (user-homedir-pathname)) custom:*load-paths*) (load '#:asdf) (push (merge-pathnames "local/lisp/systems/" (user-homedir-pathname)) asdf:*central-registry*) (asdf:oos 'asdf:load-op :guess)ロードするものが多くなって起動に時間がかかるようになったら、メモリイメージを保存して起動時にこっちを読み込むようにする。
* 2008-02-25 :
- Mercurial はなかなかよい感じかも。
- http://raido.sakura.ne.jp/southly/hgrepos/
- svn と干渉しないで使えるのが気楽だ。
- 認証はもう少し調べてからやることに。
- ID と password をどう共有するかも考えないといけないし。
- package の件
- trace マクロ
- Common Lisp いじっていると xyzzy でも欲しくなった。
- kia さんのとこにもあるのだけど encapsulate が関数なのが気になってマクロを書いてみることに。
- 思ってたより何とかなっている感じ。
- TODO : 引数の &optional etc の扱いを何とかする。
- Xyzzy Wiki
- 最近使いにくいッス。
- これを気をつければ spam フィルタに引っかからない、というのを教えていただきたいッス。
- (xyzzy :hack :-) - fixdap
- いい感じ。
- 他の参加者も発言してくれるともっといいのになぁ〜
- はてなダイアリーキーワードを編集できる人にお願い
- xyzzy の「Emacs Lisp ではなく Common Lisp を実装」→「Emacs Lisp ではなく Common Lisp をベースにした独自の Lisp 方言を実装」に変更。
- CommonLisp のフリーの処理系から xyzzy を外す。
- よく知らない人が xyzzy を Common Lisp 処理系として使うのは危ういので修正してもらえないかなと思います。
- いまさら気付いたので反応。> matsuokaさんとこ
- はい。私です。
- ちなみに ctags.l はあの時話題になっていたので調べてみただけで、使っていないんですよね (^^;
- 普段は XTAGS を使ってます。
* 2008-02-04 :
- uchardetを更新した。
- http://raido.sakura.ne.jp/southly/xyzzy/site-lisp/uchardet-20080204.lzh
- ソースを同梱していれば大丈夫そうだったので、DLLを入れることにした。
- 無駄にでかくなったがよかろう。
- packaged-xyzzy も更新。OHKUBOさんのを追加した。
- https://sourceforge.jp/projects/packaged-xyzzy/
- multiple-replaceはライセンスついていなかったんだなぁ〜
- 次はHIEさんのところかな。
* 2008-02-04 :
- うわっ、ほんとだ。clisp 2.44 出てるし。
- できたバイナリのタイムスタンプを見ると2日の朝になっているから、10数時間後に新しいバージョンが出たという感じみたい。
- FreeBSDのportsにlibsigsegv 2.5ができたくらいに再度ビルドしてみます。
- toggle-gatesはちょっと考えて、もうすでにgatesだしいいか〜ということでパスしました。一周したあとでまた考えるかもです。
- packaged-xyzzyの対象者として考えているのはNetInstallerを自力でセットアップできない人なんですよね。
- NetInstallerを使える人はそっちでやってもらった方が融通が利いていいと思っているので、siteinit.lを編集するというのは全く考慮してません。
- とは言いつつ、ライブラリは抜きやすいようにコメントを入れていますけど、実際抜けるかどうかは微妙だと思ってます。ライブラリの依存関係を把握しておかないといけないので。
- あのsiteinit.lはホームディレクトリに依存しないように特殊なことをやっているので、あんまり参考にして欲しくないかなあとか思ったり。
- siteinit.lを上書きされたくないってことであれば、packaged-xyzzyのsiteinit.lを $XYZZY/lisp/ に置くっていう手もありますが……
- どうしようかな〜
- ん? DLLの件は自分とこも関係あったのか?
- もうひとつ追加。zipじゃなくてlzhにしているのは好みッスね。
* xyzzy : *do-completion の動作がおかしいという話 2
なるほど。
そして、めも。
(*do-completion "quit" :list nil '("quit-recursive-edit" "quit-and-back" "quit-char" "quit" "quit")) =>:not-unique =>("quit" "quit" "quit-char" "quit-and-back" "quit-recursive-edit") =>nilこうなることを考えると do-completion-internal で対応するのがよさそう。
そして、めも。
If it is accessible as an internal symbol via use-package, it is first imported into package, then exported. (The symbol is then present in the package whether or not package continues to use the package through which the symbol was originally inherited.)CLHS: Function EXPORT: http://www.lisp.org/HyperSpec/Body/fun_export.html
* xyzzy lisp : ミニバッファの入力にエスケープシーケンス
interactive指定子を作っちゃえば楽に置き換えられるんじゃね?
ってことで、こんな。
ってことで、こんな。
(in-package "editor") (defun interactive-read-string-with-escape-sequence (prompt default history title) (list (decode-escape-sequence (read-string prompt :default default :history history) nil))) (pushnew '(#\w . interactive-read-string-with-escape-sequence) *interactive-specifier-alist* :test #'equal) (defun interactive-read-regexp-with-escape-sequence (prompt default history title) (list (decode-escape-sequence (read-string prompt :default default :history history) t))) (pushnew '(#\W . interactive-read-regexp-with-escape-sequence) *interactive-specifier-alist* :test #'equal) ;; こんな感じで使う ;; 文字列 (defun search-forward-wes (pattern &optional noerror) (interactive "wSearch forward: " :default0 *last-search-string* :history0 'search) (search-command pattern nil nil (interactive-p) noerror)) ;; 正規表現 (defun re-search-forward-wes (regexp &optional noerror) (interactive "WRe-search forward: " :default0 *last-search-regexp* :history0 'search) (search-command regexp nil t (interactive-p) noerror)) (export '(search-forward-wes re-search-forward-wes)) (in-package "user")