先に説明した動作モデルをごく単純化すると、「ゴールの選択」
「実行」
「ゴールの選択」...
という「ループ」であることがわかる。これをKLICのトップレベルループと
呼ぶ。このループは runtime/kmain.c内のtoploop関数により実現されている。
もう少し正確、詳細に解説すると、 モジュールはmodule型関数で実装されるが、この関数は以下のように動作する。 このモジュール型の関数はKLICのコンパイラで出力されるものであり、 ユーザが定義したモジュール、システムで定義されているモジュール各々に 一関数ずつある。
この関数が終了した後には、大域変数current_queueにその時の 実行可能queueの先頭がセットされているので、それをqpに戻し、 次のモジュールの実行を行う。
以下がmodule型関数を呼び出す toploop関数の全てである。
static void toploop()
{
declare_globals;
struct goalrec *qp = current_queue;
Const struct predicate *toppred = qp->pred;
module func = (module)toppred->func;
while (1) {
func = ((module (*)())func)(glbl, qp, heapp, toppred);
qp = current_queue;
toppred = qp->pred;
}
}
current_queueとあるのが(現在実行中の優先度の)実行可能ゴールスタックであり、 struct goalrecの線型リストとなっている。先頭をqpにとりだし、 述語レコード(struct predicate)をとりだし、モジュールを実現する関数 (func)をさらに取りだしている。そして、 その関数を呼びだすことを繰り返すwhileループに突入する。
ここで、module型関数の引数は以下のようになっている。
ページ)参照)