ENGLISH VERSION

GLOBALBASE PROJECT POWERED BY HIROHISA MORI
ホーム

GLOBALBASEとは? トピックス ダウンロード ドキュメント 実例とリンク
 
ver.B リリースノート
GLOBALBASEガイドブック
COSMOSマニュアル
LANDSCAPEマニュアル
開発情報
文献情報
GLOBALBASEマニュアル集 >> xl(standard)エージェント・リファレンス・マニュアル >> インタプリタ実行モデル
2007-11-04版

インタプリタ実行モデル

著者: 森 洋久 / joshua@globalbase.org  ※ 

* 概要
* [1] 評価
* [2] 関数
* [3] インタプリタのモデル
* [4] RemoteとLocal
* [5] エージェント
* [6] XLサーバ

概要

XLの関数の評価方法について述べる。

ページトップへ戻る

[1] 評価

プリミティブ関数の一つである評価関数Evalを、次のように定義する。

	(Eval environment-exp exp)
 

評価対象 ( exp)としては、あらゆる型を受け付ける。そして以下に示す通り、評価した結果を返す。このとき、Eval に与えられた環境 ( environment-exp)を評価対象のカレント環境と呼ぶ。
  1. 評価対象が、symbol以外の基本型の値の場合は、その値をそのまま返す。
  2. 評価対象が、symbolであった場合は、与えられた環境および、親環境、そのまた親環境と検索し、symbolに相当する変数が初めて見つかった時点で、対応した値を返す。検索に失敗したらエラーを返す。エラーはシステム構造型として後述する。
  3. 評価対象が、関数であった場合は、その値をそのまま返す。
  4. 評価対象が構造型であった場合、その最初のシンボル、あるいはタグに相当するシンボルを評価し、
    1. その評価結果が関数でも環境でもでなかった場合は、エラーを返す。
    2. その評価結果が環境の場合、その環境を親環境とした環境を新しく生 成し、これへカレント環境を変更する。この環境には、Localというシン ボルにまえのカレント環境をバインドする。
    3. その評価結果が関数であった場合は、関数がnormal-order か、 applicateive-orderかを判定、
    4. normal-order であれば、構造型の値、あるいは、要素をそのまま関数へ渡し、 関数そのものを実行し、結果を返す。
    5. applicative-order であれば、構造型の値の二項目以降あるいは、要素の中身を すべて評価し、これらを引数として関数に渡し、実行結果を返す。


ページトップへ戻る

[2] 関数

引数を与えると、それに対し所定に計算をし値を返す。関数を呼び出すときには、

	(func a b c)
 

または、

	<func> a b c </func>
 

あるいは、属性リストをつかい

	([func type="def"] a b c)

	<func type="def"> a b c </func>
 

というように、構造型を使う。この構造型全体を関数func への引数と呼び、func, a, b, cをそれぞれ、関数の1番目2番目.....の引数要素と呼ぶ。また、呼び出された側から、属性を参照する場合は、属性名に相当するシンボルを参照すればよい。

関数の引数の評価の仕方は、Normal と、Applicativeとの2種類がある。Normal では、引数は評価されずに、そのまま渡される。環境は渡される時に生成され、新しいカレント環境となる。引数を評価するかしないかは、関数を実行する中で明示的に決めたいときにこのオプションを選ぶ。

一方、Applicativeでは、引数は引数要素ごとに評価されてから渡される。引数評価のために、分岐環境が生成され、その一番目の親環境に関数定義時に定義した専用の環境がセットされ、第二番目の親環境に現在のカレント環境が設定される。評価する場合の環境の検索順序は関数定義時の環境、現在のカレント環境という順番になる。この仕組みは、

 	<SetAgent>
		"nichibun-agent"
		<User> hirohisa </User>
		<Passwd> abc </Passwd>
 	</SetAgent>
 

という呼び出しを考えたとき、User,Passwdを、SetAgent外部で使用したときと、別の処理をしたいときに有効である。評価用の環境でこの特殊な処理の関数を定義すればよい。つまり、以下のようにSequenceを使って新しい環境を定義してしようする。

	<Sequece>
		<Define> ^Env <CurrentEnvironment/> </Define>
		<Define> ^User
			()
			<Arguments> ^name </Argments>
			..... User の定義
		</Define>
		<Define> ^Passwd
			()
			<Arguments> ^password </Arguments>
			..... Passwd の定義
		</Define>
	</Sequence>

	<Define> ^SetAgent
		^Env
		<Arguments> ^db ^user ^passwd </Argements>
		.... SetAgent の定義
	</Define>

	....


 	<SetAgent>
		"nichibun-db"
		<User> hirohisa </User>
		<Passwd> abc </Passwd>
 	</SetAgent>
 

前段階が終わると、引数が評価され、関数本体へ実行が移る。

おおかたの関数は、前段階なしのApplicative関数であろう。

また関数には、インタプリタにあらかじめ組み込まれたプリミティブ関数と、スクリプトによって定義できる、マクロ関数がある。マクロ関数の定義の仕方はプリミティブ関数lambdaおよびdefineで実現される。

ページトップへ戻る

[3] インタプリタのモデル

一つのインタプリタが起動される時には、必ず一組の入力ストリームがある。たとえば、標準入出力から駆動されたり、またはファイルであったり、あるいはネットワークの外からコネクションがアクセプトされ、インタプリタが起動されるなどである。入力ストリームの先が、ファイルであったり、標準入出力であったりした場合は、このインタプリタをルート・インタプリタと呼ぶ。

インタプリタは、初期化時に、一つの環境を作り、この環境にいくつかのデフォルトの変数を定義し、入力ストリームからXLスクリプトが来るのを待つ。来たスクリプトを一つ一つの関数ごとに、先の環境と一緒にEval関数へ渡す。

駆動されたインタプリターは入力ストリームからルート要素が来るのを待つ。XLストリームの場合にはいくつものルート要素があっても良い。つまり、いくつものXMLファイルが送り込むことが出来る。

インタープリタは入力ストリームから送り込まれた要素を評価し、その結果を、もし対応する出力ストリームがあれば、そこへ返す。

インタプリタを生成する関数は、OpenInterpreter である。この関数によりインタプリタを生成すると、インタプリタID ( IID)が返ってくる。IIDは正のの正数である。インタプリタを終了するときにはこのIIDを使ってCloseInterpreter を呼べばよい。

インタプリタの駆動方式には何種類かがある。ファイルや標準入出力を入力ストリームとして指定する方法、ネットワークのアクセプトポートを指定する方法。また、どこかのXLサーバのアクセプトポートを指定し、コネクションを貼る方法である。

ファイルや標準入出力を入力ストリームとして指定した場合はその入力ストリームがそのままインタプリタの入力ストリームとなる。

アクセプトポートを指定した場合は、そのアクセプトポートに接続要求が来るたびにソケットとインタプリタを生成し、ソケットの入力ストリームをインタプリタの入力ストリームとする。

コネクションを指定した場合は、指定するアクセプトポートに接続し、生成されたソケットのの入力ストリームをインタプリタの入力ストリームとする。

このように、ネットワークのソケットの場合、ソケットは全二重なので、ソケットの両側にインタプリタが対称に生成されることになる。

ページトップへ戻る

[4] RemoteとLocal

XLの特徴的なネットワーク操作関数にRemoteとLocal関数がある。Remote はIIDによって与えられたインタプリタの出力ストリームへ、与えられた命令群(XML要素群)を送り込み、その結果が入力ストリームより返ってくるのを待つ。ソケットの出力ストリームは反対側が入力ストリームとなっており、インタプリタがあるので、このインタプリタが送り込まれたXML要素群を解釈し、結果を返す。返ってきた結果は、そのままRemote の戻り値となる。

Remote をネストすると、次々に新しいインタプリタへソケットを通じてコネクトすることが出来る。複数のインタプリタをネットワークでカスケードし、情報をやりとりする並列実行が可能となる。

Localは、Remote のXML要素を評価中のインタプリタ(リモートインタプリタ)から、ソケットの逆向きのストリームへ要素を送り込む仕組みである。このLocalからの要素を評価するのはRemoteを発行したインタプリタ(ローカルインタプリタ)ではないが、評価の時の環境を。ローカルインタプリタとそろえることにより、ローカルインタプリタのデータにアクセスすることが出来る。Remoteが何段にもカスケードしている場合は、Localも同様にカスケードする事が出来る。

Localにより送り込まれた要素は、Remoteを呼び出したインタプリタの環境で評価をしなければならないので、まず、Remote関数はあらかじめ、出力ストリームへ送り出す要素の先頭の行番号と、現在の環境をセットにしてデータベースに記憶する。一方、Localは直接、評価対象の要素を送り込むことはせず、もとの環境を検索し評価する機能をもったLocalEval関数に評価対象の要素をネストして出力ストリームへ送り込む。

Localが二重にネストすると、二度目のLocalは最後にRemoteを発行したインタプリタの出力インタプリタへ評価要素を送り込まなければならない。そこで、上述の環境と行番号のセットに、さらにRemoteを呼び出したインタプリタへのポインタを記憶しておく。この構造により次に出力すべき出力ストリームが認識できる。

ページトップへ戻る

[5] エージェント

エージェントは環境を共有する一つまたは複数のインタプリタ群からなるプロセスのことを言う。これらインタプリタはこのプロセスのスレッドとして実現される。

エージェントはまず、プロセス駆動時に、その引数として渡されるファイルを入力ストリームとしたインタプリタを生成する。このファイルからはエージェントで実行可能な全ての関数が見える状態である。このファイルでOpenInterpreter を実行すると様々なインタプリタが生成され、実行可能になる。

ページトップへ戻る

[6] XLサーバ

SetAgentとその他のAgent検索機能、クライアントの認証を備えたエージェントのことである。

ユーザこと、クライアント側は駆動したいエージェントの名前と、接続モードを指定する。接続モードとは、エージェントの機能をどこまで使用可能かを決める物である。通常考えられる接続モードの決め方としては、rootモードとuserモードの二種類を用意することである。接続モードはサーバの管理者が自由に決めることが出来る。二種類のみならず、 Agent要素を使って様々な種類を用意することが出来る。

また、ユーザのアカウントはエージェントひとつひとつに与えられるというよりは、いくつかのエージェントをまとめたグループを決め、このグループごとに定義する。これにより、一つの機関のエージェントは統一的に管理できるメリットがある。このグループも Agent要素で定義できる。

認証は、クライアントのIPアドレスと、ユーザのパスワードによる認証の二種類がある

サーバはまず、acceptタイプのインタプリタを駆動する。クライアントからのコネクション要求に対して、まず、クライアントのIPアドレスの認証を行う。

IPアドレスの認証はacceptタイプのOpenInterpreterにおいてPermissionにより指定される情報により行われる。

認証に失敗すると、クライアント側にDenyが送られ、接続はサーバから強制的に切断される。

IPが認証されると、対応する接続モードのリストが検索され、コネクションが維持され、インタプリタが割り当てられる。以降クライアントのユーザ認証が行われるが、このとき、ユーザは検索された接続モード以外では接続できない。この機能を利用し、たとえば、 rootモードではネットワークごしに接続することは出来ないなどの指定が出来る。

この時点で、クライアントからはSetAgentのみが実行可能になる。クライアントから SetAgentにより新しいエージェントを駆動することが出来る。SetAgentは以下のように指定する。

	<SetAgent>
		エージェント名
		接続モード
	</SetAgent>
 

SetAgent関数は、接続モードがIPの認証結果に違反していないか調べる。違反していれば、 Permission Deniedエラーを返す。

次に、エージェント名から、エージェントの情報を検索する。このエージェントを駆動するのにパスワードが必要と判断された場合、GetUserInfo要素をクライアント側に送る。この関数の戻り値として、クライアントはユーザ名とパスワードを返し、サーバはこれによりユーザの認証を行う。認証に成功すれば、 が返され、エージェントが駆動される。認証に失敗すると、Permission Denied のエラーを返す。

GetUserInfoの引数は、グループ、エージェント、接続モードである。クライアント側は、グループと接続モードから必要なユーザ名とパスワードを検索できるようなGetUserInfo 関数をあらかじめ用意しておき、結果を返す。クライアントが異なるサーバに接続する場合にはユーザ名、パスワードのテーブルを増やしていくことにより対応することが出来る。

もし、対応するグループ、接続モードがなかった場合は、エラーを返えす。すると、 SetAgent は同じエラーを返す。

ここで、ユーザに必要な認証情報がないことを示し、ユーザ名パスワードを求めるダイアログを出すようなスクリプトを用意すればよい。

ページトップへ戻る



  GLOBALBASEAI[v\[XE\tgEFAxvOSOURCEFORGE.JPQBĂ܂B SourceForge.jp SourceForge.net Logo