diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ae1a0bf0..82ffe0c2 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -87,9 +87,11 @@ namespace xo { static std::unique_ptr expect_type() { return std::make_unique(exprstate(exprstatetype::expect_type, nullptr)); } +#ifdef RELOCATED static std::unique_ptr make_expr_progress(rp expr) { return std::make_unique(exprstate(exprstatetype::expr_progress, expr)); } +#endif static std::unique_ptr lparen_0() { return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr)); } @@ -135,7 +137,7 @@ namespace xo { /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; - protected: + public: virtual void on_def(exprstatestack * p_stack); virtual void on_symbol(const token_type & tk, exprstatestack * p_stack, diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp new file mode 100644 index 00000000..5b2ce28f --- /dev/null +++ b/include/xo/reader/progress_xs.hpp @@ -0,0 +1,70 @@ +/** @file progress_xs.hpp + * + * Author: Roland Conybeare + **/ + +#pragma once + +#include "exprstate.hpp" +//#include + +namespace xo { + namespace scm { + /** @class progress_xs + * @brief state machine for parsing a schematica runtime-value-expression + **/ + class progress_xs : public exprstate { + public: + progress_xs(rp valex); + virtual ~progress_xs() = default; + + static const progress_xs * from(const exprstate * x) { return dynamic_cast(x); } + + static std::unique_ptr make(rp valex); + + virtual bool admits_definition() const override; + virtual bool admits_symbol() const override; + virtual bool admits_colon() const override; + virtual bool admits_semicolon() const override; + virtual bool admits_singleassign() const override; + virtual bool admits_leftparen() const override; + virtual bool admits_rightparen() const override; + virtual bool admits_f64() const override; + + // virtual void on_f64(..) override + virtual void on_def(exprstatestack * p_stack) override; + + virtual void on_expr(ref::brw expr, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_symbol(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; + virtual void on_typedescr(TypeDescr td, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) override; + virtual void on_colon(exprstatestack * p_stack) override; + virtual void on_semicolon(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_singleassign(exprstatestack * p_stack) override; + virtual void on_leftparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_rightparen(exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + virtual void on_f64(const token_type & tk, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) override; + + virtual void print(std::ostream & os) const override; + + private: +#ifdef NOT_YET + /** populate an expression here **/ + rp gen_expr_; +#endif + }; + } /*namespace scm*/ +} /*namespace xo*/ + + +/** end progress_xs.hpp **/ diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 8896040e..29bb9155 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -5,7 +5,8 @@ set(SELF_SRCS parser.cpp reader.cpp exprstate.cpp - define_xs.cpp) + define_xs.cpp + progress_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) xo_dependency(${SELF_LIB} xo_expression) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index db98d197..b463c00b 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -2,6 +2,7 @@ #include "exprstate.hpp" #include "define_xs.hpp" +#include "progress_xs.hpp" //#include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" //#include "xo/expression/ConvertExpr.hpp" @@ -59,6 +60,8 @@ namespace xo { case exprstatetype::expect_type: return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -94,6 +97,8 @@ namespace xo { return true; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -126,6 +131,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -149,6 +156,8 @@ namespace xo { case exprstatetype::expect_type: return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return true; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -193,6 +202,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -228,6 +239,8 @@ namespace xo { return false; case exprstatetype::expr_progress: + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -276,7 +289,8 @@ namespace xo { return false; case exprstatetype::expr_progress: - /* todo: will parse as function call */ + /* unreachable */ + assert(false); return false; case exprstatetype::invalid: @@ -318,9 +332,6 @@ namespace xo { return false; case exprstatetype::expr_progress: - /* satisfies expression form */ - return true; - case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -475,9 +486,7 @@ namespace xo { } case exprstatetype::expr_progress: - /* illegal input, e.g. - * foo bar - */ + /* unreachable */ assert(false); return; @@ -519,6 +528,7 @@ namespace xo { return; case exprstatetype::expr_progress: + /* unreachable */ assert(false); return; @@ -549,8 +559,8 @@ namespace xo { } void - exprstate::on_semicolon(exprstatestack * p_stack, - rp * p_emit_expr) + exprstate::on_semicolon(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag)); @@ -564,33 +574,7 @@ namespace xo { xtag("state", *this))); } - if (this->exs_type_ == exprstatetype::expr_progress) { - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ - - p_stack->top_exprstate().on_expr(expr, - p_stack, - p_emit_expr); - /* control here on input like: - * (1.234; - * - * a. '(' sets up stack [lparen_0:expect_rhs_expression] - * (see exprstate::on_leftparen()) - * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] - * (see exprstate::on_f64()) - * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] - * deliver expresssion to expect_rhs_expression.on_expr() - * (see exprstate::on_expr()) - * d. expr_rhs_expression forwards expression to [lparen_0] - * e. lparen_0 advances to [lparen_1] - * f. now deliver semicolon; [lparen_1] rejects - */ - - p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); - } else { - assert(false); - } + assert(false); } void @@ -650,33 +634,8 @@ namespace xo { } if (this->exs_type_ == exprstatetype::expr_progress) { - /* stack may be something like: - * - * lparen_0 - * expect_rhs_expression - * expr_progress - * <-- rightparen - * - * 1. rightparen completes expression-in-progress - * 2. rightparen must then match innermost waiting lparen_0 - */ - - /* right paren confirms stack expression */ - rp expr = this->gen_expr_; - - std::unique_ptr self = p_stack->pop_exprstate(); - - if (p_stack->empty()) { - throw std::runtime_error(tostr(self_name, - ": expected non-empty parsing stack")); - } - - log && log(xtag("stack", p_stack)); - - p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); - - /* now deliver rightparen */ - p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + /* unreachable -- see progress_xs::on_rightparen() */ + assert(false); } else if (this->exs_type_ == exprstatetype::lparen_1) { rp expr = this->gen_expr_; @@ -709,7 +668,7 @@ namespace xo { * \---tk---/ */ p_stack->push_exprstate - (exprstate::make_expr_progress + (progress_xs::make (Constant::make(tk.f64_value()))); } else { assert(false); @@ -834,7 +793,7 @@ namespace xo { case exprstatetype::lparen_0: { this->exs_type_ = exprstatetype::lparen_1; /* wants on_rightparen */ - p_stack->push_exprstate(exprstate::make_expr_progress(expr.promote())); + p_stack->push_exprstate(progress_xs::make(expr.promote())); return; } @@ -865,8 +824,7 @@ namespace xo { assert(false); return; case exprstatetype::expr_progress: - /* consecutive expressions isn't legal - */ + /* unreachable */ assert(false); return; case exprstatetype::invalid: diff --git a/src/reader/progress_xs.cpp b/src/reader/progress_xs.cpp new file mode 100644 index 00000000..a9701901 --- /dev/null +++ b/src/reader/progress_xs.cpp @@ -0,0 +1,216 @@ +/* @file progress_xs.cpp */ + +#include "progress_xs.hpp" + +namespace xo { + namespace scm { + std::unique_ptr + progress_xs::make(rp valex) { + return std::make_unique(progress_xs(std::move(valex))); + } + + progress_xs::progress_xs(rp valex) + : exprstate(exprstatetype::expr_progress, + std::move(valex)) + {} + + bool + progress_xs::admits_definition() const { return false; } + + bool + progress_xs::admits_symbol() const { return false; } + + bool + progress_xs::admits_colon() const { return false; } + + bool + progress_xs::admits_semicolon() const { return true; } + + bool + progress_xs::admits_singleassign() const { return false; } + + /* todo: will parse as function call */ + bool + progress_xs::admits_leftparen() const { return false; } + + bool + progress_xs::admits_rightparen() const { + /* satisfies expression form */ + return true; + } + + bool + progress_xs::admits_f64() const { return false; } + + void + progress_xs::on_def(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_def"; + + /* nothing here - admits_definition unconditionally false */ + throw std::runtime_error(tostr(self_name, + ": unexpected keyword 'def' for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_expr(ref::brw /*expr*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* consecutive expressions isn't legal */ + assert(false); + } + + void + progress_xs::on_symbol(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* illegal input, e.g. + * foo bar + */ + assert(false); + } + + void + progress_xs::on_typedescr(TypeDescr /*td*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + /* unreachable */ + assert(false); + } + + void + progress_xs::on_colon(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_colon"; + + throw std::runtime_error(tostr(self_name, + ": unexpected colon for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_semicolon(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + + p_stack->top_exprstate().on_expr(expr, + p_stack, + p_emit_expr); + /* control here on input like: + * (1.234; + * + * a. '(' sets up stack [lparen_0:expect_rhs_expression] + * (see exprstate::on_leftparen()) + * b. 1.234 pushes (in case operators) [lparen_0:expect_rhs_expression:expr_progress] + * (see exprstate::on_f64()) + * c. semicolon completes expr_progress [lparen_0:expect_rhs_expression] + * deliver expresssion to expect_rhs_expression.on_expr() + * (see exprstate::on_expr()) + * d. expr_rhs_expression forwards expression to [lparen_0] + * e. lparen_0 advances to [lparen_1] + * f. now deliver semicolon; [lparen_1] rejects + */ + + p_stack->top_exprstate().on_semicolon(p_stack, p_emit_expr); + } + + void + progress_xs::on_singleassign(exprstatestack * /*p_stack*/) { + constexpr const char * self_name = "progress_xs::on_singleassign"; + + throw std::runtime_error(tostr(self_name, + ": unexpected equals for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_leftparen(exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "exprstate::on_leftparen"; + + throw std::runtime_error(tostr(self_name, + ": unexpected leftparen '(' for parsing state", + xtag("state", *this))); + } + + void + progress_xs::on_rightparen(exprstatestack * p_stack, + rp * p_emit_expr) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "progress_xs::on_rightparen"; + + /* stack may be something like: + * + * lparen_0 + * expect_rhs_expression + * expr_progress + * <-- rightparen + * + * 1. rightparen completes expression-in-progress + * 2. rightparen must then match innermost waiting lparen_0 + */ + + /* right paren confirms stack expression */ + rp expr = this->gen_expr_; + + std::unique_ptr self = p_stack->pop_exprstate(); + + if (p_stack->empty()) { + throw std::runtime_error(tostr(self_name, + ": expected non-empty parsing stack")); + } + + log && log(xtag("stack", p_stack)); + + p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); + + /* now deliver rightparen */ + p_stack->top_exprstate().on_rightparen(p_stack, p_emit_expr); + + } + + void + progress_xs::on_f64(const token_type & /*tk*/, + exprstatestack * /*p_stack*/, + rp * /*p_emit_expr*/) + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + constexpr const char * self_name = "progress_xs::on_f64"; + + throw std::runtime_error(tostr(self_name, + ": unexpected floating-point literal for parsing state", + xtag("state", *this))); + } + + void + progress_xs::print(std::ostream & os) const { + os << ""; + } + + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end progress_xs.cpp */