switch文の実装
bjam_grammarにswitch文を実装しました。
差分
セマンティックアクションを付ける前は、
switch_stmt = keyword_p("switch") >> list >> keyword_p("{") >> cases >> keyword_p("}") ; cases = *case_ ; case_ = keyword_p("case") >> arg_p >> keyword_p(":") >> block ;
のようになっていました。
switch文は最初にマッチしたブロックしか評価しないため、結果とマッチしたかどうかを同時に返せるよう、case_とcasesの戻り値にBoost.Optionalを使ってみたのですが、Phoenixの*演算子が関連型referenceを要求するため使えず、ルール間の値受け渡しをしなくて済むように1個のルールにまとめてしまいました。
switch_stmt = keyword_p("switch") >> list [switch_stmt.value = force_front(arg1)] >> keyword_p("{") >> *( keyword_p("case") >> arg_p [switch_stmt.pattern = arg1] >> keyword_p(":") >> if_p(case_match(switch_stmt.pattern, switch_stmt.value)) [ block [switch_stmt.values = arg1] // マッチしたので移行はパースのみ >> cases_nocalc ] .else_p [ block_nocalc // マッチしていないので次のcaseへ ] ) >> keyword_p("}") ;
casesルールがなくなったため、caseにマッチしない場合のみKleene Starのループが適用されるという奇妙な構造になってしまいました。
#で、よく考えたら、casesルールは消す必要なかったです。