diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ebdf95c..a1028a18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,32 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-reader2-facetimpl-syntaxstatemachine-expectformalarglistssm + FACET_PKG xo_reader2 + FACET SyntaxStateMachine + REPR ExpectFormalArglistSsm + INPUT idl/ISyntaxStateMachine_DExpectFormalArglistSsm.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-expectformalarglistssm + FACET_PKG xo_printable2 + FACET Printable + REPR ExpectFormalArglistSsm + INPUT idl/IPrintable_DExpectFormalArglistSsm.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-ifelsessm diff --git a/idl/IPrintable_DExpectFormalArglistSsm.json5 b/idl/IPrintable_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..44f474dd --- /dev/null +++ b/idl/IPrintable_DExpectFormalArglistSsm.json5 @@ -0,0 +1,13 @@ +{ + mode: "implementation", + includes: [ "", + "" ], + local_types: [], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DExpectFormalArglistSsm", + using_doxygen: true, + repr: "DExpectFormalArglistSsm", + doc: [ "implement APrintable for DExpectFormalArglistSsm" ], +} diff --git a/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 b/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5 new file mode 100644 index 00000000..d3e16953 --- /dev/null +++ b/idl/ISyntaxStateMachine_DExpectFormalArglistSsm.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 DExpectFormalArglistSsm", + using_doxygen: true, + repr: "DExpectFormalArglistSsm", + doc: [ "implement ASyntaxStateMachine for DExpectFormalArglistSsm" ], +} diff --git a/include/xo/reader2/DExpectFormalArglistSsm.hpp b/include/xo/reader2/DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..5b32c760 --- /dev/null +++ b/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -0,0 +1,146 @@ +/** @file DExpectFormalArglistSsm.hpp + * + * @author Roland Conybeare, Aug 2024 + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include +#include + +#ifdef NOT_YET +#include "exprstate.hpp" +#include "formal_arg.hpp" +#include +#endif + +namespace xo { + namespace scm { + /** + * ( name(1) : type(1) , ..., ) + * ^ ^ ^ ^ ^ + * | | | | | + * | | | | argl_1b + * | argl_1a | argl_1a + * argl_0 argl_1b + * + * argl_0 --on_leftparen_token()--> argl_1a + * argl_1a --on_formal()--> argl_1b + * argl_1b -+-on_comma_token()--> argl_1a + * \-on_rightparen_token()--> (done) + **/ + enum class formalarglstatetype { + invalid = -1, + + argl_0, + argl_1a, + argl_1b, + + n_formalarglstatetype, + }; + + extern const char * + formalarglstatetype_descr(formalarglstatetype x); + + inline std::ostream & + operator<< (std::ostream & os, formalarglstatetype x) { + os << formalarglstatetype_descr(x); + return os; + } + + /** @class expect_formal_arglist + * @brief parser state-machine for a formal parameter list + **/ + class DExpectFormalArglistSsm { + public: + using DArena = xo::mm::DArena; + using TypeDescr = xo::reflect::TypeDescr; + using ppindentinfo = xo::print::ppindentinfo; + using size_type = std::uint32_t; + + public: + DExpectFormalArglistSsm(DArray * argl); + + /** create instance, using memory from @parser_mm **/ + static obj make(DArena & parser_mm); + static DExpectFormalArglistSsm * _make(DArena & parser_mm); + + static void start(ParserStateMachine * p_psm); + + /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ + ///@{ + + /** identifies the ssm implemented here **/ + syntaxstatetype ssm_type() const noexcept; + + 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 on parsed symbol @p sym emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm); + + /** update state on parsed typedescr @p td emitted by nested ssm, + * with overall parser state in @p p_psm + **/ + void on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm); + + /** update state on parsed expression emitted by nested ssm + * with overall parser state in @p p_psm + **/ + void on_parsed_expression(obj expr, + ParserStateMachine * p_psm); + + /** update state on parsed expression, along with following semicolon, + * emitted by nested ssm with overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + +#ifdef NOT_YET + + virtual void on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_formal(const rp & formal, + parserstatemachine * p_psm) override; + virtual void on_comma_token(const token_type & tk, + parserstatemachine * p_psm) override; + virtual void on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) override; +#endif + + ///@} + /** @defgroup scm-expectformalarglistssm-printable-facet printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + + private: + /** parsing state-machine state **/ + formalarglstatetype fastate_ = formalarglstatetype::argl_0; + /** number of formal parameters encountered. + * Invariant: n_args_ <= argl_->size() + **/ + size_type n_args_ = 0; + /** populate with (parmaeter-name, parameter-type) list + * as they're encountered. + * + * Not using flexible array here since we don't know size + **/ + DArray * argl_ = nullptr; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DExpectFormalArglistSsm.hpp */ diff --git a/include/xo/reader2/DExprSeqState.hpp b/include/xo/reader2/DExprSeqState.hpp index 72566004..96eea236 100644 --- a/include/xo/reader2/DExprSeqState.hpp +++ b/include/xo/reader2/DExprSeqState.hpp @@ -81,6 +81,11 @@ namespace xo { **/ void on_def_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming lamdba token @p tk, + * overall parser state in @p p_psm + **/ + void on_lambda_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm **/ diff --git a/include/xo/reader2/DLambdaSsm.hpp b/include/xo/reader2/DLambdaSsm.hpp index bb110165..d9b0754d 100644 --- a/include/xo/reader2/DLambdaSsm.hpp +++ b/include/xo/reader2/DLambdaSsm.hpp @@ -59,6 +59,7 @@ namespace xo { public: //using DSymbolTable = xo::scm::DSymbolTable; using DLocalSymtab = xo::scm::DLocalSymtab; + using AAllocator = xo::mm::AAllocator; using DArena = xo::mm::DArena; using TypeDescr = xo::reflect::TypeDescr; using ppindentinfo = xo::print::ppindentinfo; @@ -81,6 +82,12 @@ namespace xo { static void start(ParserStateMachine * p_psm); + /** update ssm on lambda keyword token @p tk, + * with overall parser state in @p p_psm + **/ + void on_lambda_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-lambdassm-syntaxstatemachine-facet **/ ///@{ @@ -124,8 +131,6 @@ namespace xo { #ifdef NOT_YET virtual const char * get_expect_str() const override; - virtual void on_lambda_token(const token_type & tk, - parserstatemachine * p_psm) override; virtual void on_typedescr(TypeDescr td, parserstatemachine * p_psm) override; virtual void on_formal_arglist(const std::vector> & argl, diff --git a/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp b/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..7b5479b7 --- /dev/null +++ b/include/xo/reader2/ssm/IPrintable_DExpectFormalArglistSsm.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DExpectFormalArglistSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArglistSsm.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DExpectFormalArglistSsm.hpp" + +namespace xo { namespace scm { class IPrintable_DExpectFormalArglistSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DExpectFormalArglistSsm + **/ + class IPrintable_DExpectFormalArglistSsm { + public: + /** @defgroup scm-printable-dexpectformalarglistssm-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-dexpectformalarglistssm-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DExpectFormalArglistSsm & 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_DExpectFormalArglistSsm.hpp b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp new file mode 100644 index 00000000..93154f83 --- /dev/null +++ b/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp @@ -0,0 +1,73 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + **/ + +#pragma once + +#include "SyntaxStateMachine.hpp" +#include "SyntaxStateMachine.hpp" +#include "ssm/ISyntaxStateMachine_Xfer.hpp" +#include "DExpectFormalArglistSsm.hpp" + +namespace xo { namespace scm { class ISyntaxStateMachine_DExpectFormalArglistSsm; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::ISyntaxStateMachine_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class ISyntaxStateMachine_DExpectFormalArglistSsm + **/ + class ISyntaxStateMachine_DExpectFormalArglistSsm { + public: + /** @defgroup scm-syntaxstatemachine-dexpectformalarglistssm-type-traits **/ + ///@{ + using TypeDescr = xo::scm::ASyntaxStateMachine::TypeDescr; + using Copaque = xo::scm::ASyntaxStateMachine::Copaque; + using Opaque = xo::scm::ASyntaxStateMachine::Opaque; + ///@} + /** @defgroup scm-syntaxstatemachine-dexpectformalarglistssm-methods **/ + ///@{ + // const methods + /** identify a type of syntax state machine **/ + static syntaxstatetype ssm_type(const DExpectFormalArglistSsm & self) noexcept; + /** text describing expected/allowed input to this ssm in current state **/ + static std::string_view get_expect_str(const DExpectFormalArglistSsm & self) noexcept; + + // non-const methods + /** operate state machine for incoming token @p tk **/ + static void on_token(DExpectFormalArglistSsm & self, const Token & tk, ParserStateMachine * p_psm); + /** update stat machine for incoming parsed symbol @p sym **/ + static void on_parsed_symbol(DExpectFormalArglistSsm & self, std::string_view sym, ParserStateMachine * p_psm); + /** operate state machine for incoming type description @p td **/ + static void on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr **/ + static void on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm); + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + static void on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, 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 074a5aec..2eb34122 100644 --- a/include/xo/reader2/syntaxstatetype.hpp +++ b/include/xo/reader2/syntaxstatetype.hpp @@ -21,6 +21,9 @@ namespace xo { /** toplevel of some translation unit. See @ref DExprSeqState **/ expect_toplevel_expression_sequence, + /** expecting a formal argument list (sub-syntax within lambda-expression) **/ + expect_formal_arglist, + /** expecting a s symbol. See @ref DExpectSymbolSsm **/ expect_symbol, diff --git a/src/reader2/CMakeLists.txt b/src/reader2/CMakeLists.txt index 99384589..949af024 100644 --- a/src/reader2/CMakeLists.txt +++ b/src/reader2/CMakeLists.txt @@ -33,6 +33,10 @@ set(SELF_SRCS ISyntaxStateMachine_DLambdaSsm.cpp IPrintable_DLambdaSsm.cpp + DExpectFormalArglistSsm.cpp + ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + IPrintable_DExpectFormalArglistSsm.cpp + DExpectSymbolSsm.cpp ISyntaxStateMachine_DExpectSymbolSsm.cpp IPrintable_DExpectSymbolSsm.cpp diff --git a/src/reader2/DExpectFormalArglistSsm.cpp b/src/reader2/DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..c7d3fffd --- /dev/null +++ b/src/reader2/DExpectFormalArglistSsm.cpp @@ -0,0 +1,227 @@ +/* @file DExpectFormalArglistSsm.cpp + * + * @author Roland Conybeare, Jan 2026 + */ + +#include "DExpectFormalArglistSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" +#include + +#ifdef NOT_YET +#include "parserstatemachine.hpp" +#include "exprstatestack.hpp" +#include "expect_formal_xs.hpp" +#include "expect_symbol_xs.hpp" +#include "xo/expression/Variable.hpp" +#include "xo/indentlog/print/vector.hpp" +#endif + +namespace xo { + using xo::mm::AAllocator; + using xo::print::ppindentinfo; + using xo::reflect::typeseq; + + namespace scm { + const char * + formalarglstatetype_descr(formalarglstatetype x) { + switch (x) { + case formalarglstatetype::invalid: + return "invalid"; + case formalarglstatetype::argl_0: + return "argl_0"; + case formalarglstatetype::argl_1a: + return "argl_1a"; + case formalarglstatetype::argl_1b: + return "argl_1b"; + case formalarglstatetype::n_formalarglstatetype: + break; + } + + return "?formalarglstatetype"; + } + + DExpectFormalArglistSsm::DExpectFormalArglistSsm(DArray * argl) : argl_{argl} + {} + + DExpectFormalArglistSsm * + DExpectFormalArglistSsm::_make(DArena & arena) + { + obj mm(&arena); + + /* out-of-order so argl follows ssm in arena, + * consistent with any subsequent arglist realloc. + * Not a load-bearing choice however + */ + + void * mem = arena.alloc(typeseq::id(), + sizeof(DExpectFormalArglistSsm)); + + + /* allocate room for 8 arguments (during parsing) + * will re-alloc to expand as needed + */ + DArray * argl = DArray::empty(mm, 8); + + return new (mem) DExpectFormalArglistSsm(argl); + } + + obj + DExpectFormalArglistSsm::make(DArena & arena) + { + obj retval(_make(arena)); + + return retval; + } + + void + DExpectFormalArglistSsm::start(ParserStateMachine * p_psm) + { + p_psm->push_ssm(DExpectFormalArglistSsm::make(p_psm->parser_alloc())); + } + + syntaxstatetype + DExpectFormalArglistSsm::ssm_type() const noexcept { + return syntaxstatetype::expect_formal_arglist; + } + + std::string_view + DExpectFormalArglistSsm::get_expect_str() const { + switch (fastate_) { + case formalarglstatetype::invalid: + case formalarglstatetype::n_formalarglstatetype: + assert(false); // impossible + break; + case formalarglstatetype::argl_0: + return "leftparen"; + case formalarglstatetype::argl_1a: + return "formal-name"; + case formalarglstatetype::argl_1b: + return "comma|rightparen"; + } + + return "?expect"; + } + + void + DExpectFormalArglistSsm::on_token(const Token & tk, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_token", + tk, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_symbol(std::string_view sym, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_symbol("DExpectFormalArglistSsm::on_parsed_symbol", + sym, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_typedescr(TypeDescr td, + ParserStateMachine * p_psm) + { + p_psm->illegal_input_on_typedescr("DExpectFormalArglistSsm::on_parsed_typedescr", + td, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_expression(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression", + expr, + this->get_expect_str()); + } + + void + DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectFormalArglistSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + +#ifdef NOT_YET + expect_formal_arglist_xs::expect_formal_arglist_xs() + : exprstate(exprstatetype::expect_formal_arglist), + farglxs_type_{formalarglstatetype::argl_0} + {} + + void + expect_formal_arglist_xs::on_leftparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_0) { + this->farglxs_type_ = formalarglstatetype::argl_1a; + /* TODO: refactor to have setup method on each exprstate */ + expect_formal_xs::start(p_psm); + } else { + exprstate::on_leftparen_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::on_formal(const rp & formal, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1a) { + this->farglxs_type_ = formalarglstatetype::argl_1b; + this->argl_.push_back(formal); + } else { + exprstate::on_formal(formal, p_psm); + } + } + + void + expect_formal_arglist_xs::on_comma_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + this->farglxs_type_ = formalarglstatetype::argl_1a; + expect_formal_xs::start(p_psm); + } else { + exprstate::on_comma_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, + parserstatemachine * p_psm) + { + if (farglxs_type_ == formalarglstatetype::argl_1b) { + std::unique_ptr self = p_psm->pop_exprstate(); + + p_psm->top_exprstate().on_formal_arglist(this->argl_, p_psm); + } else { + exprstate::on_rightparen_token(tk, p_psm); + } + } + + void + expect_formal_arglist_xs::print(std::ostream & os) const { + os << ""; + } +#endif + + bool + DExpectFormalArglistSsm::pretty(const ppindentinfo & ppii) const + { + return ppii.pps()->pretty_struct(ppii, + "DExpectFormalArglistSsm"); + } + + } /*namespace scm*/ +} /*namespace xo*/ + + +/* end DExpectFormalArglistSsm.cpp */ diff --git a/src/reader2/DExprSeqState.cpp b/src/reader2/DExprSeqState.cpp index cfd92683..28c62354 100644 --- a/src/reader2/DExprSeqState.cpp +++ b/src/reader2/DExprSeqState.cpp @@ -4,10 +4,12 @@ **/ #include "DExprSeqState.hpp" -#include "DDefineSsm.hpp" #include "ssm/ISyntaxStateMachine_DExprSeqState.hpp" -#include -#include +#include "DDefineSsm.hpp" +#include "DLambdaSsm.hpp" +#include "DProgressSsm.hpp" +#include "DIfElseSsm.hpp" + #include #include #include @@ -121,6 +123,10 @@ namespace xo { this->on_def_token(tk, p_psm); return; + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + case tokentype::tk_if: this->on_if_token(tk, p_psm); return; @@ -177,7 +183,6 @@ namespace xo { case tokentype::tk_cmpeq: case tokentype::tk_cmpne: case tokentype::tk_type: - case tokentype::tk_lambda: case tokentype::tk_then: case tokentype::tk_else: case tokentype::tk_let: @@ -241,6 +246,29 @@ namespace xo { */ } + void + DExprSeqState::on_lambda_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + DLambdaSsm::start(p_psm); + return; + case exprseqtype::toplevel_batch: + /* lambda not allowed at top-level in batch mode */ + break; + case exprseqtype::N: + assert(false); // unreachable + break; + } + + p_psm->illegal_input_on_token("DExprSeqState::on_lambda_token", + tk, + this->get_expect_str()); + } + void DExprSeqState::on_if_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/src/reader2/DLambdaSsm.cpp b/src/reader2/DLambdaSsm.cpp index ad678af8..a7db6e11 100644 --- a/src/reader2/DLambdaSsm.cpp +++ b/src/reader2/DLambdaSsm.cpp @@ -5,6 +5,8 @@ #include "DLambdaSsm.hpp" #include "ssm/ISyntaxStateMachine_DLambdaSsm.hpp" +#include "DExpectFormalArglistSsm.hpp" +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" #include "ParserStateMachine.hpp" #include "syntaxstatetype.hpp" #include @@ -25,6 +27,7 @@ namespace xo { using xo::print::APrintable; + using xo::mm::AAllocator; using xo::facet::FacetRegistry; using xo::reflect::typeseq; @@ -117,11 +120,77 @@ namespace xo { DLambdaSsm::on_token(const Token & tk, ParserStateMachine * p_psm) { + switch (tk.tk_type()) { + case tokentype::tk_lambda: + this->on_lambda_token(tk, p_psm); + return; + + // all the not-yet-handled cases + 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_leftparen: + case tokentype::tk_rightparen: + case tokentype::tk_leftbracket: + case tokentype::tk_rightbracket: + 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_comma: + 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; + } + p_psm->illegal_input_on_token("DLambdaSsm::on_token", tk, this->get_expect_str()); } + void + DLambdaSsm::on_lambda_token(const Token & tk, + ParserStateMachine * p_psm) + { + if (lmstate_ == lambdastatetype::lm_0) { + this->lmstate_ = lambdastatetype::lm_1; + + DExpectFormalArglistSsm::start(p_psm); + + return; + } + + p_psm->illegal_input_on_token("DLambdaSsm::on_lambda_token", + tk, + this->get_expect_str()); + } + + #ifdef NOT_YET void lambda_xs::on_lambda_token(const token_type & tk, @@ -386,8 +455,8 @@ namespace xo { DLambdaSsm::pretty(const ppindentinfo & ppii) const { obj body - = FacetRegistry::instance().variant(body_); + = FacetRegistry::instance().try_variant(body_); if (body) { return ppii.pps()->pretty_struct diff --git a/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp b/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..d5df450d --- /dev/null +++ b/src/reader2/IPrintable_DExpectFormalArglistSsm.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DExpectFormalArglistSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DExpectFormalArglistSsm.json5] +**/ + +#include "ssm/IPrintable_DExpectFormalArglistSsm.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DExpectFormalArglistSsm::pretty(const DExpectFormalArglistSsm & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DExpectFormalArglistSsm.cpp */ \ No newline at end of file diff --git a/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp b/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp new file mode 100644 index 00000000..91738110 --- /dev/null +++ b/src/reader2/ISyntaxStateMachine_DExpectFormalArglistSsm.cpp @@ -0,0 +1,59 @@ +/** @file ISyntaxStateMachine_DExpectFormalArglistSsm.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/ISyntaxStateMachine_DExpectFormalArglistSsm.json5] +**/ + +#include "ssm/ISyntaxStateMachine_DExpectFormalArglistSsm.hpp" + +namespace xo { + namespace scm { + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::ssm_type(const DExpectFormalArglistSsm & self) noexcept -> syntaxstatetype + { + return self.ssm_type(); + } + + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::get_expect_str(const DExpectFormalArglistSsm & self) noexcept -> std::string_view + { + return self.get_expect_str(); + } + + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_token(DExpectFormalArglistSsm & self, const Token & tk, ParserStateMachine * p_psm) -> void + { + self.on_token(tk, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_symbol(DExpectFormalArglistSsm & self, std::string_view sym, ParserStateMachine * p_psm) -> void + { + self.on_parsed_symbol(sym, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_typedescr(DExpectFormalArglistSsm & self, TypeDescr td, ParserStateMachine * p_psm) -> void + { + self.on_parsed_typedescr(td, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression(expr, p_psm); + } + auto + ISyntaxStateMachine_DExpectFormalArglistSsm::on_parsed_expression_with_semicolon(DExpectFormalArglistSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end ISyntaxStateMachine_DExpectFormalArglistSsm.cpp */ \ No newline at end of file diff --git a/src/reader2/reader2_register_facets.cpp b/src/reader2/reader2_register_facets.cpp index 712f5998..1cb37de9 100644 --- a/src/reader2/reader2_register_facets.cpp +++ b/src/reader2/reader2_register_facets.cpp @@ -11,9 +11,15 @@ #include #include +#include +#include + #include #include +#include +#include + #include #include @@ -48,9 +54,15 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -65,11 +77,14 @@ namespace xo { log && log(xtag("DExprSeqState.tseq", typeseq::id())); log && log(xtag("DDefineSsm.tseq", typeseq::id())); + log && log(xtag("DLambdaSsm.tseq", typeseq::id())); log && log(xtag("DIfElseSsm.tseq", typeseq::id())); + log && log(xtag("DExpectFormalArglistSsm.tseq", typeseq::id())); log && log(xtag("DExpectSymbolSsm.tseq", typeseq::id())); log && log(xtag("DExpectTypeSsm.tseq", typeseq::id())); log && log(xtag("DExpectExprSsm.tseq", typeseq::id())); log && log(xtag("DProgressSsm.tseq", typeseq::id())); + log && log(xtag("ASyntaxStateMachine.tseq", typeseq::id())); return true; } diff --git a/src/reader2/syntaxstatetype.cpp b/src/reader2/syntaxstatetype.cpp index c03667c4..7a2ece4c 100644 --- a/src/reader2/syntaxstatetype.cpp +++ b/src/reader2/syntaxstatetype.cpp @@ -15,6 +15,8 @@ namespace xo { break; case syntaxstatetype::expect_toplevel_expression_sequence: return "expect-toplevel-expression-sequence"; + case syntaxstatetype::expect_formal_arglist: + return "expect-formal-arglist"; case syntaxstatetype::expect_symbol: return "expect-symbol"; case syntaxstatetype::expect_type: diff --git a/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index 0f8c1a19..5b6124a9 100644 --- a/utest/SchematikaParser.test.cpp +++ b/utest/SchematikaParser.test.cpp @@ -197,6 +197,119 @@ namespace xo { //REQUIRE(result.error_description()); } + TEST_CASE("SchematikaParser-interactive-lambda", "[reader2][SchematikaParser]") + { + constexpr bool c_debug_flag = true; + scope log(XO_DEBUG(c_debug_flag)); + + ArenaConfig config; + config.name_ = "test-arena"; + config.size_ = 16 * 1024; + + DArena expr_arena = DArena::map(config); + obj expr_alloc = with_facet::mkobj(&expr_arena); + + SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/); + + parser.begin_interactive_session(); + + /** Walkthrough parsing input equivalent to: + * + * lambda ; + * + **/ + + { + auto & result = parser.on_token(Token::lambda_token()); + + log && log("after lambda token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + +#ifdef NOT_YET + { + auto & result = parser.on_token(Token::bool_token("true")); + + log && log("after true token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::then_token()); + + log && log("after then token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::i64_token("777")); + + log && log("after i64 token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::else_token()); + + log && log("after else token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::string_token("fooey")); + + log && log("after string token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == true); + REQUIRE(!result.is_error()); + REQUIRE(result.is_incomplete()); + } + + { + auto & result = parser.on_token(Token::semicolon_token()); + + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); + REQUIRE(!result.is_error()); + REQUIRE(!result.is_incomplete()); + } +#endif + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + } + TEST_CASE("SchematikaParser-interactive-if", "[reader2][SchematikaParser]") { constexpr bool c_debug_flag = true;