diff --git a/CMakeLists.txt b/CMakeLists.txt index b7b5a5f7..54441a8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,6 +353,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectqarrayssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectQArraySsm + INPUT idl/ISyntaxStateMachine_DExpectQArraySsm.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-expectqarrayssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectQArraySsm + INPUT idl/IPrintable_DExpectQArraySsm.json5 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-reader2-genfacet-all) # ---------------------------------------------------------------- diff --git a/idl/IPrintable_DExpectQArraySsm.json5 b/idl/IPrintable_DExpectQArraySsm.json5 new file mode 100644 index 00000000..9ba8c712 --- /dev/null +++ b/idl/IPrintable_DExpectQArraySsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectQArraySsm", + using_doxygen: true, + repr: "DExpectQArraySsm", + doc: [ "implement APrintable for DExpectQArraySsm" ], +} diff --git a/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 b/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 new file mode 100644 index 00000000..0ace11e7 --- /dev/null +++ b/idl/ISyntaxStateMachine_DExpectQArraySsm.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/reader2", + output_hpp_dir: "include/xo/reader2", + output_impl_subdir: "ssm", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DExpectQArraySsm", + using_doxygen: true, + repr: "DExpectQArraySsm", + doc: [ "implement ASyntaxStateMachine for DExpectQArraySsm" ], +} diff --git a/include/xo/reader2/DExpectQArraySsm.hpp b/include/xo/reader2/DExpectQArraySsm.hpp new file mode 100644 index 00000000..5316ee34 --- /dev/null +++ b/include/xo/reader2/DExpectQArraySsm.hpp @@ -0,0 +1,138 @@ +/** @file DExpectQArraySsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DSyntaxStateMachine.hpp" +#include +//#include +#include + +namespace xo { + namespace scm { + /** + * Already in quoted-literal context + * + * [ quote-expr ... ] + * ^ ^ ^ + * | qarray_1a qarray_2(done) + * qarray_0 + * + * qarray_0 --on_leftbrace_token()--> qarray_1a [push ExpectQLiteralSsm] + * qarray_1a --on_quoted_literal()--> qarray_1a [append literal] + * qarray_1a --on_rightbrace_token()--> qarray_2(done) [report quoted array] + **/ + class QArrayXst { + public: + enum class code { + invalid = -1, + + qarray_0, + qarray_1a, + qarray_2, + + N + }; + + explicit QArrayXst(code x) : code_{x} {} + + /** @return string representation for enum @p x **/ + static const char * _descr(code x); + + code code() const noexcept { return code_; } + + enum code code_; + }; + + inline std::ostream & + operator<< (std::ostream & os, QArrayXst x) { + os << QArrayXst::_descr(x.code_); + return os; + } + + /** @class DExpectQArraySsm + * @brief parser state-machine for a literal array + **/ + class DExpectQArraySsm : public DSyntaxStateMachine { + public: + using Super = DSyntaxStateMachine; + using AAllocator = xo::mm::AAllocator; + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + /** @defgroup scm-expectqarrayssm-ctors constructors **/ + ///@{ + + DExpectQArraySsm(); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + static DExpectQArraySsm * _make(DArena & parser_mm); + + /** start nested syntax for a quoted literal **/ + static void start(ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectformalargarrayssm-methods general methods **/ + ///@{ + + static const char * ssm_classname() { return "DExpectQArraySsm"; } + + /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ + void on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm); + + void on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqarrayssm-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + /** mnemonic for expected input (for this ssm) in current state **/ + std::string_view get_expect_str() const; + + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm + **/ + void on_token(const Token & tk, + ParserStateMachine * p_psm); + + /** update state for nested qliteral @p lit, with overall parser state in @p p_psm. + * Appends @p lit to target array + **/ + void on_quoted_literal(obj lit, + ParserStateMachine * p_psm); + + ///@} + /** @defgroup scm-expectqarrayssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** @defgroup scm-expectqarrayssm-member-vars **/ + ///@{ + + /** identifies qarray parsing state **/ + QArrayXst state_; + + /** target array **/ + DArray * array_ = nullptr; + + ///@} + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectQArraySsm.hpp */ diff --git a/include/xo/reader2/DExpectQListSsm.hpp b/include/xo/reader2/DExpectQListSsm.hpp index 2b4b70b2..1ccd0bbe 100644 --- a/include/xo/reader2/DExpectQListSsm.hpp +++ b/include/xo/reader2/DExpectQListSsm.hpp @@ -53,7 +53,7 @@ namespace xo { } /** @class DExpectQListSsm - * @brief parser state-machine for a formal parameter list + * @brief parser state-machine for a literal list **/ class DExpectQListSsm : public DSyntaxStateMachine { public: @@ -120,21 +120,6 @@ namespace xo { ///@} - private: - /** @defgroup scm-expectqlistssm-impl-methods **/ - ///@{ - - /** update local state to include parsed formal (param_name, param_type). - * If stack memory needed, get from @p parser_alloc. - * Lifetime until formal arglist completely parsed - **/ - void _accept_formal(obj expr_alloc, - DArena & parser_alloc, - const DUniqueString * param_name, - TypeDescr param_type); - - ///@} - private: /** @defgroup scm-expectqlistssm-member-vars **/ ///@{ diff --git a/include/xo/reader2/DExpectQLiteralSsm.hpp b/include/xo/reader2/DExpectQLiteralSsm.hpp index efb93f6d..b8452961 100644 --- a/include/xo/reader2/DExpectQLiteralSsm.hpp +++ b/include/xo/reader2/DExpectQLiteralSsm.hpp @@ -24,17 +24,21 @@ namespace xo { using size_type = std::uint32_t; public: - explicit DExpectQLiteralSsm(bool cxl_on_rightparen); + explicit DExpectQLiteralSsm(bool cxl_on_rightparen, + bool cxl_on_rightbracket); /** create instance, using memory from @parser_mm **/ static obj make(DArena & parser_mm, - bool cxl_on_rightparen); + bool cxl_on_rightparen, + bool cxl_on_rightbracket); static DExpectQLiteralSsm * _make(DArena & parser_mm, - bool cxl_on_rightparen); + bool cxl_on_rightparen, + bool cxl_on_rightbracket); /** start nested syntax for a quoted literal **/ static void start(ParserStateMachine * p_psm, - bool cxl_on_rightparen = false); + bool cxl_on_rightparen = false, + bool cxl_on_rightbracket = false); /** @defgroup scm-expectformalarglistssm-methods general methods **/ ///@{ @@ -47,18 +51,38 @@ namespace xo { void on_f64_token(const Token & tk, ParserStateMachine * p_psm); - /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ + /** update state on incoming token @p tk, + * with overall parser state in @p p_psm. + * + * Forward in-place to ExpectQListSsm. + **/ void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); - /** update state on incoming token @p tk, with overall parser state in @p p_psm **/ - void on_comma_token(const Token & tk, - ParserStateMachine * p_psm); - - /** update state on incoming rightparen token @p tk, with overall parser state in @p p_psm **/ + /** update state on incoming rightparen token @p tk, + * with overall parser state in @p p_psm + * + * Error unless @ref cxl_on_rightparen_ + **/ void on_rightparen_token(const Token & tk, ParserStateMachine * p_psm); + /** update state on incoming leftbracket token @p tk, + * with overall parser state in @p p_psm. + * + * Forward in-place to ExpectQArraySsm + **/ + void on_leftbracket_token(const Token &tk, + ParserStateMachine * p_psm); + + /** update state on incoming rightbracket token @p tk, + * with overall parser state in @p p_psm. + * + * Error unless @ref cxl_on_rightbracket_ + **/ + void on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -101,6 +125,8 @@ namespace xo { private: /** if true rightparen pops + delegates to parent ssm **/ bool cxl_on_rightparen_ = false; + /** if true rightbracket pops + delegates to parent ssm **/ + bool cxl_on_rightbracket_ = false; }; } /*namespace scm*/ } /*namespace xo*/ diff --git a/include/xo/reader2/ExpectQArraySsm.hpp b/include/xo/reader2/ExpectQArraySsm.hpp new file mode 100644 index 00000000..78dcf1cb --- /dev/null +++ b/include/xo/reader2/ExpectQArraySsm.hpp @@ -0,0 +1,12 @@ +/** @file ExpectQArraySsm.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DExpectQArraySsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp" +#include "ssm/IPrintable_DExpectQArraySsm.hpp" + +/* end ExpectQArraySsm.hpp */ diff --git a/include/xo/reader2/ssm/IPrintable_DExpectQArraySsm.hpp b/include/xo/reader2/ssm/IPrintable_DExpectQArraySsm.hpp new file mode 100644 index 00000000..8c9b2c4a --- /dev/null +++ b/include/xo/reader2/ssm/IPrintable_DExpectQArraySsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectQArraySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQArraySsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectQArraySsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectQArraySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectQArraySsm + **/ + class IPrintable_DExpectQArraySsm { + public: + /** @defgroup scm-printable-dexpectqarrayssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectqarrayssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectQArraySsm & self, const ppindentinfo & ppii); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp new file mode 100644 index 00000000..78018537 --- /dev/null +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp @@ -0,0 +1,82 @@ +/** @file ISyntaxStateMachine_DExpectQArraySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectQArraySsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectQArraySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectQArraySsm + **/ + class ISyntaxStateMachine_DExpectQArraySsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectqarrayssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using AGCObject = xo::scm::ASyntaxStateMachine::AGCObject; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectqarrayssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectQArraySsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectQArraySsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectQArraySsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectQArraySsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectQArraySsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DExpectQArraySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal_with_token(DExpectQArraySsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DExpectQArraySsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for nested parsed expression @p expr **/ + static void on_parsed_expression(DExpectQArraySsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine @p p_psm for incoming parsed expression @p expr followed by token @p tk **/ + static void on_parsed_expression_with_token(DExpectQArraySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + /** update state machine for nested quoted literal @p lit **/ + static void on_quoted_literal(DExpectQArraySsm & self, obj lit, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/reader2/syntaxstatetype.hpp b/include/xo/reader2/syntaxstatetype.hpp index 0a0c857c..4d857d53 100644 --- a/include/xo/reader2/syntaxstatetype.hpp +++ b/include/xo/reader2/syntaxstatetype.hpp @@ -63,10 +63,13 @@ namespace xo { /** expecting a quoted literal. See @ref DExpectQLiteralSsm **/ expect_qliteral, - /** expecint a quoted list. See @ref DExpectQListSsm **/ + /** expecting a quoted list. See @ref DExpectQListSsm **/ expect_qlist, - /** comes lasts, counts number of valid enums **/ + /** expecting a quoted array. See @ref DExpectQArraySsm **/ + expect_qarray, + + /** comes last, counts number of valid enums **/ N }; diff --git a/src/reader2/CMakeLists.txt b/src/reader2/CMakeLists.txt index fa88a4dd..15a7a338 100644 --- a/src/reader2/CMakeLists.txt +++ b/src/reader2/CMakeLists.txt @@ -73,6 +73,10 @@ set(SELF_SRCS ISyntaxStateMachine_DExpectQListSsm.cpp IPrintable_DExpectQListSsm.cpp + DExpectQArraySsm.cpp + ISyntaxStateMachine_DExpectQArraySsm.cpp + IPrintable_DExpectQArraySsm.cpp + DProgressSsm.cpp ISyntaxStateMachine_DProgressSsm.cpp IPrintable_DProgressSsm.cpp diff --git a/src/reader2/DExpectQArraySsm.cpp b/src/reader2/DExpectQArraySsm.cpp new file mode 100644 index 00000000..b4a9ac29 --- /dev/null +++ b/src/reader2/DExpectQArraySsm.cpp @@ -0,0 +1,222 @@ +/** @file DExpectQArraySsm.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "ExpectQArraySsm.hpp" +#include "ExpectQLiteralSsm.hpp" +#include +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::mm::AGCObject; + + namespace scm { + const char * + QArrayXst::_descr(enum code x) + { + switch (x) { + case code::invalid: break; + case code::qarray_0: return "qarray_0"; + case code::qarray_1a: return "qarray_1a"; + case code::qarray_2: return "qarray_2"; + case code::N: break; + } + + return "?QArrayXst"; + } + + DExpectQArraySsm::DExpectQArraySsm() : state_{QArrayXst::code::qarray_0} {} + + obj + DExpectQArraySsm::make(DArena & parser_mm) + { + return obj(_make(parser_mm)); + } + + DExpectQArraySsm * + DExpectQArraySsm::_make(DArena & parser_mm) + { + void * mem = parser_mm.alloc_for(); + + return new (mem) DExpectQArraySsm(); + } + + void + DExpectQArraySsm::start(ParserStateMachine * p_psm) + { + DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); + + p_psm->push_ssm(ckp, DExpectQArraySsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectQArraySsm::ssm_type() const noexcept { + return syntaxstatetype::expect_qarray; + } + + std::string_view + DExpectQArraySsm::get_expect_str() const { + switch (state_.code()) { + case QArrayXst::code::qarray_0: + return "leftparen"; + case QArrayXst::code::qarray_1a: + return "qliteral|rightparen"; + case QArrayXst::code::qarray_2: + return "(done)"; + case QArrayXst::code::invalid: + case QArrayXst::code::N: + break; + } + + return "?DExpectQArraySsm"; + } + + void + DExpectQArraySsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch(tk.tk_type()) + { + case tokentype::tk_leftbracket: + this->on_leftbracket_token(tk, p_psm); + return; + + case tokentype::tk_rightbracket: + this->on_rightbracket_token(tk, p_psm); + return; + + case tokentype::tk_comma: + case tokentype::tk_lambda: + case tokentype::tk_def: + case tokentype::tk_if: + case tokentype::tk_symbol: + case tokentype::tk_colon: + case tokentype::tk_singleassign: + case tokentype::tk_string: + case tokentype::tk_f64: + case tokentype::tk_i64: + case tokentype::tk_bool: + case tokentype::tk_semicolon: + case tokentype::tk_invalid: + case tokentype::tk_quote: + case tokentype::tk_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbrace: + case tokentype::tk_rightbrace: + case tokentype::tk_leftangle: + case tokentype::tk_rightangle: + case tokentype::tk_lessequal: + case tokentype::tk_greatequal: + case tokentype::tk_dot: + case tokentype::tk_doublecolon: + case tokentype::tk_assign: + case tokentype::tk_yields: + case tokentype::tk_plus: + case tokentype::tk_minus: + case tokentype::tk_star: + case tokentype::tk_slash: + case tokentype::tk_cmpeq: + case tokentype::tk_cmpne: + case tokentype::tk_type: + case tokentype::tk_then: + case tokentype::tk_else: + case tokentype::tk_let: + case tokentype::tk_in: + case tokentype::tk_end: + case tokentype::N: + break; + } + } + + void + DExpectQArraySsm::on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QArrayXst::code::qarray_0) { + this->state_ = QArrayXst(QArrayXst::code::qarray_1a); + + this->array_ = DArray::empty(p_psm->expr_alloc(), + 8 /*heuristic starting capacity*/); + + DExpectQLiteralSsm::start(p_psm, + false /*cxl_on_rightparen*/, + true /*cxl_on_rightbracket*/); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQArraySsm::on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (state_.code() == QArrayXst::code::qarray_1a) { + this->state_ = QArrayXst(QArrayXst::code::qarray_2); + + array_->shrink_to_fit(); + + obj lit = obj(array_); + + p_psm->pop_ssm(); + p_psm->on_quoted_literal(lit); + return; + } + + Super::illegal_token(tk, p_psm); + } + + void + DExpectQArraySsm::on_quoted_literal(obj lit, + ParserStateMachine * p_psm) + { + if(state_.code() == QArrayXst::code::qarray_1a) { + // append lit at the end of array_ + { + assert(array_); + + // ensure sufficient capacity + if (array_->size() == array_->capacity()) { + assert(array_->capacity() > 0); + + /* reallocate w/ 2x capacity */ + this->array_ = DArray::copy(p_psm->expr_alloc(), + array_, + 2 * array_->capacity()); + } + + bool ok = array_->push_back(lit); + + assert(ok); + } + + // start syntax to receive next literal + DExpectQLiteralSsm::start(p_psm, + false /*cxl_on_rightparen*/, + true /*cxl_on_rightbracket*/); + return; + } + + Super::illegal_quoted_literal(lit, p_psm); + } + + bool + DExpectQArraySsm::pretty(const ppindentinfo & ppii) const + { + obj array(array_); + auto array_pr = FacetRegistry::instance().variant(array); + + return ppii.pps()->pretty_struct(ppii, + "DExpectQArraySsm", + refrtag("state", state_), + refrtag("expect", this->get_expect_str()), + refrtag("array", array_pr)); + } + } +} + +/* end DExpectQArraySsm.cpp */ diff --git a/src/reader2/DExpectQLiteralSsm.cpp b/src/reader2/DExpectQLiteralSsm.cpp index efc92a48..e03e7a39 100644 --- a/src/reader2/DExpectQLiteralSsm.cpp +++ b/src/reader2/DExpectQLiteralSsm.cpp @@ -5,6 +5,7 @@ #include "ExpectQLiteralSsm.hpp" #include "ExpectQListSsm.hpp" +#include "ExpectQArraySsm.hpp" #include //#include "DExpectFormalArgSsm.hpp" //#include "ssm/ISyntaxStateMachine_DExpectFormalArgSsm.hpp" @@ -25,13 +26,16 @@ namespace xo { // using xo::reflect::typeseq; namespace scm { - DExpectQLiteralSsm::DExpectQLiteralSsm(bool cxl_on_rightparen) - : cxl_on_rightparen_{cxl_on_rightparen} + DExpectQLiteralSsm::DExpectQLiteralSsm(bool cxl_on_rightparen, + bool cxl_on_rightbracket) + : cxl_on_rightparen_{cxl_on_rightparen}, + cxl_on_rightbracket_{cxl_on_rightbracket} {} DExpectQLiteralSsm * DExpectQLiteralSsm::_make(DArena & arena, - bool cxl_on_rightparen) + bool cxl_on_rightparen, + bool cxl_on_rightbracket) { /* out-of-order so argl follows ssm in arena, * consistent with any subsequent arglist realloc. @@ -40,26 +44,30 @@ namespace xo { void * mem = arena.alloc_for(); - return new (mem) DExpectQLiteralSsm(cxl_on_rightparen); + return new (mem) DExpectQLiteralSsm(cxl_on_rightparen, cxl_on_rightbracket); } obj DExpectQLiteralSsm::make(DArena & arena, - bool cxl_on_rightparen) + bool cxl_on_rightparen, + bool cxl_on_rightbracket) { obj retval(_make(arena, - cxl_on_rightparen)); + cxl_on_rightparen, + cxl_on_rightbracket)); return retval; } void DExpectQLiteralSsm::start(ParserStateMachine * p_psm, - bool cxl_on_rightparen) + bool cxl_on_rightparen, + bool cxl_on_rightbracket) { DArena::Checkpoint ckp = p_psm->parser_alloc().checkpoint(); p_psm->push_ssm(ckp, DExpectQLiteralSsm::make(p_psm->parser_alloc(), - cxl_on_rightparen)); + cxl_on_rightparen, + cxl_on_rightbracket)); } syntaxstatetype @@ -78,6 +86,7 @@ namespace xo { ParserStateMachine * p_psm) { switch (tk.tk_type()) { + case tokentype::tk_f64: this->on_f64_token(tk, p_psm); return; @@ -90,6 +99,14 @@ namespace xo { this->on_rightparen_token(tk, p_psm); return; + case tokentype::tk_leftbracket: + this->on_leftbracket_token(tk, p_psm); + return; + + case tokentype::tk_rightbracket: + this->on_rightbracket_token(tk, p_psm); + return; + case tokentype::tk_comma: case tokentype::tk_lambda: case tokentype::tk_def: @@ -103,8 +120,6 @@ namespace xo { case tokentype::tk_semicolon: case tokentype::tk_invalid: case tokentype::tk_quote: - case tokentype::tk_leftbracket: - case tokentype::tk_rightbracket: case tokentype::tk_leftbrace: case tokentype::tk_rightbrace: case tokentype::tk_leftangle: @@ -200,22 +215,6 @@ namespace xo { p_psm->on_token(tk); } -#ifdef NOT_YET - void - DExpectQLiteralSsm::on_comma_token(const Token & tk, - ParserStateMachine * p_psm) - { - if (fastate_ == formalarglstatetype::argl_1b) { - this->fastate_ = formalarglstatetype::argl_1a; - - DExpectFormalArgSsm::start(p_psm); - return; - } - - Super::on_token(tk, p_psm); - } -#endif - void DExpectQLiteralSsm::on_rightparen_token(const Token & tk, ParserStateMachine * p_psm) @@ -226,7 +225,31 @@ namespace xo { return; } - Super::on_token(tk, p_psm); + Super::illegal_token(tk, p_psm); + } + + void + DExpectQLiteralSsm::on_leftbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + // replace self with specialized version for parsing a literal array + + p_psm->pop_ssm(); + DExpectQArraySsm::start(p_psm); + p_psm->on_token(tk); + } + + void + DExpectQLiteralSsm::on_rightbracket_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (cxl_on_rightbracket_) { + p_psm->pop_ssm(); + p_psm->on_token(tk); + return; + } + + Super::illegal_token(tk, p_psm); } bool diff --git a/src/reader2/IPrintable_DExpectQArraySsm.cpp b/src/reader2/IPrintable_DExpectQArraySsm.cpp new file mode 100644 index 00000000..b3f875d9 --- /dev/null +++ b/src/reader2/IPrintable_DExpectQArraySsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectQArraySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectQArraySsm.json5] +**/ + +#include "ssm/IPrintable_DExpectQArraySsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectQArraySsm::pretty(const DExpectQArraySsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectQArraySsm.cpp */ diff --git a/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp b/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp new file mode 100644 index 00000000..32d8bfd1 --- /dev/null +++ b/src/reader2/ISyntaxStateMachine_DExpectQArraySsm.cpp @@ -0,0 +1,79 @@ +/** @file ISyntaxStateMachine_DExpectQArraySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectQArraySsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectQArraySsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectQArraySsm::ssm_type(const DExpectQArraySsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectQArraySsm::get_expect_str(const DExpectQArraySsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectQArraySsm::on_token(DExpectQArraySsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_symbol(DExpectQArraySsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_typedescr(DExpectQArraySsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_formal(DExpectQArraySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_formal_with_token(DExpectQArraySsm & self, const DUniqueString * param_name, TypeDescr param_type, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_with_token(param_name, param_type, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_formal_arglist(DExpectQArraySsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_expression(DExpectQArraySsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_parsed_expression_with_token(DExpectQArraySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectQArraySsm::on_quoted_literal(DExpectQArraySsm & self, obj lit, ParserStateMachine * p_psm) -> void + { + self.on_quoted_literal(lit, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectQArraySsm.cpp */ diff --git a/src/reader2/reader2_register_facets.cpp b/src/reader2/reader2_register_facets.cpp index 1df5cb82..909c1bc2 100644 --- a/src/reader2/reader2_register_facets.cpp +++ b/src/reader2/reader2_register_facets.cpp @@ -23,6 +23,7 @@ #include "ExpectExprSsm.hpp" #include "ExpectQLiteralSsm.hpp" #include "ExpectQListSsm.hpp" +#include "ExpectQArraySsm.hpp" #include #include @@ -87,6 +88,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + // misc types showing up in aux arena TypeRegistry::register_type(); // misc types showing up in parser stack arena @@ -103,6 +107,7 @@ namespace xo { log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); log && log(xtag("DExpectQLiteralSsm.tseq", typeseq::id())); log && log(xtag("DExpectQListSsm.tseq", typeseq::id())); + log && log(xtag("DExpectQArraySsm.tseq", typeseq::id())); log && log(xtag("DProgressSsm.tseq", typeseq::id())); log && log(xtag("DParenSsm.tseq", typeseq::id())); diff --git a/src/reader2/syntaxstatetype.cpp b/src/reader2/syntaxstatetype.cpp index f1d93239..9b6c0928 100644 --- a/src/reader2/syntaxstatetype.cpp +++ b/src/reader2/syntaxstatetype.cpp @@ -45,6 +45,8 @@ namespace xo { return "expect-qliteral"; case syntaxstatetype::expect_qlist: return "expect-qlist"; + case syntaxstatetype::expect_qarray: + return "expect-qarray"; case syntaxstatetype::N: break; } diff --git a/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index 17022d42..0404a800 100644 --- a/utest/SchematikaParser.test.cpp +++ b/utest/SchematikaParser.test.cpp @@ -1287,7 +1287,7 @@ namespace xo { const auto & testname = Catch::getResultCapture().getCurrentTestName(); - constexpr bool c_debug_flag = true; + constexpr bool c_debug_flag = false; scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); ParserFixture fixture(testname, c_debug_flag); @@ -1319,6 +1319,44 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-batch-qarray", "[reader2][SchematikaParser]") + { + // top-level recursive function definition + + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag), xtag("test", testname)); + + ParserFixture fixture(testname, c_debug_flag); + auto & parser = *(fixture.parser_); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * #q{ [4.5 7.2] }; + * ^ ^ ^^ ^ ^ ^^ + * 0 1 2| 4 5 6| + * 3 7 + **/ + + std::vector tk_v{ + /* [ 0] */ Token::quote_token(), + /* [ 1] */ Token::leftbrace_token(), + /* [ 2] */ Token::leftbracket_token(), + /* [ 3] */ Token::f64_token("4.5"), + /* [ 4] */ Token::f64_token("7.2"), + /* [ 5] */ Token::rightbracket_token(), + /* [ 6] */ Token::rightbrace_token(), + /* [ 7] */ Token::semicolon_token(), + }; + + utest_tokenizer_loop(&parser, tk_v, c_debug_flag); + + log && fixture.log_memory_layout(&log); + } + } /*namespace ut*/ } /*namespace xo*/