<document>
<title "XL仕様書">
<chapter "履歴">
<list>
<item "2000.9.30.">
環境に分岐環境の記述を追加。それに伴い、関数の評価のところも変更。
</item>
<item "2000.10.31.">
「構文」の章の構文解析についての記述について更新。
LISP形式の場合の属性リストの記述法について変更。
インタプリタのモデルを変更。それにともないRemote,Localの解釈をはっきりさせた。また、多少エージェント、サーバの用語を変更した。 
</item>
<item "2000.11.05.">
インタプリタのモデルの変更にともない、OpenInterpreter,CloseInterpreterのセマンティックスを変更。OpenInterpreterでソケットをオープンできるようにし、 CloseInterpreterで閉じることが出来るようにした。ConnectはOpenInterpreterで代用できるので標準サポートしないことにした。 
Cancel の追加。 
</item>
<item "2000.11.11.">
SetMainInterpreter,Switch,Arg,GetIid,GetUserInfo,Permission,Account,Agent,GetVariable, Launchの追加。 
しかし、Permissionの実装は不完全。Account の最初の要素はgroup が妥当。まだ変更していない。GetEnvVarは、GetVariableに変更した方がよい。MainInterpreter は SetMainInterpreterに変更した方がよい。 
OpenInterpreter のオプションにPermissionを追加。 
SetAgentの仕様の変更 
</item>
<item "2000.11.15.>
WaitInterpreter の追加。 
</item>
<item "2000.12.24.">
ErrHandlerの仕様を変更。While,Break,Continue,ListLengthの追加。 OpenInterpreterにResultオプションを追加。 
</item>
<item "2001.01.24.">
環境を関数と見なす新しいシンタックスの追加。（関数の評価のところを参照のこと） ThisAgentName, DatabasePath, SetPrefixMode, GetPrefixMode, Get, Set, GetLocalHostName, GetLocalHostIP, OpenSession, RemoteSession, CloseSession, Sync, Lock, Unlockの追加</item>
<item "2001.01.25.">
InvokeError,DeleteSymbol,MoveSymbolを追加。 
</item>
<item "2001.02.03.>
DeleteSymbol,MoveSymbolをDeleteDefine,MoveDefineと改称。また、属性値に、シンボルを入れることが出来るようにした。 
LISPのリストの中で!を使うと、XML形式へ戻るというシンタックスをやめた。< を受信したところでXML形式へ戻る。従って、"<"をS式のシンボルなどとして使いたい場合は、&lt;を使うこと。 
</item>
<item "2000.01.05.>
出力フォーマットに関するオプションをOpenInterpreter,Saveに追加。Argの引数の数え方の変更。 
</item>
<item "2000.01.14.">
DivideStringの追加、Sortの追加。quoteの仕様変更。
</item>
</list>
</chapter>
<chapter "はじめに">
インターネットのブラウザなどでは、HTML、XMLといったマークアップ言語をデータ表現の方法として使い、それを転送するプロトコルとしてHTTPが一般的である。しかし、XMLが発達するにつれて、データベースのクエリをXML形式で記述する方法が提案されるなど、XMLをデータ表現ではなく、プロトコルとしての性格の強い使われ方が成されるようになってきた。 

XMLがプロトコルとしての機能を充実すると、HTTPの役割はXMLで置き換えることが出来る。たとえば、HTTPのGET文は、....というXMLの構文で置き換えることが出来る。このように全てがXMLで置き換えられるようになると、パーザが二つから一つで十分になるなど、リソースの節約が期待される。しかし、単に構文を置き換えるだけでは、実行系は依然として二つ必要であるため、そのメリットはあまりない。 

たとえば、XMLでデータベースに検索クエリを出し、データを引き出したとする。 HTTPを使用した場合、GET文の中にXMLで定義された検索クエリがネストした形でデータベースに送り込まれる。しかし、検索クエリのセマンティックスはデータを GETするという意味はすでに含まれており、冗長性は避けられない。 

この問題の原因は、XMLの構文が統一されたにも関わらず、依然としてプロトコルとその上で処理されるデータという二つの概念が存在しいるからである。そこで、データとプロトコルという二つの概念が交換可能な言語XL(XML LISP)を提案する。つまり、 

<pre>
	<greeting>Hello World</greeting>
</pre>

というXML表現があったとする。このgreeting というタグは、Hello Worldに付属した属性データであると解釈することもできるが、サーバがブラウザたいして「飾り立てて表示しろ」という指令するプロトコルとも取ることが出来、これらの解釈の違いを時と場合によって明示的にいろいろ変えることの出来る仕組みを提案する。 

プロトコルをプログラムと置き換えれば、プログラムとデータが交換可能で、プログラムをデータとして処理したり、データをプログラムとして実行したりすることの出来る言語として、LISP,MLなどの言語が存在する。XLでは、XMLの構文にLISPのセマンティックスを当てはめることによってXML構文の解釈をいろいろプログラムする仕組みを提供する。具体的には、XMLのタグをLISPの関数名、要素にネストした要素をLISPの関数の引数と解釈し、この関数の本体を定義する方法を導入する。たとえば、上述の例では、 

<pre>
	(greeting "Hello World")
</pre>


というLISPのS式と同一であると解釈する。greeting という関数を定義すれば、この構文は実行可能となる。 

ところが、XMLの要素をLISPの関数と解釈したときに問題となるのは、関数の引数の評価方法の考え方がLISPでははっきりとしているが、XMLでは曖昧であるということである。この曖昧さには二種類ある。 

まず最初の曖昧さは、評価順序の曖昧さである。XML文書の要素の中の子要素は、アプリケーションの種類や、評価の状況などによって、必要な物だけが評価されるというNormal Orderの評価が行われる一方で、全ての物をきちっと評価される Applicative Orderの評価が行われる場合もある。 

次の曖昧さは、評価方法そのものの曖昧さである。要素の評価の仕方は、どのような要素のなかにネストされるかによって評価のされ方が違うという曖昧さがある。 

XML文書を処理するためには、まず関数定義の時に、引数の評価順序をNormal Orderか、Applicative Orderか明示的に選択できるようにすることによって、最初の曖昧さに対応する。次に、関数定義の時に、引数を評価するための専用の環境を明示的に指定することによって、要素がネストした場合の評価の方法を切り替えることが出来るようにする。
</chapter>
<chapter "基本言語仕様">

<section "構文">
XLの構文は、XML形式の構文とLISP形式の構文2種類がある。本来、XML 形式のみで十分であるが、それでは煩雑になるので、LISP形式も採用した。ただし、LISP形式はXML形式の要素の中に入れ子にすることが出来るが、その逆は出来ない。関数の仕様書などでは二つの形式を併記している。 

XLパーザには、XMLモードとLISPモードの二種類がある。XMLモードの時には、タグを認識するための構文解析が行われ、また、要素の中の'(',')'、'^'、および数字を認識すると、LISPモードになる。LISPモードでは、'<'を認識すると、XMLモードになる。二つのモードはネストしており、モードの変化点はパーザによって記憶されており、ネストが終わると自動的に基のモードへもどる。 

XMLモードのときの要素は、空白や改行で区切られる。空白や改行は無視する化しないかは?xml:optionで指定することが出来る。もし、空白を無視しないことにした場合、空白のところの区切り目に空白だけの文字列が挿入される。 

<pre>
	<tag>
		abc def
		hhh
		^sym
		ghi
		(+ a b)
		jk 123
		lm
		(print stdout !
			<name data="eee"> hello </name>)
		nop
	</tag>
</pre>

空白、改行を無視するモードでは、 

<pre>
	(tag
		"abc" "def"
		"hhh"
		sym
		"ghi"
		(+ a b)
		"jk" 123
		"lm"
		(print stdout
			([name data="eee"] "hello"))
		"nop"
	</tag>
</pre>

と等価である。空白、改行を無視しないモードでは、 

<pre>
	(tag
		"abc" " " "def" "\n\t\t"
		"hhh"
		sym
		"ghi"
		(+ a b)
		"jk" 123
		"lm"
		(print stdout
			([name data="eee"] "hello"))
		"nop"
	</tag>
</pre>

となる。タグのあと、'('や'^'など、LISPモードへ変化する前後では空白や改行は無視されることに注意されたい。 
</section>
<section "変数と値と型">
XL では、型は値に与えられる物であり、変数はどのような値も受け付ける。 
</section>
<section "型">

<subsection "型と値の標記">
XLで使用する値の種類は以下の通りである。 

<pre>
exp ::=
	fundamantal-exp		(基本型)
	structured-exp		(構造型)
	function-exp		(関数型)
	environment-exp		(環境型)
</pre>
</subsection>
<subsection "基本型">
XLで定義される基本型は以下の通りである。 

<pre>
fundamental-exp ::=
	integer
		表記：XML方式,LISP方式ともに同じ
	floating-point（浮動小数点）
		表記：XML方式,LISP方式ともに同じ
	string
		表記：	
			XML	解析文字列
			LISP 	"..."
	symbol
		表記：
			XML	^... (最後に空白が入る)
			LISP	以下参照。
	raw
		表記：
			XML形式LISP形式ともに同じ
			#byte数#...RAWデータ...
			例：#5#!x$%~
	error
		表記：
			%E(
				エラーシーケン番号(行番号)
				エラー発生siteのURL
				エラー発生ファイル名
				エラー発生関数名
				エラーコード
				exp (その他付加データ)
				)
	environment
		表記：なし
</pre>
error型は、エラーを処理するための特別な値で、エラーが発生した関数が戻り値として返す。一方、この値を受け取った関数は即座に同じエラーを返さなければならない。ただし、ErrHandler関数は例外である。この関数はエラーを補足してエラーの後処理をするための関数である。 

通常、インタープリタは、エラーが発生すると、それをResult関数の引数として表示する。しかし、error型のうちErrDontPrintエラーは特殊なエラーで、インタプリターはこのエラーを受けるとなにも表示しない。このようにすることによって、ネットワークでエラーやデータがループする事態を回避している。
</subsection>
<subsection "文字コードについて">
XLの処理系内部ではあらゆる文字を32bit固定長で表現する。この文字コードを内部文字コードと呼ぶ。内部文字コードの割り当ては以下の通りである。

<pre>
ゾーン	ゾーンの意味	割り当てられたコード 
00 00 00 00 ～ 7F FF FF FF	4バイトコード	UCS 
80 00 00 00 ～ 80 00 FF FF	2バイトコード	JIS 第一水準、第二水準 
80 00 00 00 ～ BF FF FF FF	2バイトコード	未使用 
C0 00 00 00 ～ DF FF FF FF	3バイトコード	未使用 
E0 00 00 00 ～ FF FF FF FF	1バイトコード	未使用 
</pre>

UCSおよびJISの領域以外は、UCSやJISと異なるコンセプトのコードを割り当てることが出来る。現在はEUC、SJISは全てパーザによってJISに変換される。 
</subsection>
<subsection "構造型(LISPのS式に対応)">
<pre>
LISP形式
structured-type ::=
	()
	(exp exp ....)
	([symbol 属性リスト])
	([symbol 属性リスト] exp ....)



XML形式

([symbol 属性リスト] ....)


は、 


<symbolと同じ文字列 属性リスト> .</symbolと同じ文字列>


と等価である。たとえば、 


([greeting
	FirstName = "Hirohisa" 
	LastName = "Mori"] 
	"Hello World")


は、 


<greeting 
	FirstName="Hirohisa" 
	LastName = "Mori"> 
	Hello World
</greeting>
</pre>
と変換できる。この場合、Hello World は一続きの文字列として認識されるが、これを別々に分けたい場合は、間に \ をいれる。つまり、 

<pre>

<greeting 
	FirstName="Hirohisa" 
	LastName = "Mori"> 
	Hello \ World 
</greeting>


は、 


(greeting [
	FirstName = "Hirohisa" 
	LastName = "Mori"]
	"Hello" "World")
</pre>

と等価である。 

属性値にシンボルを定義したい場合は、 
<pre>

(greeting [FirstName = "^symbol" ]
	"Hello" "World")


<greeting FirstName = "^symbol"> Hello World </greeting>

</pre>
というように、属性値の頭に^を付ければよい。^を二つ続け、"^^symbol"とすると、それはシンボルではなく、"^symbol"という文字列と解釈される。 
</subsection>
<subsection "環境">
変数と値の対応表。変数の名前はsymbolで示される。つまり、symbolと値の対応表が環境である。 

通常一つの環境には、一つの親環境がある。以下に述べる、評価においては、親環境の情報も検索対象となる。 

しかし、関数の引数の評価時には、関数の引数評価用の環境を先に評価し、その後、関数のカレントの環境を評価する必要があるため、親環境を二つもった分岐環境が生成される。ただし、この環境にはシンボルや値をバインドすることは出来ない。 

評価時の分岐環境の検索順序は、まず、第一番目の親環境、次に第二番目の親環境となる。したがって、親環境に定義されているシンボルが優先される。 
</subsection>
</section>
<section "インタプリタ実行モデル">
<subsection "評価">
プリミティブ関数の一つである評価関数Evalを、次のように定義する。 
<pre>
	(Eval environment-exp　exp)
</pre>
評価対象(exp)としては、あらゆる型を受け付ける。そして以下に示す通り、評価した結果を返す。このとき、Eval に与えられた環境(environment-exp)を評価対象のカレント環境と呼ぶ。 
<list>
<item>
評価対象が、symbol以外の基本型の値の場合は、その値をそのまま返す。
</item>
<item>
評価対象が、symbolであった場合は、与えられた環境および、親環境、そのまた親環境と検索し、symbolに相当する変数が初めて見つかった時点で、対応した値を返す。検索に失敗したらエラーを返す。エラーはシステム構造型として後述する。
</item>
<item>
評価対象が、関数であった場合は、その値をそのまま返す。
</item>
<item>
評価対象が構造型であった場合、その最初のシンボル、あるいはタグに相当するシンボルを評価し、 
<list>
<item>
その評価結果が関数でも環境でもでなかった場合は、エラーを返す。 
</item>
<item>
その評価結果が環境の場合、その環境を親環境とした環境を新しく生 成し、これへカレント環境を変更する。この環境には、Localというシン ボルにまえのカレント環境をバインドする。
</item>
<item>
その評価結果が関数であった場合は、関数がnormal-order か、 applicateive-orderかを判定、
</item>
<item>
normal-order であれば、構造型の値、あるいは、要素をそのまま関数へ渡し、 関数そのものを実行し、結果を返す。 
</item>
<item>
applicative-order であれば、構造型の値の二項目以降あるいは、要素の中身を すべて評価し、これらを引数として関数に渡し、実行結果を返す。
</item>
</list>
</item>
</list>
</subsection>
<subsection "関数">
引数を与えると、それに対し所定に計算をし値を返す。関数を呼び出すときには、 
<pre>
	(func a b c)
</pre>
または、 
<pre>
	<func> a b c </func>
</pre>
あるいは、属性リストをつかい 
<pre>
	([func type="def"] a b c)

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

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

一方、Applicativeでは、引数は引数要素ごとに評価されてから渡される。引数評価のために、分岐環境が生成され、その一番目の親環境に関数定義時に定義した専用の環境がセットされ、第二番目の親環境に現在のカレント環境が設定される。評価する場合の環境の検索順序は関数定義時の環境、現在のカレント環境という順番になる。この仕組みは、 
<pre>
 	<SetAgent>
		"nichibun-agent"
		<User> hirohisa </User>
		<Passwd> abc </Passwd>
 	</SetAgent>
</pre>
という呼び出しを考えたとき、User,Passwdを、SetAgent外部で使用したときと、別の処理をしたいときに有効である。評価用の環境でこの特殊な処理の関数を定義すればよい。つまり、以下のようにSequenceを使って新しい環境を定義してしようする。 
<pre>
	<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>
</pre>
前段階が終わると、引数が評価され、関数本体へ実行が移る。 

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

また関数には、インタプリタにあらかじめ組み込まれたプリミティブ関数と、スクリプトによって定義できる、マクロ関数がある。マクロ関数の定義の仕方はプリミティブ関数lambdaおよびdefineで実現される。 
</subsection>
<subsection "インタプリタのモデル">
一つのインタプリタが起動される時には、必ず一組の入力ストリームがある。たとえば、標準入出力から駆動されたり、またはファイルであったり、あるいはネットワークの外からコネクションがアクセプトされ、インタプリタが起動されるなどである。入力ストリームの先が、ファイルであったり、標準入出力であったりした場合は、このインタプリタをルート・インタプリタと呼ぶ。 

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

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

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

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

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

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

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

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

このように、ネットワークのソケットの場合、ソケットは全二重なので、ソケットの両側にインタプリタが対称に生成されることになる。 
</subsection>
<subsection "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を呼び出したインタプリタへのポインタを記憶しておく。この構造により次に出力すべき出力ストリームが認識できる。 
</subsection>
<subsection "エージェント">
エージェントは環境を共有する一つまたは複数のインタプリタ群からなるプロセスのことを言う。これらインタプリタはこのプロセスのスレッドとして実現される。 

エージェントはまず、プロセス駆動時に、その引数として渡されるファイルを入力ストリームとしたインタプリタを生成する。このファイルからはエージェントで実行可能な全ての関数が見える状態である。このファイルでOpenInterpreter を実行すると様々なインタプリタが生成され、実行可能になる。 
</subsection>
<subsection "XLサーバ">
SetAgentとその他のAgent検索機能、クライアントの認証を備えたエージェントのことである。 

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

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

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

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

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

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

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

この時点で、クライアントからはSetAgentのみが実行可能になる。クライアントから SetAgentにより新しいエージェントを駆動することが出来る。SetAgentは以下のように指定する。 
<pre>
	<SetAgent>
		エージェント名
		接続モード
	</SetAgent>
</pre>
SetAgent関数は、接続モードがIPの認証結果に違反していないか調べる。違反していれば、 Permission Deniedエラーを返す。 

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

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

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

ここで、ユーザに必要な認証情報がないことを示し、ユーザ名パスワードを求めるダイアログを出すようなスクリプトを用意すればよい。 
</subsection>
</section>
<section "プラグマ">
以下に挙げるタグはXLではプラグマと呼ばれ、XLパーザに対する命令と解釈される。 
<pre>
 <?xml version="1.0" .... ?> 
XMLのバージョンと文字コード指定。


 <?xl seq="数字" ?> 
文書の行数の固定


 <?xl code="...." ?> 
文字コードの変更


 <?xl appltag="ignore/remark" ?> 
文字コードの変更
</pre>
そのほかの、 <? ... ?> は、appltagの指定に従い、無視されるか、されないかが決まる。appltag="remark"のときは、?から始まるシンボルを一つもった、長さ1の構造型として翻訳される。 
</section>
<section "組み込み関数インタフェース">
データベースのフロントエンドをするインタプリタには、データベース操作を行う固有の関数を組み込まなければならない。その組み込み関数はCで記述し、インタプリタのコードとリンクする。 

まず以下のように、関数を定義する。 
<pre>
XLtype * pEmbeddedFunction(XLenv * e, XLtype * s) { s に関する処理。 return 結果 } 
</pre>
sは、List(引数0,引数1,引数2,....)という形を取っている。それぞれの引数は、以下に示す、cLambdaにおけるオプションがApplicativeであれば、評価されてから渡される。 

次に、インタプリタの初期の環境生成時に上記関数を環境に登録するコードを追加する。<pre>
XLenv * RootEnv;

main()
{

	Env0 = cNewEnvironment(0);
	....
	cDefine(Env0,"EnbeddedFunction",
		cLambda(	// 関数を得る。
			"Applicative",		// 関数の属性
			0,			// 引数評価のための環境
			pEmbeddedFunction));　	// 呼び出される関数名
	....
}
</pre>
以下に述べるプリミティブは、インタプリタのソースコード内では、 
<pre>
XLtype *
_プリミティブ名(XLenv * e,XLtype * s)
{

}
</pre>
という形で定義されている。新たなるプリミティブを定義するときにこの関数を使うことが出来る。 

また、このプリミティブをそのまま使うには、引数がsで示される構造型にすべてまとめられており、使いにくく、また、カレント環境を参照しない演算関数などでも、eが定義されている。従って、プリミティブを新たにコーディングするために使いやすく引数を整理した関数として、以下のような関数を定義している。 
<pre>
XLtype *
cプリミティブ名(....)
{

}
</pre>
上述main関数の例のなかで定義しているcDefine,cLambdaはこの関数である。引数の評価はEvalが行うので、_プリミティブ名、および、cプリミティブ名、のいずれの形式に置いても、引数の評価はされないことに注意しなければならない。 

XLtype は、XLにおける基本型、構造型の内部形式であり、XLenvは環境の内部形式である。この実際の定義は別途インタプリタのソースコードのヘッダファイルにて明らかにする。
</section>
</chapter>
<chapter "プリミティブ">
インタプリタ初期化時に、環境にデフォルトで組み込まれる変数とその値をプリミティブと呼ぶ。そのうち値は固定的であり、Cなどのインタプリタを記述する言語で書かれている。そのうち、あらゆるXLでいつでも使える関数を汎用プリミティブとよぶ。また、データベース検索など何らかの高機能な目的のために拡張するために組み込まれるものを拡張プリミティブと呼ぶ。拡張プリミティブについては、ここの仕様では定義しない。
</chapter>
</title>
</document>