LoginSignup
0
1

More than 5 years have passed since last update.

Easy-ISLispでビット演算

Last updated at Posted at 2019-03-10

はじめに

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

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1