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が使用できるので、確実にモジュールを元に戻すことが可能になります。
また、モジュールの名前は実際にパースする段階まで分からないので、名前を返すファンクタを渡すようになっています。
上の例だと、クロージャのメンバがそれです。