/** @file if_else_xs.hpp * * author: Roland Conybeare, Jul 2025 **/ #pragma once #include "xo/expression/IfExpr.hpp" #include "exprstate.hpp" #include "xo/indentlog/print/ppdetail_atomic.hpp" namespace xo { namespace scm { /** * if test-expr then then-expr else else-expr ; * ^ ^ ^ ^ ^ ^ ^ * | | | | | | | * | if_1 if_2 if_3 if_4 if_5 if_6 * if_0 * * if_0 --on_if_token()--> if_1 * if_1 --on_expr()--> if_2 * if_2 --on_then_token()--> if_3 * if_3 --on_expr()--> if_4 * if_4 --on_else_token()--> if_5 * --on_semicolon_token()--> (done) * if_5 --on_expr()-->if_6 * if_6 --on_semicolon_token()--> (done) **/ enum class ifexprstatetype { invalid = -1, if_0, if_1, if_2, if_3, if_4, if_5, if_6, n_ifexprstatetype, }; extern const char * ifexprstatetype_descr(ifexprstatetype x); std::ostream & operator<<(std::ostream & os, ifexprstatetype x); /** @class if_else_xs * @brief state to provide parsing of a conditional expression **/ class if_else_xs : public exprstate { public: using IfExprAccess = xo::scm::IfExprAccess; public: if_else_xs(rp if_expr); virtual ~if_else_xs() = default; static const if_else_xs * from(const exprstate * x) { return dynamic_cast(x); } static void start(parserstatemachine * p_psm); // ----- inherited from exprstate ----- virtual const char * get_expect_str() const override; virtual void on_if_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_then_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_else_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_semicolon_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_rightbrace_token(const token_type & tk, parserstatemachine * p_psm) override; virtual void on_expr(bp expr, parserstatemachine * p_psm) override; virtual void on_expr_with_semicolon(bp expr, parserstatemachine * p_psm) override; virtual void print(std::ostream & os) const override; private: static std::unique_ptr make(); /** exit this exprstate, * and deliver @ref if_expr_ to parent exprstate **/ void finish_and_continue(parserstatemachine * p_psm); private: ifexprstatetype ifxs_type_; /** scaffold output expression here **/ rp if_expr_; }; } /*namespace scm*/ namespace print { #ifndef ppdetail_atomic PPDETAIL_ATOMIC(xo::scm::ifexprstatetype); #endif } } /*namespace xo*/ /* end if_else_xs.hpp */