diff --git a/xo-expression2/include/xo/expression2/DDefineExpr.hpp b/xo-expression2/include/xo/expression2/DDefineExpr.hpp index 1056dbb7..6b7716e3 100644 --- a/xo-expression2/include/xo/expression2/DDefineExpr.hpp +++ b/xo-expression2/include/xo/expression2/DDefineExpr.hpp @@ -56,6 +56,7 @@ namespace xo { ///@{ void assign_lhs_name(const DUniqueString * name); + void assign_rhs(obj rhs); ///@} /** @defgroup scm-defineexpr-expression-facet **/ diff --git a/xo-expression2/src/expression2/DDefineExpr.cpp b/xo-expression2/src/expression2/DDefineExpr.cpp index c8785415..e193c4d4 100644 --- a/xo-expression2/src/expression2/DDefineExpr.cpp +++ b/xo-expression2/src/expression2/DDefineExpr.cpp @@ -67,6 +67,11 @@ namespace xo { lhs_var_->assign_valuetype(td); } + void + DDefineExpr::assign_rhs(obj x) { + this->rhs_ = x; + } + bool DDefineExpr::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/idl/SyntaxStateMachine.json5 b/xo-reader2/idl/SyntaxStateMachine.json5 index 74843096..c12d3736 100644 --- a/xo-reader2/idl/SyntaxStateMachine.json5 +++ b/xo-reader2/idl/SyntaxStateMachine.json5 @@ -135,5 +135,14 @@ {type: "ParserStateMachine *", name: "p_psm"}, ], }, + { + name: "on_parsed_expression_with_semicolon", + doc: ["update state machine for incoming parsed expression @p expr followed by semicolon"], + return_type: "void", + args: [ + {type: "obj", name: "expr"}, + {type: "ParserStateMachine *", name: "p_psm"}, + ], + }, ], } diff --git a/xo-reader2/include/xo/reader2/DDefineSsm.hpp b/xo-reader2/include/xo/reader2/DDefineSsm.hpp index 3496b5c8..1d94f3ad 100644 --- a/xo-reader2/include/xo/reader2/DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/DDefineSsm.hpp @@ -177,6 +177,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon, + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp index 6ed81bff..7bf48dea 100644 --- a/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectExprSsm.hpp @@ -113,6 +113,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon, + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-define-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp index 6f9a568c..1083b454 100644 --- a/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectSymbolSsm.hpp @@ -86,6 +86,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax after parsing an expression @p expr + * followed by semicolon in nested state machine. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming token @p tk, * overall parser state in @p p_psm. **/ diff --git a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp index 49bd1aa9..cf28fedf 100644 --- a/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/DExpectTypeSsm.hpp @@ -114,6 +114,13 @@ namespace xo { void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** operate state machine for this syntax on receiving expression + * followed by semicolon from nested parser. + * (provided to satisfy ASyntaxStateMachine api. not reachable) + **/ + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} /** @defgroup scm-expecttype-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DExprSeqState.hpp b/xo-reader2/include/xo/reader2/DExprSeqState.hpp index a3989200..eefcb15d 100644 --- a/xo-reader2/include/xo/reader2/DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/DExprSeqState.hpp @@ -118,6 +118,12 @@ namespace xo { **/ void on_parsed_expression(obj expr, ParserStateMachine * p_psm); + /** update state for this syntax on parsed expression @p expr + * followed by semicolon from nested ssm. + * overall parser state in @p p_psm + **/ + void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm); + ///@} /** @defgroup scm-exprseq-printable-facet printable facet methods **/ ///@{ diff --git a/xo-reader2/include/xo/reader2/DProgressSsm.hpp b/xo-reader2/include/xo/reader2/DProgressSsm.hpp index f1e15fba..2b4121c3 100644 --- a/xo-reader2/include/xo/reader2/DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/DProgressSsm.hpp @@ -123,12 +123,14 @@ namespace xo { std::string_view get_expect_str() const noexcept; -#ifdef NOT_YET - void on_expr(bp expr, - parserstatemachine * p_psm) override; - void on_expr_with_semicolon(bp expr, - parserstatemachine * p_psm) override; -#endif + /** assemble expression from collected inputs. + * Usually triggered by syntax like ';' or ')' + **/ + obj assemble_expr(ParserStateMachine * p_psm); + + /** @defgroup scm-progressssm-ssm-facet syntaxstatemachine facet methods **/ + /// @{ + void on_symbol_token(const Token & tk, ParserStateMachine * p_psm); void on_def_token(const Token & tk, @@ -149,12 +151,17 @@ namespace xo { ParserStateMachine * p_psm); void on_parsed_expression(obj, ParserStateMachine * p_psm); + void on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm); + ///@} + /** @defgroup scm-progressssm-printable-facet printable facet methods **/ ///@{ - /** @defgroup scm-progressssm-printable-facet printable facet methods **/ bool pretty(const ppindentinfo & ppii) const; + ///@} + #ifdef NOT_YET void on_comma_token(const token_type & tk, parserstatemachine * p_psm) final override; diff --git a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp index e5c0ab68..42c8af64 100644 --- a/xo-reader2/include/xo/reader2/ParserStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ParserStateMachine.hpp @@ -102,6 +102,22 @@ namespace xo { **/ void on_parsed_typedescr(TypeDescr td); + /** update state to respond to parsed expression @p expr + * (from nested parsing state) + **/ + void on_parsed_expression(obj expr); + + /** update state to respond to parsed expression @p expr + * (from nested parsing state), with trailing semicolon. + * + * Need to distinguish cases like: + * 6 // ; allowed + * f(6 // ) allowed ; forbidden + * 6 + // ) forbidden ; forbidden + * + **/ + void on_parsed_expression_with_semicolon(obj expr); + /** update state to respond to input token @p tk. * record output (if any) in @ref result_ **/ diff --git a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp index a5cf677f..b68a1289 100644 --- a/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ASyntaxStateMachine.hpp @@ -77,6 +77,8 @@ public: virtual void on_parsed_typedescr(Opaque data, TypeDescr td, ParserStateMachine * p_psm) = 0; /** update state machine for incoming parsed expression @p expr **/ virtual void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; + /** update state machine for incoming parsed expression @p expr followed by semicolon **/ + virtual void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) = 0; ///@} }; /*ASyntaxStateMachine*/ diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp index 1098b86e..52dc4059 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Any.hpp @@ -70,6 +70,7 @@ namespace scm { [[noreturn]] void on_parsed_symbol(Opaque, std::string_view, ParserStateMachine *) override; [[noreturn]] void on_parsed_typedescr(Opaque, TypeDescr, ParserStateMachine *) override; [[noreturn]] void on_parsed_expression(Opaque, obj, ParserStateMachine *) override; + [[noreturn]] void on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) override; ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp index a65f47d5..3084631c 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DDefineSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DDefineSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DDefineSsm & 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(DDefineSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp index 28beddcd..efebe9c7 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectExprSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectExprSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectExprSsm & 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(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp index a38306ed..d870667a 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectSymbolSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectSymbolSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectSymbolSsm & 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(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp index aefe5afa..23eb8af0 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExpectTypeSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExpectTypeSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExpectTypeSsm & 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(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp index cc0d918d..020e7552 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DExprSeqState.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DExprSeqState & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DExprSeqState & 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(DExprSeqState & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp index c305cf80..1735b2b1 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_DProgressSsm.hpp @@ -74,6 +74,8 @@ namespace xo { static void on_parsed_typedescr(DProgressSsm & self, TypeDescr td, ParserStateMachine * p_psm); /** update state machine for incoming parsed expression @p expr **/ static void on_parsed_expression(DProgressSsm & 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(DProgressSsm & self, obj expr, ParserStateMachine * p_psm); ///@} }; diff --git a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp index a0a832b5..da16f766 100644 --- a/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp +++ b/xo-reader2/include/xo/reader2/ssm/ISyntaxStateMachine_Xfer.hpp @@ -82,6 +82,9 @@ namespace scm { void on_parsed_expression(Opaque data, obj expr, ParserStateMachine * p_psm) override { return I::on_parsed_expression(_dcast(data), expr, p_psm); } + void on_parsed_expression_with_semicolon(Opaque data, obj expr, ParserStateMachine * p_psm) override { + return I::on_parsed_expression_with_semicolon(_dcast(data), expr, p_psm); + } ///@} diff --git a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp index 187a32c7..cfa354b9 100644 --- a/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp +++ b/xo-reader2/include/xo/reader2/ssm/RSyntaxStateMachine.hpp @@ -86,6 +86,9 @@ public: void on_parsed_expression(obj expr, ParserStateMachine * p_psm) { return O::iface()->on_parsed_expression(O::data(), expr, p_psm); } + void on_parsed_expression_with_semicolon(obj expr, ParserStateMachine * p_psm) { + return O::iface()->on_parsed_expression_with_semicolon(O::data(), expr, p_psm); + } ///@} /** @defgroup scm-syntaxstatemachine-member-vars **/ diff --git a/xo-reader2/src/reader2/DDefineSsm.cpp b/xo-reader2/src/reader2/DDefineSsm.cpp index 3e91a480..6de3bd93 100644 --- a/xo-reader2/src/reader2/DDefineSsm.cpp +++ b/xo-reader2/src/reader2/DDefineSsm.cpp @@ -578,6 +578,12 @@ namespace xo { DDefineSsm::on_semicolon_token(const Token & tk, ParserStateMachine * p_psm) { + if (defstate_ == defexprstatetype::def_6) { + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_semicolon(def_expr_); + return; + } + p_psm->illegal_input_on_token("DDefineSsm::on_semicolon_token", tk, this->get_expect_str()); @@ -587,11 +593,27 @@ namespace xo { DDefineSsm::on_parsed_expression(obj expr, ParserStateMachine * p_psm) { + if (defstate_ == defexprstatetype::def_5) + { + this->defstate_ = defexprstatetype::def_6; + + def_expr_.data()->assign_rhs(expr); + return; + } + p_psm->illegal_parsed_expression("DDefineSsm::on_parsed_expression", expr, this->get_expect_str()); } + void + DDefineSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + this->on_parsed_expression(expr, p_psm); + this->on_semicolon_token(Token::semicolon_token(), p_psm); + } + bool DDefineSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectExprSsm.cpp b/xo-reader2/src/reader2/DExpectExprSsm.cpp index 3f817763..cea683c4 100644 --- a/xo-reader2/src/reader2/DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/DExpectExprSsm.cpp @@ -206,6 +206,17 @@ namespace xo { this->get_expect_str()); } + void + DExpectExprSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + // expression (reported by nested ProgressSsm) + // completes this DExpectExprSsm's assignment + + p_psm->pop_ssm(); + p_psm->on_parsed_expression_with_semicolon(expr); + } + bool DExpectExprSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp index a1db308c..e55d35be 100644 --- a/xo-reader2/src/reader2/DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/DExpectSymbolSsm.cpp @@ -83,6 +83,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectSymbolSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectSymbolSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + void DExpectSymbolSsm::on_symbol_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/xo-reader2/src/reader2/DExpectTypeSsm.cpp b/xo-reader2/src/reader2/DExpectTypeSsm.cpp index 9a97ef2d..30520811 100644 --- a/xo-reader2/src/reader2/DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/DExpectTypeSsm.cpp @@ -172,6 +172,15 @@ namespace xo { this->get_expect_str()); } + void + DExpectTypeSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExpectTypeSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + bool DExpectTypeSsm::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DExprSeqState.cpp b/xo-reader2/src/reader2/DExprSeqState.cpp index a5b7edd6..e67790d5 100644 --- a/xo-reader2/src/reader2/DExprSeqState.cpp +++ b/xo-reader2/src/reader2/DExprSeqState.cpp @@ -223,6 +223,15 @@ namespace xo { this->get_expect_str()); } + void + DExprSeqState::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DExprSeqState::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + bool DExprSeqState::pretty(const ppindentinfo & ppii) const { diff --git a/xo-reader2/src/reader2/DProgressSsm.cpp b/xo-reader2/src/reader2/DProgressSsm.cpp index d141daf6..f202728e 100644 --- a/xo-reader2/src/reader2/DProgressSsm.cpp +++ b/xo-reader2/src/reader2/DProgressSsm.cpp @@ -213,11 +213,12 @@ namespace xo { { /* note: implementation should parallel .on_rightparen_token() */ -#ifdef NOT_YET + (void)tk; + obj expr = this->assemble_expr(p_psm); p_psm->pop_ssm(); - p_psm->on_expr_with_semicolon(expr); + p_psm->on_parsed_expression_with_semicolon(expr); /* control here on input like: * (1.234; @@ -232,11 +233,12 @@ namespace xo { * d. expr_rhs_expression forwards expression to [lparen_0] * e. lparen_0 would advance to [lparen_1], but rejects semicolon */ -#endif +#ifdef OBSOLETE p_psm->illegal_input_on_token("DProgressSsm::on_semicolon_token", tk, this->get_expect_str()); +#endif } void @@ -266,6 +268,15 @@ namespace xo { this->get_expect_str()); } + void + DProgressSsm::on_parsed_expression_with_semicolon(obj expr, + ParserStateMachine * p_psm) + { + p_psm->illegal_parsed_expression("DProgressSsm::on_parsed_expression_with_semicolon", + expr, + this->get_expect_str()); + } + #ifdef NOT_YET void progress_xs::apply_type_error(const char * self_name, @@ -967,6 +978,194 @@ namespace xo { } #endif } + + obj + DProgressSsm::assemble_expr(ParserStateMachine * p_psm) + { + /* need to defer building Apply incase expr followed by higher-precedence operator: + * consider input like + * 3.14 + 2.0 * ... + */ + + constexpr const char * c_self_name = "DProgressSsm::assemble_expr"; + + if ((op_type_ != optype::invalid) && rhs_) { + std::string errmsg_string = tostr("expected expression on rhs of operator op", + xtag("lhs", lhs_), + xtag("op", op_type_)); + + auto errmsg = DString::from_view(p_psm->expr_alloc(), + std::string_view(errmsg_string)); + + p_psm->capture_error(c_self_name, errmsg); + } + + /* consecutive expressions not legal, e.g: + * 3.14 6.28 + * but expressions surrounding an infix operators is: + * 3.14 / 6.28 + */ + switch (op_type_) { + case optype::invalid: + return this->lhs_; + + case optype::op_assign: + case optype::op_equal: + case optype::op_not_equal: + case optype::op_less: + case optype::op_less_equal: + case optype::op_great: + case optype::op_great_equal: + case optype::op_add: + case optype::op_subtract: + case optype::op_multiply: + case optype::op_divide: + // TODO: implement binary operator expression assembly + break; + +#ifdef NOT_YET +case optype::op_assign: + { + bp lhs = Variable::from(this->lhs_); + + if (!lhs) { + throw std::runtime_error + (tostr("progress_xs::assemble_expr", + " expect variable on lhs of assignment operator :=", + xtag("lhs", lhs_), + xtag("rhs", rhs_))); + } + + return AssignExpr::make(lhs.promote(), + this->rhs_); + } + +case optype::op_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_eq_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_not_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ne_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_less: + // TODO: floating-point less-than + + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_lt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_less_equal: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_le_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_great: + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_gt_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_great_equal: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_cmp_ge_i64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + assert(false); + +case optype::op_add: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_add2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_add2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; +case optype::op_subtract: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_sub2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_sub2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; + +case optype::op_multiply: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_mul2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_mul2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + + break; + +case optype::op_divide: + // TODO: upconvert integer->double + if (lhs_->valuetype()->is_i64() && rhs_->valuetype()->is_i64()) { + return Apply::make_div2_i64(lhs_, rhs_); + } else if (lhs_->valuetype()->is_f64() && rhs_->valuetype()->is_f64()) { + return Apply::make_div2_f64(lhs_, rhs_); + } else { + this->apply_type_error(c_self_name, + op_type_, lhs_, rhs_, p_psm); + return nullptr; + } + break; +#endif + + case optype::n_optype: + /* unreachable */ + assert(false); + break; + } + + return obj(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp index c953b1e1..a789bce9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_Any.cpp @@ -94,6 +94,12 @@ ISyntaxStateMachine_Any::on_parsed_expression(Opaque, obj, ParserSt _fatal(); } +auto +ISyntaxStateMachine_Any::on_parsed_expression_with_semicolon(Opaque, obj, ParserStateMachine *) -> void +{ + _fatal(); +} + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp index cab18818..89589841 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DDefineSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DDefineSsm::on_parsed_expression_with_semicolon(DDefineSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp index feb2d13a..858ce1ab 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectExprSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectExprSsm::on_parsed_expression_with_semicolon(DExpectExprSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp index 714ef041..1982212c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectSymbolSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectSymbolSsm::on_parsed_expression_with_semicolon(DExpectSymbolSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp index 2dd5a9ca..eb66f8db 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExpectTypeSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExpectTypeSsm::on_parsed_expression_with_semicolon(DExpectTypeSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp index 6d42b86b..cfd419b9 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DExprSeqState.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DExprSeqState::on_parsed_expression_with_semicolon(DExprSeqState & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp index 62dd2ce0..53c8706c 100644 --- a/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp +++ b/xo-reader2/src/reader2/ISyntaxStateMachine_DProgressSsm.cpp @@ -77,6 +77,11 @@ namespace xo { { self.on_parsed_expression(expr, p_psm); } + auto + ISyntaxStateMachine_DProgressSsm::on_parsed_expression_with_semicolon(DProgressSsm & self, obj expr, ParserStateMachine * p_psm) -> void + { + self.on_parsed_expression_with_semicolon(expr, p_psm); + } } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-reader2/src/reader2/ParserStateMachine.cpp b/xo-reader2/src/reader2/ParserStateMachine.cpp index 262db2df..66e4703e 100644 --- a/xo-reader2/src/reader2/ParserStateMachine.cpp +++ b/xo-reader2/src/reader2/ParserStateMachine.cpp @@ -129,6 +129,26 @@ namespace xo { this->stack_->top().on_parsed_typedescr(td, this); } + void + ParserStateMachine::on_parsed_expression(obj expr) + { + scope log(XO_DEBUG(debug_flag_), xtag("expr", expr)); + + assert(stack_); + + this->top_ssm().on_parsed_expression(expr, this); + } + + void + ParserStateMachine::on_parsed_expression_with_semicolon(obj expr) + { + scope log(XO_DEBUG(debug_flag_), xtag("expr", expr)); + + assert(stack_); + + this->top_ssm().on_parsed_expression_with_semicolon(expr, this); + } + void ParserStateMachine::on_token(const Token & tk) { diff --git a/xo-reader2/utest/SchematikaParser.test.cpp b/xo-reader2/utest/SchematikaParser.test.cpp index e70f449b..a8544687 100644 --- a/xo-reader2/utest/SchematikaParser.test.cpp +++ b/xo-reader2/utest/SchematikaParser.test.cpp @@ -177,14 +177,13 @@ namespace xo { } { -#ifdef NOT_YET - auto def_ssm - = obj::from(parser.top_ssm()); + auto & result = parser.on_token(Token::semicolon_token()); - REQUIRE(def_ssm); - REQUIRE(def_ssm.data()->ssm_type() == syntaxstatetype::defexpr); - REQUIRE(def_ssm.data()->defstate() == defexprstatetype::def_5); -#endif + log && log("after semicolon token:"); + log && log(xtag("parser", &parser)); + log && log(xtag("result", result)); + + REQUIRE(parser.has_incomplete_expr() == false); } // define-expressions not properly implemented diff --git a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp index d47b311d..cc6e13d9 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/Token.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/Token.hpp @@ -112,7 +112,7 @@ namespace xo { /** token representing double-colo @c "::" **/ static Token doublecolon() { return Token(tokentype::tk_doublecolon); } /** token representing semicolon @c ";" **/ - static Token semicolon() { return Token(tokentype::tk_semicolon); } + static Token semicolon_token() { return Token(tokentype::tk_semicolon); } /** token representing single-assignment @c "=" (editor bait: equal_token) **/ static Token singleassign_token() { return Token(tokentype::tk_singleassign); } /** token representing unrestricted assignment @c ":=" **/