From 6df599673aa43a472d537eacc91e4a36460e5def Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 29 Jan 2026 13:48:24 -0500 Subject: [PATCH] xo-reader2: DExpectFormalArglistSsm parses multiple formals --- .../xo/reader2/DExpectFormalArglistSsm.hpp | 8 +-- .../src/reader2/DExpectFormalArglistSsm.cpp | 67 ++++++------------- xo-reader2/utest/SchematikaParser.test.cpp | 44 ++++++++++-- xo-tokenizer2/include/xo/tokenizer2/Token.hpp | 2 +- 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp index ac7bc643..2898fa7c 100644 --- a/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectFormalArglistSsm.hpp @@ -75,6 +75,10 @@ namespace xo { void on_leftparen_token(const Token & tk, ParserStateMachine * p_psm); + /** update state on incoming token @p tk, with overall parser state in @p psm **/ + void on_comma_token(const Token & tk, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expectformalarglistssm-ssm-facet syntaxstatemachine facet methods **/ ///@{ @@ -140,10 +144,6 @@ namespace xo { 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. * diff --git a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp index 555ab275..676e0a9e 100644 --- a/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp +++ b/xo-reader2/src/reader2/DExpectFormalArglistSsm.cpp @@ -122,6 +122,10 @@ namespace xo { this->on_leftparen_token(tk, p_psm); return; + case tokentype::tk_comma: + this->on_comma_token(tk, p_psm); + return; + // all the not-yet-handled cases case tokentype::tk_lambda: case tokentype::tk_def: @@ -145,7 +149,6 @@ namespace xo { 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: @@ -238,20 +241,6 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET - 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); - } - } -#endif - void DExpectFormalArglistSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) @@ -270,13 +259,6 @@ namespace xo { 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} - {} -#endif - void DExpectFormalArglistSsm::on_leftparen_token(const Token & tk, ParserStateMachine * p_psm) @@ -293,19 +275,23 @@ namespace xo { this->get_expect_str()); } -#ifdef NOT_YET void - expect_formal_arglist_xs::on_comma_token(const token_type & tk, - parserstatemachine * p_psm) + DExpectFormalArglistSsm::on_comma_token(const Token & 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); + if (fastate_ == formalarglstatetype::argl_1b) { + this->fastate_ = formalarglstatetype::argl_1a; + + DExpectFormalArgSsm::start(p_psm); + return; } + + p_psm->illegal_input_on_token("DExpectFormalArglistSsm::on_comma_token", + tk, + this->get_expect_str()); } +#ifdef NOT_YET void expect_formal_arglist_xs::on_rightparen_token(const token_type & tk, parserstatemachine * p_psm) @@ -318,15 +304,6 @@ namespace xo { exprstate::on_rightparen_token(tk, p_psm); } } - - void - expect_formal_arglist_xs::print(std::ostream & os) const { - os << ""; - } #endif bool @@ -344,12 +321,12 @@ namespace xo { if (!pps->print_upto(xrefrtag("expect", this->get_expect_str()))) return false; - if (!pps->print_upto(xrefrtag("n_args", n_args_))) + if (!pps->print_upto(xrefrtag("n_args", argl_->size()))) return false; - for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + for (size_type i_arg = 0; i_arg < argl_->size(); ++i_arg) { char buf[80]; - snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + snprintf(buf, sizeof(buf), "arg[%u]", i_arg); auto arg_gco = argl_->at(i_arg); obj arg_pr @@ -372,11 +349,11 @@ namespace xo { pps->pretty(refrtag("expect", this->get_expect_str())); pps->newline_indent(ppii.ci1()); - pps->pretty(refrtag("n_args", n_args_)); + pps->pretty(refrtag("n_args", argl_->size())); - for (size_type i_arg = 0; i_arg < n_args_; ++i_arg) { + for (size_type i_arg = 0, n_arg = argl_->size(); i_arg < n_arg; ++i_arg) { char buf[80]; - snprintf(buf, sizeof(buf), "arg[%ud]", i_arg); + snprintf(buf, sizeof(buf), "arg[%u]", i_arg); auto arg_gco = argl_->at(i_arg); obj arg_pr diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index 934b26ed..cedb4c1d 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -215,7 +215,7 @@ namespace xo { /** Walkthrough parsing input equivalent to: * - * lambda (n : i64; + * lambda (n : i64, * **/ @@ -279,11 +279,10 @@ namespace xo { REQUIRE(result.is_incomplete()); } -#ifdef NOT_YET { - auto & result = parser.on_token(Token::i64_token("777")); + auto & result = parser.on_token(Token::comma_token()); - log && log("after i64 token:"); + log && log("after comma token:"); log && log(xtag("parser", &parser)); log && log(xtag("result", result)); @@ -292,6 +291,43 @@ namespace xo { REQUIRE(result.is_incomplete()); } + { + auto & result = parser.on_token(Token::symbol_token("r")); + + log && log("after symbol(r) 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::colon_token()); + + log && log("after colon 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::symbol_token("i64")); + + log && log("after symbol(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()); + } + +#ifdef NOT_YET { auto & result = parser.on_token(Token::else_token()); diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index 55a2d57d..607bc0a4 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -106,7 +106,7 @@ namespace xo { /** token representing period @c "." **/ static Token dot() { return Token(tokentype::tk_dot); } /** token representing comma @c "," **/ - static Token comma() { return Token(tokentype::tk_comma); } + static Token comma_token() { return Token(tokentype::tk_comma); } /** token representing colon @c ":" **/ static Token colon_token() { return Token(tokentype::tk_colon); } /** token representing double-colo @c "::" **/