diff --git a/include/xo/reader/define_xs.hpp b/include/xo/reader/define_xs.hpp index f3a5f15a..59b55d83 100644 --- a/include/xo/reader/define_xs.hpp +++ b/include/xo/reader/define_xs.hpp @@ -56,18 +56,18 @@ namespace xo { exprstatestack * p_stack, rp * p_emit_expr) override; virtual void on_typedescr(TypeDescr td, - exprstatestack * /*p_stack*/, - rp * /*p_emit_expr*/) override; + exprstatestack * p_stack, + rp * p_emit_expr) override; virtual void on_colon_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_semicolon_token(const token_type & tk, exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + rp * p_emit_expr) override; virtual void on_singleassign_token(const token_type & tk, exprstatestack * p_stack) override; virtual void on_rightparen_token(const token_type & tk, exprstatestack * p_stack, - rp * /*p_emit_expr*/) override; + rp * p_emit_expr) override; virtual void on_f64_token(const token_type & tk, exprstatestack * p_stack, rp * /*p_emit_expr*/) override; diff --git a/include/xo/reader/expect_formal_xs.hpp b/include/xo/reader/expect_formal_xs.hpp new file mode 100644 index 00000000..557ffa61 --- /dev/null +++ b/include/xo/reader/expect_formal_xs.hpp @@ -0,0 +1,80 @@ +/* file expect_formal_xs.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "exprstate.hpp" +#include "formal_arg.hpp" + +namespace xo { + namespace scm { + /** + * name : type + * ^ ^ ^ + * | | formal_2 + * | formal_1 + * formal_0 + * + **/ + enum class formalstatetype { + invalid = -1, + + formal_0, + formal_1, + formal_2, + + n_formalstatetype, + }; + + extern const char * + formalstatetype_descr(formalstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalstatetype x) { + os << formalstatetype_descr(x); + return os; + } + + /** @class expect_formal_xs + * @brief parser state-machine for a typed formal parameter + **/ + class expect_formal_xs : public exprstate { + public: + expect_formal_xs() = default; + + virtual void on_symbol(const std::string & symbol_name, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + virtual void on_colon_token(const token_type & tk, + exprstatestack * p_stack + /*rp * p_emit_expr*/) override; + + // virtual void on_comma_token(...) override; + +#ifdef PROBABLY_NOT + virtual void on_rightparen_token(const token_type & tk, + exprstatestack * p_stack, + rp * p_emit_expr) override; +#endif + + virtual void on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr) override; + + virtual void print(std::ostream & os) const override; + + private: + /** parsing state-machine state **/ + formalstatetype formalxs_type_; + /** populate with {parameter-name, parameter-type} + * as they're encountered + **/ + formal_arg result_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end expect_formal_xs.hpp */ diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index ef65e8f5..fbdc8b50 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -52,7 +52,7 @@ namespace xo { class exprstatestack; - class define_xs; + class formal_arg; /** state associated with a partially-parsed expression. **/ @@ -91,6 +91,10 @@ namespace xo { virtual void on_typedescr(TypeDescr td, exprstatestack * p_stack, rp * p_emit_expr); + /** update exprstate when expecting a formal parameter **/ + virtual void on_formal(const formal_arg & formal, + exprstatestack * p_stack, + rp * p_emit_expr); /** print human-readable representation on @p os **/ virtual void print(std::ostream & os) const; diff --git a/include/xo/reader/formal_arg.hpp b/include/xo/reader/formal_arg.hpp new file mode 100644 index 00000000..4f0afaef --- /dev/null +++ b/include/xo/reader/formal_arg.hpp @@ -0,0 +1,58 @@ +/* file formal_arg.hpp + * + * author: Roland Conybeare, Aug 2024 + */ + +#pragma once + +#include "TypeDescr.hpp" +#include "xo/indentlog/print/tag.hpp" + +namespace xo { + namespace scm { + /** @class formal_arg + * @brief description of formal parameter in an argument list + * + * Terminated by an argument separator ',' or rightparen ')' + **/ + class formal_arg { + public: + using TypeDescr = xo::reflect::TypeDescr; + + public: + formal_arg() = default; + formal_arg(const std::string & n, TypeDescr td) : name_{n}, td_{td} {} + + const std::string & name() const { return name_; } + TypeDescr td() const { return td_; } + + void assign_name(const std::string & x) { name_ = x; } + void assign_td(TypeDescr x) { td_ = x; } + + void print(std::ostream & os) const { + os << ""; + } + + private: + /** formal parameter name **/ + std::string name_; + /** type description for variable @p name **/ + TypeDescr td_; + }; + + inline std::ostream & + operator<< (std::ostream & os, + const formal_arg & x) { + x.print(os); + return os; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end formal_arg.hpp */ diff --git a/include/xo/reader/progress_xs.hpp b/include/xo/reader/progress_xs.hpp index 361e6d3d..bc1ada8d 100644 --- a/include/xo/reader/progress_xs.hpp +++ b/include/xo/reader/progress_xs.hpp @@ -18,7 +18,9 @@ namespace xo { progress_xs(rp valex); virtual ~progress_xs() = default; - static const progress_xs * from(const exprstate * x) { return dynamic_cast(x); } + static const progress_xs * from(const exprstate * x) { + return dynamic_cast(x); + } static std::unique_ptr make(rp valex); diff --git a/src/reader/CMakeLists.txt b/src/reader/CMakeLists.txt index 6907dff2..ae233e22 100644 --- a/src/reader/CMakeLists.txt +++ b/src/reader/CMakeLists.txt @@ -11,6 +11,7 @@ set(SELF_SRCS exprseq_xs.cpp expect_expr_xs.cpp expect_symbol_xs.cpp + expect_formal_xs.cpp expect_type_xs.cpp) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/src/reader/expect_formal_xs.cpp b/src/reader/expect_formal_xs.cpp new file mode 100644 index 00000000..5ec91987 --- /dev/null +++ b/src/reader/expect_formal_xs.cpp @@ -0,0 +1,87 @@ +/* file expect_formal_xs.cpp + * + * author: Roland Conybeare + */ + +#include "expect_formal_xs.hpp" + +namespace xo { + using xo::reflect::TypeDescr; + + namespace scm{ + const char * + formalstatetype_descr(formalstatetype x) { + switch (x) { + case formalstatetype::invalid: + case formalstatetype::n_formalstatetype: + return "?formalstatetype"; + case formalstatetype::formal_0: + return "formal_0"; + case formalstatetype::formal_1: + return "formal_1"; + case formalstatetype::formal_2: + return "formal_2"; + } + + return "???formalstatetype"; + } + + void + expect_formal_xs::on_symbol(const std::string & symbol_name, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (this->formalxs_type_ == formalstatetype::formal_0) { + this->formalxs_type_ = formalstatetype::formal_1; + this->result_.assign_name(symbol_name); + } else { + exprstate::on_symbol(symbol_name, + p_stack, + p_emit_expr); + } + } + + void + expect_formal_xs::on_colon_token(const token_type & tk, + exprstatestack * p_stack + /* rp * p_emit_expr */) + { + if (this->formalxs_type_ == formalstatetype::formal_1) { + this->formalxs_type_ = formalstatetype::formal_2; + } else { + exprstate::on_colon_token(tk, + p_stack); + } + } + + void + expect_formal_xs::on_typedescr(TypeDescr td, + exprstatestack * p_stack, + rp * p_emit_expr) + { + if (this->formalxs_type_ == formalstatetype::formal_2) { + this->result_.assign_td(td); + + std::unique_ptr self = p_stack->pop_exprstate(); + + //p_stack->top_exprstate().on_formal(result_, p_stack, p_emit_expr); + } else { + exprstate::on_typedescr(td, p_stack, p_emit_expr); + } + } + + void + expect_formal_xs::print(std::ostream & os) const { + os << ""; + } + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end expect_formal_xs.cpp */ diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index e7933d7c..d36fba94 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -1,6 +1,8 @@ /* @file exprstate.cpp */ #include "exprstate.hpp" +#include "formal_arg.hpp" +#include //#include "define_xs.hpp" //#include "progress_xs.hpp" //#include "paren_xs.hpp" @@ -63,15 +65,45 @@ namespace xo { } void - exprstate::on_typedescr(TypeDescr /*td*/, - exprstatestack * /*p_stack*/, + exprstate::on_typedescr(TypeDescr td, + exprstatestack * p_stack, rp * /*p_emit_expr*/) { /* returning type description to something that wants it */ - /* unreachable - implement in derived class */ - assert(false); - return; + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", + p_stack->top_exprstate().exs_type())); + + constexpr const char * c_self_name = "exprstate::on_typedescr"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected typedescr for parsing state", + xtag("td", td), + xtag("state", *this))); + } + + void + exprstate::on_formal(const formal_arg & formal, + exprstatestack * p_stack, + rp * /*p_emit_expr*/) + { + /* returning type description to something that wants it */ + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", + p_stack->top_exprstate().exs_type())); + + constexpr const char * c_self_name = "exprstate::on_formal"; + + throw std::runtime_error(tostr(c_self_name, + ": unexpected formal-arg for parsing state", + xtag("formal", formal), + xtag("state", *this))); } void @@ -254,13 +286,19 @@ namespace xo { } /*on_expr*/ void - exprstate::on_symbol(const std::string & /*symbol_name*/, + exprstate::on_symbol(const std::string & symbol_name, exprstatestack * /*p_stack*/, rp * /*p_emit_expr*/) { /* unreachable - derived class that can receive * will override this method */ + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + log && log(xtag("exstype", this->exs_type_), + xtag("symbol_name", symbol_name)); + assert(false); }