libオブジェクト

他のファイルに書かれたライブラリを読み込みたい。
(Cでいうinlcude、Rubyでいうrequire、Pythonでいうimportがしたい)

そんな時には libオブジェクト を使います。

libオブジェクトは特殊なオブジェクトで、lib::foo とアクセスした場合、foo.xtalを読み、そこでexportされた値を返す機能を持ってます。

 // foo.xtal
 export "文字列をexportしました";
 // test.xtal
 foo : lib::foo; // ここでfoo.xtalがコンパイルされ、実行される

 println(foo); // => 文字列をexportしました

lib::fooと書けばその度に何回もコンパイル、実行されるわけではなく、最初の実行で値は保存されるため、2回目以降は保存された値が返ります。
組み込み関数でload関数が用意されているので、それを使えば何度でもコンパイル、実行ができます。

 load("foo.xtal");

libオブジェクトは階層にも対応しています。

 // folder/bar.xtalをコンパイル、実行してexportされた値を取り出す
 bar : lib::folder::bar; 

また、libオブジェクトにプログラムから登録することもできます。
登録の構文は、クラスやモジュールにメンバを追加定義するのとまったく同じです。

 lib::hoge : "register";

 // lib::hogeはもう格納されているため、hoge.xtalファイルは探されない
 println(lib::hoge); // => register

 // error! classやmodule同様、libオブジェクトも再定義を認めない
 lib::hoge : "once more"; 

 // 次の文はそもそもコンパイルできない。代入の左辺にメンバ参照式は許可されない。
 // lib::hoge = "once more"; 

libがファイルの検索を開始するパスは builtin::lib_path に配列として格納されています。
ここにパスを追加すれば、そのパスも検索対象となります。

 lib_path.push_back("c:/hoge/huge");
 println(lib_path.join(", ")); // => ., c:/hoge/huge

この状態で lib::foo と書くと
./foo.xtal、 c:/hoge/huge/foo.xtalと検索されて、最初に見つかったものがコンパイル、実行されます。