From 65d1fd840b9609818aca609c56d54bad32019a5b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 11 Feb 2026 18:07:55 -0500 Subject: [PATCH] xo-reader2: progress+apply works up to lparen introducing formals --- CMakeLists.txt | 26 +++++++ idl/IPrintable_DApplySsm.json5 | 13 ++++ idl/ISyntaxStateMachine_DApplySsm.json5 | 13 ++++ include/xo/reader2/ApplySsm.hpp | 12 +++ include/xo/reader2/DApplySsm.hpp | 18 ++++- include/xo/reader2/SequenceSsm.hpp | 13 ++++ .../xo/reader2/ssm/IPrintable_DApplySsm.hpp | 62 +++++++++++++++ .../ssm/ISyntaxStateMachine_DApplySsm.hpp | 77 +++++++++++++++++++ src/reader2/CMakeLists.txt | 4 +- src/reader2/DApplySsm.cpp | 36 +++++++-- src/reader2/DProgressSsm.cpp | 42 +++++++--- src/reader2/IPrintable_DApplySsm.cpp | 28 +++++++ src/reader2/ISyntaxStateMachine_DApplySsm.cpp | 69 +++++++++++++++++ src/reader2/reader2_register_facets.cpp | 7 +- 14 files changed, 393 insertions(+), 27 deletions(-) create mode 100644 idl/IPrintable_DApplySsm.json5 create mode 100644 idl/ISyntaxStateMachine_DApplySsm.json5 create mode 100644 include/xo/reader2/ApplySsm.hpp create mode 100644 include/xo/reader2/SequenceSsm.hpp create mode 100644 include/xo/reader2/ssm/IPrintable_DApplySsm.hpp create mode 100644 include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp create mode 100644 src/reader2/IPrintable_DApplySsm.cpp create mode 100644 src/reader2/ISyntaxStateMachine_DApplySsm.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d1e807e6..7bfc86f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,6 +244,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-applyssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ApplySsm + INPUT idl/ISyntaxStateMachine_DApplySsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-printable-applyssm + FACET_PKG xo_printable2 + FACET Printable + REPR ApplySsm + INPUT idl/IPrintable_DApplySsm.json5 + OUTPUT_HPP_DIR include/xo/reader2 + OUTPUT_IMPL_SUBDIR ssm + OUTPUT_CPP_DIR src/reader2 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-reader2-facetimpl-syntaxstatemachine-expectsymbolssm diff --git a/idl/IPrintable_DApplySsm.json5 b/idl/IPrintable_DApplySsm.json5 new file mode 100644 index 00000000..cdcd32ca --- /dev/null +++ b/idl/IPrintable_DApplySsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DApplySsm", + using_doxygen: true, + repr: "DApplySsm", + doc: [ "implement APrintable for DApplySsm" ], +} diff --git a/idl/ISyntaxStateMachine_DApplySsm.json5 b/idl/ISyntaxStateMachine_DApplySsm.json5 new file mode 100644 index 00000000..7806d2cb --- /dev/null +++ b/idl/ISyntaxStateMachine_DApplySsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "\"SyntaxStateMachine.hpp\"", + "\"ssm/ISyntaxStateMachine_Xfer.hpp\"" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/SyntaxStateMachine.json5", + brief: "provide ASyntaxStateMachine interface for DApplySsm", + using_doxygen: true, + repr: "DApplySsm", + doc: [ "implement ASyntaxStateMachine for DApplySsm" ], +} diff --git a/include/xo/reader2/ApplySsm.hpp b/include/xo/reader2/ApplySsm.hpp new file mode 100644 index 00000000..6e9f9a9d --- /dev/null +++ b/include/xo/reader2/ApplySsm.hpp @@ -0,0 +1,12 @@ +/** @file ApplySsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DApplySsm.hpp" +#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" +#include "ssm/IPrintable_DApplySsm.hpp" + +/* end ApplySsm.hpp */ diff --git a/include/xo/reader2/DApplySsm.hpp b/include/xo/reader2/DApplySsm.hpp index 34c78f78..46f9097b 100644 --- a/include/xo/reader2/DApplySsm.hpp +++ b/include/xo/reader2/DApplySsm.hpp @@ -89,10 +89,11 @@ namespace xo { static DApplySsm * make(DArena & parser_mm, obj fn_expr); -#ifdef NOT_YET /** * Start apply. Will trigger this after input like * "fn(" + * or + * "makefn()()" * * apply_xs remains on expr stack until closing right paren * fn(arg1-expr, arg2-expr, ...) @@ -100,9 +101,8 @@ namespace xo { * @p fnex expression in function position * @p p_psm parser state machine **/ - static void start(rp fnex, - parserstatemachine * p_psm); -#endif + static void start(obj fnex, + ParserStateMachine * p_psm); ///@} /** @defgroup scm-applyssm-access methods **/ @@ -124,6 +124,8 @@ namespace xo { /** mnemonic for expected remaining syntax for current parsing state **/ std::string_view get_expect_str() const noexcept; + ///@} + #ifdef NOT_YET virtual void on_expr(bp expr, @@ -143,6 +145,14 @@ namespace xo { static std::unique_ptr make(); #endif + /** @defgroup ssm-applyssm-printable-facet printable facet **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + private: /** current state of parser for this apply expression **/ applyexprstatetype applystate_ = applyexprstatetype::apply_0; diff --git a/include/xo/reader2/SequenceSsm.hpp b/include/xo/reader2/SequenceSsm.hpp new file mode 100644 index 00000000..0e82e081 --- /dev/null +++ b/include/xo/reader2/SequenceSsm.hpp @@ -0,0 +1,13 @@ +/** @file SequenceSsm.hpp + * + * @author Roland Conybeare, Feb 2026 + **/ + +#pragma once + +#include "DSequenceSsm.hpp" +#include "ssm/ISyntaxStateMachine_DSequenceSsm.hpp" +#include "ssm/IPrintable_DSequenceSsm.hpp" + +/* end SequenceSsm.hpp */ + diff --git a/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp b/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp new file mode 100644 index 00000000..3bae71f2 --- /dev/null +++ b/include/xo/reader2/ssm/IPrintable_DApplySsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DApplySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplySsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DApplySsm.hpp" + +namespace xo { namespace scm { class IPrintable_DApplySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DApplySsm + **/ + class IPrintable_DApplySsm { + public: + /** @defgroup scm-printable-dapplyssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dapplyssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DApplySsm & 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_DApplySsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp new file mode 100644 index 00000000..d6b1a53e --- /dev/null +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DApplySsm.hpp @@ -0,0 +1,77 @@ +/** @file ISyntaxStateMachine_DApplySsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DApplySsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DApplySsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DApplySsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DApplySsm + **/ + class ISyntaxStateMachine_DApplySsm { + public: + /** @defgroup scm-syntaxstatemachine-dapplyssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dapplyssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DApplySsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DApplySsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DApplySsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DApplySsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DApplySsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** operate state machine for formal emitted by nested ssm **/ + static void on_parsed_formal(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm); + /** consume formal arglist emitted by nested ssm **/ + static void on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DApplySsm & 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(DApplySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm); + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/src/reader2/CMakeLists.txt b/src/reader2/CMakeLists.txt index b6d9bed0..5c98e209 100644 --- a/src/reader2/CMakeLists.txt +++ b/src/reader2/CMakeLists.txt @@ -38,8 +38,8 @@ set(SELF_SRCS IPrintable_DLambdaSsm.cpp DApplySsm.cpp - # ISyntaxStateMachine_DApplySsm.cpp - # IPrintable_DApplySsm.cpp + ISyntaxStateMachine_DApplySsm.cpp + IPrintable_DApplySsm.cpp DParenSsm.cpp ISyntaxStateMachine_DParenSsm.cpp diff --git a/src/reader2/DApplySsm.cpp b/src/reader2/DApplySsm.cpp index f58ce7d4..217c60b2 100644 --- a/src/reader2/DApplySsm.cpp +++ b/src/reader2/DApplySsm.cpp @@ -3,13 +3,14 @@ * @author Roland Conybeare, Feb 2026 **/ -#include "DApplySsm.hpp" +#include "ApplySsm.hpp" #include //#include "parserstatemachine.hpp" //#include "expect_expr_xs.hpp" namespace xo { + using xo::print::APrintable; using xo::reflect::typeseq; namespace scm { @@ -60,18 +61,21 @@ namespace xo { return new (mem) DApplySsm(fn_expr); } -#ifdef NOT_YET void - apply_xs::start(rp fn_expr, - parserstatemachine * p_psm) + DApplySsm::start(obj fn_expr, + ParserStateMachine * p_psm) { scope log(XO_DEBUG(p_psm->debug_flag())); - p_psm->push_exprstate(apply_xs::make()); - p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); - p_psm->top_exprstate().on_leftparen_token(token_type::leftparen(), p_psm); + DApplySsm * apply_ssm + = DApplySsm::make(p_psm->parser_alloc(), fn_expr); + + obj ssm(apply_ssm); + + p_psm->push_ssm(ssm); + //OBSOLETE //p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm); + //OBSOLETE //p_psm->on_token(token_type::leftparen(), p_psm); } -#endif syntaxstatetype DApplySsm::ssm_type() const noexcept { @@ -194,7 +198,23 @@ namespace xo { this->illegal_input_on_token(c_self_name, tk, exp, p_psm); } +#endif + bool + DApplySsm::pretty(const ppindentinfo & ppii) const + { + // TODO: const-correct version of obj<> template + auto fn_expr = const_cast(this)->fn_expr_.to_facet(); + bool fn_expr_present(fn_expr); + + return ppii.pps()->pretty_struct(ppii, + "DApplySsm", + refrtag("applystate", applystate_), + refrtag("expect", this->get_expect_str()), + refrtag("fn_expr", fn_expr, fn_expr_present)); + } + +#ifdef NOT_YET void apply_xs::print(std::ostream & os) const { diff --git a/src/reader2/DProgressSsm.cpp b/src/reader2/DProgressSsm.cpp index 0a28fd60..19d318f6 100644 --- a/src/reader2/DProgressSsm.cpp +++ b/src/reader2/DProgressSsm.cpp @@ -9,6 +9,7 @@ #include "DExpectExprSsm.hpp" #include "ssm/ISyntaxStateMachine_DExpectExprSsm.hpp" +#include "ApplySsm.hpp" #include "ParenSsm.hpp" #include @@ -20,21 +21,13 @@ #include // for xo::scm::Primitives #include -#ifdef NOT_YET -#include "DApplySsm.hpp" -#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" -#endif - #include #include #include #include #ifdef NOT_YET -#include "apply_xs.hpp" -#include "exprstatestack.hpp" #include "expect_expr_xs.hpp" -#include "parserstatemachine.hpp" #include "pretty_exprstatestack.hpp" #include "xo/expression/AssignExpr.hpp" #include "xo/expression/Apply.hpp" @@ -912,12 +905,39 @@ namespace xo { } if (op_type_ == optype::invalid) { - // leftparen begins function call arguments. - // .lhs_ now understood to be expression that evaluates to a - // function + // input: + /// <--- F1 ---> + // (..........)(.. ).. + // <------ A1 -----> + // <------- X1 ------> + // + // F1: expression evaluating to a function, + // parsed as fn_expr + // A1: expression parsed as a function call (i.e. apply-expression) + // X1: operator expression starting with A1 + // + // before: + // [0] ProgressSsm responsible for input beginning with F1 + // .lhs = fn_expr, .op_type empty, .rhs empty + // + // after: + // [0] ApplySsm responsible for function call A1 + // .fn_expr = fn_expr + // [1] ProgressSsm responsible for operator expression X1 + // .lhs empty, .op_type empty, .rhs empty + // + // Remarks: + // 1. keep ProgressSsm on the stack in case input continues like: + // fn_expr(args..) + .. + // i.e. to allow for infix operator following apply + // + obj fn_expr(this->lhs_); + this->lhs_ = obj(); + DApplySsm::start(fn_expr, p_psm); + return; } Super::on_token(tk, p_psm); diff --git a/src/reader2/IPrintable_DApplySsm.cpp b/src/reader2/IPrintable_DApplySsm.cpp new file mode 100644 index 00000000..5066b082 --- /dev/null +++ b/src/reader2/IPrintable_DApplySsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DApplySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DApplySsm.json5] +**/ + +#include "ssm/IPrintable_DApplySsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DApplySsm::pretty(const DApplySsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DApplySsm.cpp */ diff --git a/src/reader2/ISyntaxStateMachine_DApplySsm.cpp b/src/reader2/ISyntaxStateMachine_DApplySsm.cpp new file mode 100644 index 00000000..2164ae04 --- /dev/null +++ b/src/reader2/ISyntaxStateMachine_DApplySsm.cpp @@ -0,0 +1,69 @@ +/** @file ISyntaxStateMachine_DApplySsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DApplySsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DApplySsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DApplySsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DApplySsm::ssm_type(const DApplySsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DApplySsm::get_expect_str(const DApplySsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DApplySsm::on_token(DApplySsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_symbol(DApplySsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_typedescr(DApplySsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_formal(DApplySsm & self, const DUniqueString * param_name, TypeDescr param_type, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal(param_name, param_type, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_formal_arglist(DApplySsm & self, DArray * arglist, ParserStateMachine * p_psm) -> void + { + self.on_parsed_formal_arglist(arglist, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_expression(DApplySsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DApplySsm::on_parsed_expression_with_token(DApplySsm & self, obj expr, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_token(expr, tk, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DApplySsm.cpp */ diff --git a/src/reader2/reader2_register_facets.cpp b/src/reader2/reader2_register_facets.cpp index 3955fae3..eb39f6ac 100644 --- a/src/reader2/reader2_register_facets.cpp +++ b/src/reader2/reader2_register_facets.cpp @@ -17,8 +17,8 @@ #include #include -#include - +#include "ApplySsm.hpp" +#include "SequenceSsm.hpp" #include "ParenSsm.hpp" #include @@ -67,6 +67,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + + FacetRegistry::register_impl(); FacetRegistry::register_impl(); FacetRegistry::register_impl();