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