eval_in_module_d

module文を実装しました。
今日の差分


module文は続くブロックを指定したモジュール中で実行します。
これは、ブロックに入る前にモジュールを切り替え、ブロックから出たら元のモジュールに戻すことで実装できます。
これをそのまま実装すると、

module_stmt
    =   keyword_p("module")
        >> list [module_stmt.name = try_front(arg1)]
        >> keyword_p("{") [change_module(self.context, module_stmt.name)]
        >> block [module_stmt.values = arg1]
        >> keyword_p("}") [restore_module(self.context)]
    ;

のような感じになりますが、例外が発生した場合にモジュールが切り替わったままになる恐れがあります。
そこで、spirit::scoped_lock_dを参考に、eval_in_module_dというディレクティブを作成してみました。
これを使うと、上の例はこうなります。

module_stmt
    =   keyword_p("module")
        >> list [module_stmt.name = try_front(arg1)]
        >> keyword_p("{")
        >> eval_in_module_d(self.context, module_stmt.name)
        [
            block [module_stmt.values = arg1]
        ]
        >> keyword_p("}")
    ;

eval_in_module_dは"["〜"]"内のパーサーをeval_in_module_parserでラップしたパーサーの生成をします。
eval_in_module_parser::parse()関数の中では普通にRTTIが使用できるので、確実にモジュールを元に戻すことが可能になります。
また、モジュールの名前は実際にパースする段階まで分からないので、名前を返すファンクタを渡すようになっています。
上の例だと、クロージャのメンバがそれです。