* 構造 [#f309c15c]
-辞書=エントリの集合
-エントリ=キーの集合+出力行(複数行可能)
-ただし第一キーは主キーとなり特別な扱いがされる
#pre{{
*キー1(主キー),キー2,キー3...
出力行
出力行
@単語群キー(主キー)
単語候補
単語候補
}}
-単語群は、エントリと比べて
-- キーはひとつだけ
-- 出力行の各行が単語の候補になる
-- 単語候補は選ばれる単語が「確定した時点で」出力行と同じ評価を受ける
** 処理の方法 [#a5e8ff1d]
-行レベルの処理
-行頭、行末の空白文字はファイル解析処理前に取り除かれる
-各キーの前後の空白文字は取り除かれる
-区切り文字は改行。ただし出力行内の改行はエントリ登録前に取り除かれる
-- ただし出力行で行頭が >> で始まる場合は次の行頭が << の行までを出力行として扱う
-- 行頭や行末に空白文字を入れたい場合、改行コードを入れたい場合の処置。
- _がつくのはシステム変数、関数
-キー内、出力行内の !{~!} はJavaScriptとして実行され、その結果に展開される。
-- ?{ ?}は !{ !}と同じくJavaScriptとして実行されるが結果を展開しない。
-- *{ *}は !{_call(new Array( ));!} のエイリアス。指定したエントリを評価しその結果を返す。
-- @{ @}は !{_Any(_GetWord[ ]);!} のエイリアス。指定した単語群を評価しその結果を返す。
-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]
-すべてのエントリは_Entryオブジェクト。
-_Entries[序数] で各エントリにアクセス可能。
-_Entry.Keys[序数] 文字列の配列。0=主キー
-_Entry.Output 出力文(複数行)
-_Entry.Status ステータス
-_Entry.DicFile 辞書ファイル名(DLLからの相対パス)
-_Entry.Option エントリオプション(ビット集合)
-上記は実行中に変更可能
-- ゆえに実行中の辞書ファイルのパージ(特定辞書ファイル名を持つエントリの削除)が可能
-- 辞書ファイルの読み込みをシステム関数で提供→上と合わせて、辞書の切り替えが可能
** 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@{ツッコミ@}
@ツッコミ
どないせえちゅうねん。
なんでやねん。
@{標準語ツッコミ@}
@標準語ツッコミ
なんでですか。
おかしいですよ。
}}