* 構造 [#f309c15c]
-辞書=エントリの集合
-エントリ=キーの集合+出力行(複数行可能)
-ただし第一キーは主キーとなり特別な扱いがされる
-全角記号を特殊記号に使おう!
--「,」は「,」と交換可能
--「*」は「*」と交換可能
--「@」は「@」と交換可能
--「+」は「+」と交換可能
--「<>」「《》」「「」」「『』」は半角と交換できない!
--「%< %>」とかでエスケープ。
--「%%」は「%」のエスケープ。
#pre{{
*キー1(主キー),キー2,キー3...
出力行
出力行
@単語群キー(主キー)
単語候補
単語候補
}}
-単語群は、エントリと比べて
-- キーはひとつだけ
-- 主キーはユニークでなければいけない
-- 各行が単語の候補になる
-- 単語候補は選ばれる単語が「確定した時点で」出力行と同じ評価を受ける
** 処理の方法 [#a5e8ff1d]
-行レベルの処理
-行頭、行末の空白文字はファイル解析処理前に取り除かれる
-各キーの前後の空白文字は取り除かれる
-区切り文字は改行。ただし出力行内の改行はエントリ登録前に取り除かれる
-- ただし出力行で行頭が 『 で始まる場合は次の行頭が 』 の行までを出力行として扱う
-- 行頭や行末に空白文字を入れたい場合、改行コードを入れたい場合の処置。
- _がつくのはシステム変数、関数
-キー内、出力行内の <> はJavaScriptとして実行され、その結果に展開される。
-- 《》は !{ !}と同じくJavaScriptとして実行されるが結果を展開しない。
-- 「」は <_Call(new Array( ));> のエイリアス。指定したエントリを評価しその結果を返す。
-- 『』は <_Any(_GetWord[" "]);> のエイリアス。指定した単語群を評価しその結果を返す。
-JavaScript実行結果が複数ある場合(マルチステートメント)は最後の値が使われる。
-出力は _output システム変数に溜め込まれ、エントリ処理終了後にSHIORI戻り値となる。
-_Call(引数配列)システム関数はエントリを検索し、選択されたエントリの出力を返す
-_Jump(引数配列)システム関数はエントリを検索し、選択されたエントリへ処理を移行する。
-- ジャンプした場合出力はクリアされない。
-キー内ではJavaScriptで真偽判定の式を書ける
-出力の中にはJavaScriptを混ぜることができる
** エントリのヒット、選択 [#faebce45]
-エントリを検索してヒットしたエントリを探すロジックがキモ
-エントリ登録順に検索
-引数配列にヒットしたキーを持つエントリがヒットする。
-<>で囲まれたキーはJavaScript。結果がTrueならヒット。「_val」システム変数が現在の引数の値。
-// で囲まれたキーは正規表現。引数の当該番号のものとマッチしたらヒット。
-+で始まるキーはオプション。キーとしては扱われない。
-キーが「*」の場合無条件でヒット。
-それ以外のキーは即値。引数の当該番号のものと文字列一致したらヒット。
-ただし、主キーでは即値しか使えない。
-主キー中では特殊記号(<,/,+など)は使えない(使っても即値として評価される)
-最初の引数からヒットするエントリを決めていく
-まず第一引数と主キーを比較する。ヒットしなかったものはその場で「除外」
--この時点で何もヒットしなければエントリなし。
-残りのエントリに対し、第二引数と第二キーを比較…を引数の数だけ繰り返す。
-ヒットしたキー数が一番多いものが「選択」される。
-ヒット数が同じものが複数あるばあい、どれか一つがランダムに「選択」される。
-例
#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]
-すべてのエントリは_Entryオブジェクト。
-_Entries[主キー]=Array(_Entry,_Entry,_Entry...)
-_Entries[主キー][序数]=_Entry 各エントリにアクセス可能。
-- 序数は0から辞書読み込み順にカウントアップ
-_Entry.Keys[序数] 文字列の配列。0=主キー
-_Entry.Output 出力文(複数行)
-_Entry.Status ステータス
-_Entry.DicFile 辞書ファイル名(DLLからの相対パス)
-_Entry.Option エントリオプション(ビット集合)
-上記は実行中に変更可能
-- ゆえに実行中の辞書ファイルのパージ(特定辞書ファイル名を持つエントリの削除)が可能
-- 辞書ファイルの読み込みをシステム関数で提供→上と合わせて、辞書の切り替えが可能
-すべての単語群は_Wordオブジェクト。
-_Words[主キー]
-_Words[主キー][序数]=単語
** C++の仕事 [#t1008646]
*** ロード時 [#j9a10773]
-最初のファイル(DLL名称.js)を読み込む
-- #include ちっくなのが使いたい!
--- プリプロセッサをかける?
-「load()」JS関数を実行する
*** リクエスト時 [#bb3f87e4]
-「request()」JS関数を実行する
*** アンロード時 [#m629e932]
-「unload()」JS関数を実行する
*** その他 [#ob0e9088]
- システム変数を供給する。_val,_arg[]
- システム関数を供給する。特に_callと_jump、あとOS依存の関数
-- ファイルIOとかFMOとかDSSTPとかタイマとか
--- タイマってどうやって実装するの
** ミドルの仕事 [#e9fe81fb]
- load() で_Entries[] を構築する
- ミドルは「イベント名、Ref0、Ref1...」という引数セットでエントリを捜す
- _Call(引数配列) でエントリを探して実行、その結果を返す
- 条件式およびエントリ内では _Args[] という変数が有効
- ミドル側で_R[]にリファレンス、_Eventにイベント名を入れる
- _V[]を最初クリアして呼び出す。_V[] に何か入ってたら requestの結果として返す
* サンプル(こんな記述がしたい!) [#w1c3d56c]
** サンプル1 [#s11781b8]
#pre{{
*OnBoot
起動しました。
}}
** サンプル2 [#b9e4eab7]
#pre{{
*OnMinuteChange,*,<_val==0>
<_R[0]>時になりました。
}}
** サンプル3 [#j7c81b4a]
#pre{{
*RandomTalk,+nooverlap
** ほげほげ
** へもへも
}}
- ** は現在のキーを継承して新しいエントリを登録、つまり
#pre{{
*RandomTalk,+nooverlap
ほげほげ
*RandomTalk,+nooverlap
へもへも
}}
- キーが+で始まる場合はそのエントリに対するオプション。キーとしては扱わない
** サンプル4 [#u1f6a472]
#pre{{
*OnCommunicate
《_V[0]=_R[0];》
「"コミュ"+_R[0],_R[1]」
*コミュさくら,+nooverlap
**/寝る/
\h<_R[0]>、寝るんじゃない。
\uそんなこと言ったって眠いやろ。
**/起きる/
\h起きるんじゃない。\u『ツッコミ』
@ツッコミ
どないせえちゅうねん。
なんでやねん。
『標準語ツッコミ』
@標準語ツッコミ
なんでですか。
おかしいですよ。
}}