#はじめに
Easy-ISLisp(以下「EISL」)にはC言語を取り込む、Cラッパがコンパイラに組み込まれています。これを使うとC言語の機能をフルに使うことができます。使い方の例としてビット演算をする関数の書き方をご紹介します。
#Cラッパ
EISLのコンパイラはISLispのコードをGCCのCコードに変換する方式に拠っています。CラッパはここにCのソースを直接に記述するものです。下記の特殊形式を用意してあります。
(c-include x) #include x に変換される
(c-option x) コンパイルとのきのオプションにxを追加する。
(c-lang x) C言語ソースに文字列xを挿入する。
#ビット演算の例
Cラッパを利用するとCommonLispのash関数は次のように記述できます。
(c-include "<stdio.h>")
(defun ash (n m)
(if (>= m 0)
(c-lang "res = INT_FLAG | ((INT_MASK & N) << (INT_MASK & M));")
(let ((m1 (- m)))
(c-lang "res = INT_FLAG | ((INT_MASK & N) >> (INT_MASK & M1));"))))
#実行例
eisl -c compiler.lsp
Easy-ISLisp Ver0.91
> (compile-file "bit.lsp")
type inference
initialize
pass1
pass2
compiling ASH
finalize
invoke GCC
T
> (load "bit.o")
T
> (ash 5 -2)
1
> (ash 5 -1)
2
> (ash (+ 5 2) -2)
1
> (ash 10 2)
40
>
#補足説明
変数はすべて大文字に変換されています。このためn,m変数はC言語ではN,Mとなります。
小整数は効率化のために即値となっています。最上位から2番目のビットを立てることにより内部的に小整数と認識されます。C言語の演算子を使う場合にはこのビットが邪魔になります。そこでINT_MASKとのANDをとりそのビットを下ろしています。Cでの演算が終了した場合には即値に戻さないといけません。これはINT_FLAGとのORをとることにより第二ビットを立てています。これらの値はfast.hに記述してあります。
S式の返り値はC言語内ではresという変数が保持しています。resに値を代入します。
#ラズパイでの利用
EISLは主にラズパイでの利用を想定しています。C言語による細かな操作や、WiringPIのようなCライブラリが必要なときはこのCラッパを使うことにより容易にCの機能を取り込むことができます。
#リポジトリ
EISLは現在OSSとなり、GitHubにて公開されています。BSDライセンスです。
https://github.com/sasagawa888/eisl