C# による L2 Lisp の実装

2008.7.18 - 2008.8.28 (鈴)

1. はじめに

L2 Lisp 7.2L2 Lisp 7.3 をベースとして C# 上に L2 Lisp を実装した。 C# 2.0 の仕様にもとづいて Mac OS X 10.4.11 上の Mono 1.9.1 で作成し,同環境および Windows 2000/XP 上の .NET Framework で構築でき,動作することを確かめた。 当然期待されるように python (+ psyco) 上の L2 Lisp 7.2,ruby 上の L2 Lisp 7.3 よりも高速に動作する。

Lib_Reader.csLib_Types.csyield return 文を使ってイテレータを定義したり, Lib_Funcs.csPreludeExtra.cs で C# のメソッドにカスタム属性を付け,リフレクションにより自動的に Lisp の関数として delegate 化するなど, C# の学習者にとって興味深い技術のデモンストレーションとして,このプログラムを読むことができる。

Lisp 言語としては L2 Lisp 7.2,7.3 とほとんど同じだが,多倍長整数をサポートしない点で異なる。 これは C# 2.0 とその標準ライブラリが多倍長整数をサポートしないことによる。 整数は int (つまり System.Int32), 実数は double (つまり System.Double) によって表現される。 この非互換性により 7.4 版ではなく 8.0 版とした。

7月17日に作成した 8.0 版にいくつかの問題が発見されたため,さらに 8.1 版に改訂した。 Reader クラスの IDisposable 化とそれによる Interp クラス Run メソッドでの確実な資源解放, Lisp 関数 (cs-self) の追加,LL.List, LL.MapCar の効率改善,つづり間違いの訂正,使われていないメソッドの整理が改訂点である。

8月1日に作成した 8.1 版には字句解析時のエラー処理に不備があったため,8.2 版に改訂した。 実質的な変更ファイルは Lib_Reader.cs である。 Mac OS X 10.4.11 では Mono 2.0_0 でバイナリを構築し,実行した。

Mono 2.0 のプレビュー版である Mono 2.0_0 は,バイナリの構築と実行はできますが,make doc で HTML ドキュメントの作成をしたとき,monodocs2html コマンドが途中で停止してしまう模様です。

1.1 使い方

l2lisp-8.2-bin.zip を展開し,L2Lisp.exe を実行する (Windows XP ならば,すべて GUI で操作できる)。 Mac OS X などに Mono をインストールして動かす場合は,mono コマンドの引数として L2Lisp.exe のパス名を与える。

$ unzip l2lisp-8.2-bin.zip
Archive:  l2lisp-8.2-bin.zip
   creating: l2lisp-8.2/
  inflating: l2lisp-8.2/Copyright.txt  
  inflating: l2lisp-8.2/Help.txt     
  inflating: l2lisp-8.2/L2Lisp.exe   
  inflating: l2lisp-8.2/L2LispLib.dll  
  inflating: l2lisp-8.2/Prelude.l    
  inflating: l2lisp-8.2/PreludeExtra.dll  
$ mono l2lisp-8.2/L2Lisp.exe
> 

EOF 文字の打鍵,または (exit) 関数の実行で終了する。

> (exit)
$ 
Mac OS X 上の Mono 1.9.1_3,Mono 2.0_0 では Control-D でも Control-Z でも EOF 文字の打鍵にはならないようです。

ファイル名を与えると Lisp スクリプトとして非対話的に実行する。 ハイフン - を与えると対話セッションに入る。 例えば下記のように 8queens.l とハイフンを与えると, 8queens.l を実行した後,そのまま対話セッションに入る。 8queens.l で定義された関数を呼び出すことができる。

$ mono l2lisp-8.2/L2Lisp.exe 8queens.l -
92
> (nqueens 4)
((3 1 4 2) (2 4 1 3))
> (nqueens 6)
((5 3 1 6 4 2) (4 1 5 2 6 3) (3 6 2 5 1 4) (2 4 6 1 3 5))
> 
つまり,今までの L2 Lisp と同じです。 Mono 環境では mono コマンドを使う,という点だけ注意します。

l2lisp-8.2 ディレクトリに展開された L2Lisp.exe 以外の五つのファイルは必ず L2Lisp.exe と同じディレクトリに置く。 そうする限り,どこに置いてもよい。

L2LispLib.dll はプライベート・アセンブリとして L2Lisp.exe と同じディレクトリに置く必要があります。 他の四つのファイルは Assembly.GetEntryAssembly() の戻り値の Location プロパティを使って参照するディレクトリを決定していますから,やはり同じディレクトリに置く必要があります。
ディレクトリを決定するコードについては Lib_Types.csL2Lisp.LL クラスにある PathTo メソッドを見てください。


目次へ 2.へ


Copyright (c) 2008 OKI Software Co., Ltd.