* 構造 [#f309c15c]
-辞書=エントリの集合
-エントリ=キーの集合+出力行(複数行可能)
-ただし第一キーは主キーとなり特別な扱いがされる
#pre{{
*キー1(主キー),キー2,キー3...
出力行
出力行
}}
** 処理の方法 [#a5e8ff1d]
-行レベルの処理
-行頭、行末の空白文字はファイル解析処理前に取り除かれる
-区切り文字は改行。ただし出力行内の改行はエントリ登録前に取り除かれる
-- ただし出力行で行頭が >> で始まる場合は次の行頭が << の行までを出力行として扱う
-- 行頭や行末に空白文字を入れたい場合、改行コードを入れたい場合の処置。
-キー内、出力行内の @{~@} はJavaScriptとして実行され、その結果に展開される。
-JavaScript実行結果が複数ある場合(マルチステートメント)は最後の値が使われる。
-出力は _output システム変数に溜め込まれ、エントリ処理終了後にSHIORI戻り値となる。
-_call(引数配列)システム関数はエントリを検索し、選択されたエントリの出力を返す
-_jump(引数配列)システム関数はエントリを検索し、選択されたエントリへ処理を移行する。
-- ジャンプした場合出力はクリアされない。
-キー内ではJavaScriptで真偽判定の式を書ける
-出力の中にはJavaScriptを混ぜることができる
** エントリのヒット、選択 [#faebce45]
-エントリを検索してヒットしたエントリを探すロジックがキモ
-エントリ登録順に検索
-引数配列にヒットしたキーを持つエントリがヒットする。
-@{ @}で囲まれたキーはJavaScript。結果がTrueならヒット。「_val」システム変数が現在の引数の値。
-// で囲まれたキーは正規表現。引数の当該番号のものとマッチしたらヒット。
-キーが「*」の場合無条件でヒット。
-それ以外のキーは即値。引数の当該番号のものと文字列一致したらヒット。
-ただし、主キーでは即値しか使えない。
-主キー中では特殊記号(/,@,{など)は使えない。
-主キーは同じものが複数あってもよい(main,request除く)
-最初の引数からヒットするエントリを決めていく
-まず第一引数と主キーを比較する。ヒットしなかったものはその場で「除外」
--この時点で何もヒットしなければエントリなし。
-残りのエントリに対し、第二引数と第二キーを比較…を引数の数だけ繰り返す。
-ヒットしたキー数が一番多いものが「選択」される。
-ヒット数が同じものが複数あるばあい、どれか一つがランダムに「選択」される。
-例
#pre{{
1:AAA,BBB,@{_val=="DDD";@}
2:AAA,BBB
3:AAA
4:BBB
5:CCC
}}
というエントリがあった場合
-引数AAAのコールでは1,2,3のいずれかが選択される。1のJavaScriptは評価されない。
-引数AAA,BBBのコールでは1,2のいずれかが選択される。1のJavaScriptは評価されない。
-引数AAA,BBB,CCCのコールでは1,2のいずれかが選択される。1のJavaScriptは評価される。
-引数AAA,BBB,DDDのコールでは1が選択される。
-引数BBBのコールでは4が選択される。
-引数BBB,CCCのコールでは4が選択される。
-引数DDDのコールではエントリなし。
** 内部構造 [#s26c0815]
-すべてのエントリは_E オブジェクトのツリーとなる
-_E[主キー]=Array(_E[第2キー],_E[第2キー]...)
-_E[主キー][第2キー]=Array(_E[第3キー],...)
-すべてのエントリは「辞書ファイル名@主キー@エントリ番号」というエントリIDを持つ
-エントリ番号はその辞書ファイル、その主キー中でそのエントリが出てきた順序、0スタート
-システム変数_Entries[]はエントリに関する情報を持つマップ。キーはエントリID
-_Entries[].Condition 条件式
-_Entries[].Output 出力文(複数行)
-_Entries[].Status ステータス
-_Entries[].Option エントリオプション(ビット集合)
-上記は実行中に変更可能
-- ゆえに実行中の辞書ファイルのパージ(特定辞書ファイル名@で始まるエントリの削除)が可能
--
** C++の仕事 [#t1008646]
*** ロード時 [#j9a10773]
-辞書ファイル(DLL名称.dic)を読み込む
-_Entries[] を構築する ←これはJavaScriptで出来てしまうかも
-主キーが「load」 のエントリを実行する
*** リクエスト時 [#bb3f87e4]
- requestエントリを実行する
*** アンロード時 [#m629e932]
- unload エントリを実行する
*** その他 [#ob0e9088]
- システム変数を供給する。_val,_arg[]
- システム関数を供給する。特に_callと_jump、あとOS依存の関数とか(JavaScriptに無いもの)
- ミドルは「イベント名、Ref0、Ref1...」という引数セットでエントリを捜す
- _call(引数配列) でエントリを探して実行、その結果を返す
- 条件式およびエントリ内では _Args[] という変数が有効
- ミドル側で_R[]にリファレンス、_Eventにイベント名を入れる
- _がつくのはシステム変数、関数
- 条件式はJavaScriptとして真偽判定
- 出力式内の{}はJavaScriptとして実行、値を出力に混ぜる
* サンプル(こんな記述がしたい!) [#w1c3d56c]
#pre{{
*@OnBoot
起動しました。
}}
- 行頭に*のあるものがエントリ。その後改行があり、出力の羅列。次のエントリまでつづく。
- 条件式内の@は _Args[0]=="OnBoot" の省略記法
#pre{{
*@OnMinuteChange && _R[1]==0
{_R[0]}時になりました。
}}
#pre{{
}}
#pre{{
*RandomTalk,@nooverlap
** ほげほげ
** へもへも
}}
- ** は現在の条件式のまま新しいエントリを登録
- 複数のエントリがヒットした場合はどれか一つをランダムに選択
- キーのエントリの直後の行が@で始まる場合はそのエントリに対するオプション
#pre{{
*OnCommunicate
{
_V[0]=_R[0];
_call(new Array("コミュ"+_R[0],_R[1]));
}
*コミュさくら,@nooverlap
**/寝る/
\h寝るんじゃない。
\uそんなこと言ったって眠いやろ。
**/起きる/
\h起きるんじゃない。
\uどないせえちゅうねん。
**
}}
これはこう書くのと等価
#pre{{
*コミュさくら,/寝る/,@nooverlap \h寝るんじゃない\uそんなこと~
*コミュさくら,/起きる/,@nooverlap \h起きるんじゃない\uそんなこと~
}}
#pre{{
}}