Clover2開発日誌

Clover2というJavaのように静的な型を持つRubyのようなコンパイラ+仮想マシンの開発日誌です。LLVMでJITもします。https://github.com/ab25cqにて開発しています

シェルのような記述

Commandクラスのメソッドが一つだけの場合シェルのような記述を許すようにしました。

 

> ls -al src/main.c

-rw-rw-r--. 1 ab25cq ab25cq 1098  9月 18 08:01 src/main.c

> vim src/main.c

などです。まだiclover2でのファイル名の補完は出来ませんが明日以降補完ができるようにします。

 

あとJITでclosureを使うとローカル変数がおかしくなるバグが見つかっています。(code/block5.clでテストしていますがテストが失敗します)

 

明日以降修正します。

 

とりあえず、しばらくはバグを修正したりもしますが、インタプリタの使い勝手を良くする作業をします。

もともとClover2を作り始めた理由はシェルの代わりになる物が作りたいという動機でした。シェルってもう古臭くないですか?xyzshというRubyのようなコマンドが使えるシェルやmfiler2, mfiler3, mfiler4というCUIファイラを作っていた理由もそれでした。その過程で思ったのはJavaIDEのような補完があるインタプリタがあればシェルの代わりに使えるのではないかということでした。それを実現するためインタプリタをしばらく改良します。

自分でもシェルの代わりにiclover2を使ってClover2の開発をしたいと思います(再帰開発)

 

自分で使ってみるClover2も楽しみです。それでは。満足する物が作れたらversion 3.1としてリリースしたいと思います。

メソッドの引数になるブロックオブジェクトの糖衣構文を入れました。

3.times() { println("HO!"); }

 

sum := 0;

list { 1,2,3 }.each() { |n:Integer| sum += n }

 

などを入れました。

型推論

ブロックオブジェクトで戻り値の型を省略した場合、returnされる値によって型推論されるようになりました。ただ、Clover2の場合boxingやunboxing、プリミティブ型やユーザークラスなどがあるので、それほど便利ではありません。例えばList.mapメソッドのブロックオブジェクトの戻り値にAnonymousクラスと記述しないと、boxingされません。結局toIntegerなどと型変換のスペシャルメソッドを呼ばないといけないため期待されるほど記述が減るわけでは無いです。まあ、とりあえず、入れただけです。

 

後はAnonymousクラスにはcast("bool")などキャストスペシャルメソッドを作りました。ちょっと自分でClover2を使ってみたんですがAnonymousクラスが使いづらかったためです。

 

テスト中仮想マシンがSegmentation Faultするなど、まだまだシステムが不安定なため、しばらく機能拡張よりもデバッグに専念します。

 

ユーザーの皆様も、もしバグを見つけたらgithubのab25cq宛にメッセージを送っていただけると助かります。すぐに対応させて貰いたいと思います。フィードバックよろしく、お願いします。

 

自分で使ってみた印象ですが、ブロックオブジェクトを書くのが凄くめんどくさいため、ブロックオブジェクトが一つだけの引数の場合Rubyのような記述ができるような糖衣構文を入れたいと思います。

今日中にやってしまうかもしれません。

 

3.times() { println("HO!"); }

3.times(lambda() { println("HO!") });

と同じ記述ってことにしますかね。そのままRubyですが、、、、。

 

引数がある場合もRubyと同じ記述にしていまいます。

あとlist { 1, 2, 3 }とかもかなり記述が面倒くさいんですよね。Ruby風の方が良いんでしょうね。

なんか全体的に記述が面倒くさい気がします。

型チェックの厳密性はそのままにもう少し記述が楽にできるように工夫してみます。型チェックの厳密性は維持します。型チェックを甘くするとシステムが不安定になるので。

それだけ今日やってみますかね。

関数が定義できるようになりました。

メインスクリプトやメソッドの中などで、def fun(a:int): int { return a * 2 } などと書くと関数が定義できます。

 

内部的には単にブロックオブジェクトをローカル変数funに代入しただけのものです。特に関数オブジェクトってわけじゃないです。単なるlambdaブロックオブジェクトです。

拡張ライブラリを作れるようになりました。

dlopen, dlsym, dlcloseなどダイナミックライブラリ関連のシステムコールを用意しました。クラスのinitialize():staticで、これらとnative methodの登録用のメソッドを使うと拡張ライブラリが作れます。

詳しくはwikiに書きますので見てください。もしくはcode/ext.clcとcode/ext.cl, ext/hello.cを見てください。C言語での関数の書き方はsrc/class_system.cが参考になると思います。

対話的なプログラムの実行で複数行対応

> 1+1; 2*3

2

6

などと期待通りに動くようになりました。(今までは1行のみしか対応していなかった)

JITでインタプリタ

./configure --with-jit --with-interpreterでバグがあったので修正しました。

 

インタプリタでもJITできます。すみません。バグに気づきませんでした。