Windows10のAnniversary Updateで超クッソ激烈に面倒な状況になってしまい本来の作業が全然進まないので、その隙にyunibaseをアップデートした。いろいろとbacklogが有ったので纏めて。

yunibaseのディレクトリ構成を変更 yunibaseはyuniをビルドするように変更した。これはPicrinのyuniサポートコードをPicrinと同時にビルドする必要があるため。もともとそういう処理系が出現することは想定していたけど実際にはGambitのようにコンパイル済の.soを直接loadできたり、Gaucheやchibi-schemeのように組込みのC Extensionサポートが有ったりしたため必要性が生じてこなかった。 https://hub.docker.com/r/okuoku/yunibase/ Docker hubもちょっとドキュメントした。要するにyunibaseイメージにはビルド済の各種Scheme処理系(週1くらいでアップデート)とyuniが収録されており、dockerが使える環境であればこれをpullしてくることで直ぐにyuniライブラリを各種処理系で試すことができる。

... という環境を作っておかないとクロス処理系なライブラリってのはなかなか開発しづらいと思う。まぁyuni自体はまだ空なので今後内容を充実させていきたい。唯一実用的そうなのは本来R6RSのChezやVicareでR7RS smallライブラリが使えることか。まだパッケージャを用意していない & R6RSなんでREPLが無いのであんまり意味無いけど。

現状はyuni自体のCIくらいにしか用途が無いけど、例えばWebサーバを中で上げて各種処理系用のWeb REPLが有ると良いかな。。 https://microbadger.com/#/images/okuoku/yunibase 生成元のソースコードが解らなくなる問題は、Dockerのコンテナにメタデータを振ることで解決した。docker commitコマンドでイメージを作っているので、LABELは -c オプションで付与する必要があった。 https://github.com/okuoku/yunibase/blob/f64ee51fe0d5c7bb86aeecc8e0384286578bce47/hosts/docker-linux/docker-run-build.cmake#L52 yunibase自体はmacOSとかFreeBSDのような環境にも対応しているけど如何せんイメージの良い配布手段が無いし、イメージを配布したところでそれを受け入れる良いCIサービスが有るわけでもないのでどうするかは考え中。たぶんローカルに構築するのかな。。

ChickenとGambitでのFFI Rapid-GambitでGambitを使ってR7RSを実行できるようになったのでyuniFFIも移植してみた。...実はGambitとChickenは結構諸々の仕組みが似ているのでついでにChickenにも対応した。 Chicken: https://github.com/okuoku/yuni/blob/18683896761fb66adc60439e7b7816b37aabc160/yunistub/chicken/yuniffi-chicken.scm

Gambit: https://github.com/okuoku/yuni/blob/18683896761fb66adc60439e7b7816b37aabc160/yunistub/gambit/yuniffi-gambit.scm これで、C言語で実装された処理系のうちLarcenyを除く全部でyuniFFIが使えるようになった。 ...まだABIが決まってないので呼べるライブラリは無いけど。POSIXくらいはさっさとバインディングを用意したいところ。。

Chickenはforeign-lambda、Gambitはc-lambdaを使って、C言語コードを混ぜ書きする。GaucheやSagittariusのようなCソースジェネレータのある処理系と違って相当量のコードを文字列として書かないといけないのでちょっと辛い。いわゆるhere documentが有るとは言え、構文強調の類いは効かないんで。。

Gambitは処理系自体でbignumをサポートしているがChickenはそうではない(numbersモジュールの手続きを使用する必要がある - Cインターフェースから受けとる数値はnumbersの手続きで解釈できない)のでポインタを数値として直接Cコードとやりとりすることができない。Chickenの場合は、c-pointerとして専用の型が存在するのでそれを利用できる。意外なことに、bytevectorから直接c-pointerオブジェクトを生成する手段が存在しないため、yuniFFIとして自前で実装している。 ( define %%yuniffi-ptr64-ref/bv ( foreign-lambda* c-pointer (( nonnull-u8vector in ) ( size_t off )) "void* in0; in0 = in + off; C_return((void*)(uintptr_t)(*(uint64_t*)in0));" )) ChickenもScheme側のコードではbignumが使えるので特に苦労なく実装できた。Chicken、Gambitいづれもyuniのビルド時にそれぞれの処理系を使用しなければならなくなるが、これはGaucheやchibi-schemeのようなインタプリタでも(stubライブラリの生成に使うので)同様なのでこれといって追加の考察は必要なかった。