LoginSignup
5
3

More than 3 years have passed since last update.

ElixirでLisp遊び

Last updated at Posted at 2019-07-20

はじめに

ElixirでLispインタプリタを書きました。実用性はまったくありません。楽しいお遊びです。

使い方

mixで作ってあります。巻末のGithubからダウンロードあるいはクローンを作って mix lisp と入力すると起動します。


$ mix lisp
Compiling 1 file (.ex)
Lisp in Elixir
? (+ 1 2)
3
? (setq a 3)
3
?


処理系を終了するときは (quit)です。

仕様

ダイナミックスコープです。
使える特殊形式はdefunとsetq、quote,ifです。'がquoteの代わりになります。
defunでの暗黙のprognは使えません。
使える組み込み関数は下記の通りです。
+ - * / = > < >= <=
car cdr cons eq null atom numberp listp symbolp read eval print

プログラム構造、データ構造

4つのモジュールから成ります。Lisp、Read、Eval、Printのモジュールです。Lispには全体をとりまとめたREPLが収録されています。残りのモジュールはその名の通り、read,eval,printの各コードを収録しています。

readはS式を読み込みElixirのデータに変換して返します。そのデータの他に読み込み途中のバッファも返します。Tupleにして{sexp,buf}のようにしています。sexpは読み込んだものをElixirデータに変換したものです。リストであれば (+ 1 2) -> [:+,1,2] のようになります。bufは未読み込みのトークンのリストです。

evalはElixirのデータ型に変換されたs式を評価します。環境を常時、保持します。環境はキーワードリストの形式です。evalは評価した値をtupleにして{sexp,env}のようにして返します。

defunにより定義された関数は {:func,name,args,body} の形式のTupleになっています。これは環境に保持されます。

readのbuf,evalのenvはREPLループの間で保持されます。関数型のElixirでは大域変数を持ちません。このためbuf,envは引数として持ちまわるようにしてあります。

お気に召すまま

Elixirのコードは500行程度です。とてもシンプルです。あとはマクロを実装するなり、レキシカルスコープにするなり、M式対応にするなり、皆様、お気に召すまま改造してお楽しみください。BSDライセンスです。

ソースコード

ここに置いてあります。

5
3
2

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
5
3