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ルールは消す必要なかったです。