こんにちは、鈴木です。
「C言語からGaucheを使おう!」シリーズです。
前回の「C言語からGaucheを使おう! (8) Scm_LoadFromPortでloadする」では文字列リテラルから入力ポートを作成し、そこから load する方法を調べました。
今回はファイルに保存された Scheme コードを読み込む方法を調べます。
Scm_Load 関数
まずは Scheme コードをファイルに保存しておきます。
カレントディレクトリに a.scm というファイルを作成し、以下の内容を記述します。
| 1 2 3 4 5 | (define sum (lambda (xs)     (apply + xs))) (define average (lambda (xs)     (/ (sum xs) (length xs)))) | 
合計を求める手続き sum と、平均を求める手続き average を定義しています。
a.scm を読み込むには、以下のようにします。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include <stdio.h> #include <gauche.h> /**  * ScmEvalPacket や ScmLoadPacket に含まれる例外情報を表示します.   */ #define PRINT_EXCEPTION(packet) \     printf("[%s] %s\n", \            SCM_STRING_CONST_CSTRING(Scm_ConditionTypeName(packet.exception)), \            SCM_STRING_CONST_CSTRING(Scm_ConditionMessage(packet.exception))); void load() {     ScmLoadPacket load_packet;     Scm_AddLoadPath(".", TRUE);     if(Scm_Load("a.scm", 0, &load_packet) < 0) {         PRINT_EXCEPTION(load_packet);         return;     } } void apply_something() {     ScmObj procedure;     ScmObj arguments;     ScmEvalPacket eval_packet;     /* (apply sum '((1 2 3))) */     procedure = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("sum")), SCM_BINDING_STAY_IN_MODULE);     arguments = SCM_LIST1(SCM_LIST3(SCM_MAKE_INT(1), SCM_MAKE_INT(2), SCM_MAKE_INT(3)));     if(Scm_Apply(procedure, arguments, &eval_packet) < 0) {         PRINT_EXCEPTION(eval_packet);         return;     }        Scm_Printf(SCM_CUROUT, "%S\n", eval_packet.results[0]);     /* (apply average '((1 2 3))) */     procedure = Scm_GlobalVariableRef(Scm_UserModule(), SCM_SYMBOL(SCM_INTERN("average")), SCM_BINDING_STAY_IN_MODULE);     arguments = SCM_LIST1(SCM_LIST3(SCM_MAKE_INT(1), SCM_MAKE_INT(2), SCM_MAKE_INT(3)));     if(Scm_Apply(procedure, arguments, &eval_packet) < 0) {         PRINT_EXCEPTION(eval_packet);         return;     }     Scm_Printf(SCM_CUROUT, "%S\n", eval_packet.results[0]); } int main() {     GC_INIT();     Scm_Init(GAUCHE_SIGNATURE);     load();     apply_something();     return 0; } | 
内容は「C言語からGaucheを使おう! (8) Scm_LoadFromPortでloadする」のサンプルコードとほとんど同じで、sample_load_from_port 関数が sample_load 関数に変わっているだけです。
実行すると、以下の結果が得られます。(※「C言語からGaucheを使おう! (1) コンパイル環境を整える」で作成した Makefile を使用します)
| 1 2 3 | > make run 6 2 | 
前回同様、出力の 1 行目は「(apply sum '((1 2 3)))」の結果、2 行目が「(apply average '((1 2 3)))」の結果です。
load 関数
load 関数を詳しく見ていきましょう。
| 1 2 3 4 5 6 7 8 9 10 11 | void load() {     ScmLoadPacket load_packet;     Scm_AddLoadPath(".", TRUE);     if(Scm_Load("a.scm", 0, &load_packet) < 0) {         PRINT_EXCEPTION(load_packet);         return;     }    } | 
まず、Scm_AddLoadPath 関数でカレントディレクトリをロードパスに追加しています(初期状態ではカレントディレクトリはロードパスに含まれていません)。
次に Scm_Load 関数を用いて、先ほど作成した a.scm を読み込んでいます。
まとめ
今回はファイルとして保存されている Scheme プログラムを読み込む方法を調べました。
今までの内容で Gauche を組み込み言語として使うための準備が整いました。
C 言語で拡張できる他の言語(Ruby や Python、Java など)にも Gauche を組み込めるということですね。

 
						