diff --git a/include/xo/reader2/DExpectExprSsm.hpp b/include/xo/reader2/DExpectExprSsm.hpp index 539fbb39..66189754 100644 --- a/include/xo/reader2/DExpectExprSsm.hpp +++ b/include/xo/reader2/DExpectExprSsm.hpp @@ -84,12 +84,18 @@ namespace xo { void on_quote_token(const Token & tk, ParserStateMachine * p_psm); - /** step state machine for this syntax on incoming boolean literal token @p tkk + /** step state machine for this syntax on incoming boolean literal token @p tk * with overall parser state in @p p_psm **/ void on_bool_token(const Token & tk, ParserStateMachine * p_psm); + /** step state machine for this syntax on incoming nil literal token @p tk + * with overall parser state in @p p_psm. + **/ + void on_nil_token(const Token & tk, + ParserStateMachine * p_psm); + /** update state for this syntax on incoming f64 token @p tk, * overall parser state in @p p_psm **/ diff --git a/include/xo/reader2/DToplevelSeqSsm.hpp b/include/xo/reader2/DToplevelSeqSsm.hpp index 9bb9b076..2466ed1e 100644 --- a/include/xo/reader2/DToplevelSeqSsm.hpp +++ b/include/xo/reader2/DToplevelSeqSsm.hpp @@ -119,6 +119,11 @@ namespace xo { **/ void on_bool_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming nil token @p tk, + * overall parser state in @p p_psm + **/ + void on_nil_token(const Token & tk, ParserStateMachine * p_psm); + /** update state for this syntax on incoming leftparen token @p tk, * overall parser state in @p p_psm **/ diff --git a/src/reader2/DApplySsm.cpp b/src/reader2/DApplySsm.cpp index ad9a4e50..cd591c9c 100644 --- a/src/reader2/DApplySsm.cpp +++ b/src/reader2/DApplySsm.cpp @@ -171,6 +171,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_let: diff --git a/src/reader2/DDefineSsm.cpp b/src/reader2/DDefineSsm.cpp index 344e1fc1..2f7f99be 100644 --- a/src/reader2/DDefineSsm.cpp +++ b/src/reader2/DDefineSsm.cpp @@ -546,6 +546,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DDeftypeSsm.cpp b/src/reader2/DDeftypeSsm.cpp index ec36391a..383f4fee 100644 --- a/src/reader2/DDeftypeSsm.cpp +++ b/src/reader2/DDeftypeSsm.cpp @@ -150,6 +150,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DExpectExprSsm.cpp b/src/reader2/DExpectExprSsm.cpp index c2d46140..f4fabfc9 100644 --- a/src/reader2/DExpectExprSsm.cpp +++ b/src/reader2/DExpectExprSsm.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +156,10 @@ namespace xo { this->on_bool_token(tk, p_psm); return; + case tokentype::tk_nil: + this->on_nil_token(tk, p_psm); + return; + case tokentype::tk_if: this->on_if_token(tk, p_psm); return; @@ -372,6 +377,23 @@ namespace xo { p_psm); } + void + DExpectExprSsm::on_nil_token(const Token & tk, + ParserStateMachine * p_psm) + { + (void)tk; + + auto nil = DList::nil(); + auto expr = DConstant::make(p_psm->expr_alloc(), nil); + + // DProgressSsm responsible for resolving cases like + // nil ++ nil; + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + } + void DExpectExprSsm::on_f64_token(const Token & tk, ParserStateMachine * p_psm) diff --git a/src/reader2/DExpectFormalArgSsm.cpp b/src/reader2/DExpectFormalArgSsm.cpp index db287abf..a17d094c 100644 --- a/src/reader2/DExpectFormalArgSsm.cpp +++ b/src/reader2/DExpectFormalArgSsm.cpp @@ -135,6 +135,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DExpectFormalArglistSsm.cpp b/src/reader2/DExpectFormalArglistSsm.cpp index 67f327e1..9f7da033 100644 --- a/src/reader2/DExpectFormalArglistSsm.cpp +++ b/src/reader2/DExpectFormalArglistSsm.cpp @@ -165,6 +165,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DExpectListTypeSsm.cpp b/src/reader2/DExpectListTypeSsm.cpp index 3b040962..1f42d171 100644 --- a/src/reader2/DExpectListTypeSsm.cpp +++ b/src/reader2/DExpectListTypeSsm.cpp @@ -127,6 +127,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DExpectQArraySsm.cpp b/src/reader2/DExpectQArraySsm.cpp index 33ccd7c8..aa89862f 100644 --- a/src/reader2/DExpectQArraySsm.cpp +++ b/src/reader2/DExpectQArraySsm.cpp @@ -122,6 +122,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DExpectQListSsm.cpp b/src/reader2/DExpectQListSsm.cpp index 9584bfea..f3f50b81 100644 --- a/src/reader2/DExpectQListSsm.cpp +++ b/src/reader2/DExpectQListSsm.cpp @@ -122,6 +122,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DExpectQLiteralSsm.cpp b/src/reader2/DExpectQLiteralSsm.cpp index 92309ddc..4cb26099 100644 --- a/src/reader2/DExpectQLiteralSsm.cpp +++ b/src/reader2/DExpectQLiteralSsm.cpp @@ -140,6 +140,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DExpectSymbolSsm.cpp b/src/reader2/DExpectSymbolSsm.cpp index 79ae0622..17cdca06 100644 --- a/src/reader2/DExpectSymbolSsm.cpp +++ b/src/reader2/DExpectSymbolSsm.cpp @@ -101,6 +101,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DExpectTypeSsm.cpp b/src/reader2/DExpectTypeSsm.cpp index 600b7650..9eb2b15d 100644 --- a/src/reader2/DExpectTypeSsm.cpp +++ b/src/reader2/DExpectTypeSsm.cpp @@ -107,6 +107,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DIfElseSsm.cpp b/src/reader2/DIfElseSsm.cpp index 5752dbdc..b915c061 100644 --- a/src/reader2/DIfElseSsm.cpp +++ b/src/reader2/DIfElseSsm.cpp @@ -186,6 +186,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_let: diff --git a/src/reader2/DLambdaSsm.cpp b/src/reader2/DLambdaSsm.cpp index 9364476a..ac19c7e0 100644 --- a/src/reader2/DLambdaSsm.cpp +++ b/src/reader2/DLambdaSsm.cpp @@ -163,6 +163,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_then: case tokentype::tk_else: diff --git a/src/reader2/DParenSsm.cpp b/src/reader2/DParenSsm.cpp index d3fb5cfa..7bf28d02 100644 --- a/src/reader2/DParenSsm.cpp +++ b/src/reader2/DParenSsm.cpp @@ -132,6 +132,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DProgressSsm.cpp b/src/reader2/DProgressSsm.cpp index edb55001..be927bef 100644 --- a/src/reader2/DProgressSsm.cpp +++ b/src/reader2/DProgressSsm.cpp @@ -309,6 +309,7 @@ namespace xo { this->on_operator_token(tk, p_psm); return; + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: break; diff --git a/src/reader2/DQuoteSsm.cpp b/src/reader2/DQuoteSsm.cpp index 7f6dd00d..c61ed632 100644 --- a/src/reader2/DQuoteSsm.cpp +++ b/src/reader2/DQuoteSsm.cpp @@ -133,6 +133,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_then: diff --git a/src/reader2/DSequenceSsm.cpp b/src/reader2/DSequenceSsm.cpp index 8bb2f779..b2b237dd 100644 --- a/src/reader2/DSequenceSsm.cpp +++ b/src/reader2/DSequenceSsm.cpp @@ -114,6 +114,7 @@ namespace xo { case tokentype::tk_slash: case tokentype::tk_cmpeq: case tokentype::tk_cmpne: + case tokentype::tk_nil: case tokentype::tk_type: case tokentype::tk_lambda: case tokentype::tk_let: diff --git a/src/reader2/DToplevelSeqSsm.cpp b/src/reader2/DToplevelSeqSsm.cpp index 2b5b0dcb..612f64fd 100644 --- a/src/reader2/DToplevelSeqSsm.cpp +++ b/src/reader2/DToplevelSeqSsm.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -152,6 +153,10 @@ namespace xo { this->on_bool_token(tk, p_psm); return; + case tokentype::tk_nil: + this->on_nil_token(tk, p_psm); + return; + case tokentype::tk_leftparen: this->on_leftparen_token(tk, p_psm); return; @@ -378,7 +383,7 @@ namespace xo { break; } - Super::on_token(tk, p_psm); + Super::illegal_token(tk, p_psm); } void @@ -404,7 +409,32 @@ namespace xo { break; } - Super::on_token(tk, p_psm); + Super::illegal_token(tk, p_psm); + } + + void + DToplevelSeqSsm::on_nil_token(const Token & tk, + ParserStateMachine * p_psm) + { + switch (seqtype_) { + case exprseqtype::toplevel_interactive: + { + auto dvalue = DList::nil(); + auto expr = DConstant::make(p_psm->expr_alloc(), dvalue); + + DProgressSsm::start(p_psm->parser_alloc(), + expr, + p_psm); + return; + } + case exprseqtype::toplevel_batch: + break; + case exprseqtype::N: + assert(false); + break; + } + + Super::illegal_token(tk, p_psm); } void @@ -431,7 +461,7 @@ namespace xo { break; } - Super::on_token(tk, p_psm); + Super::illegal_token(tk, p_psm); } void @@ -454,7 +484,7 @@ namespace xo { break; } - Super::on_token(tk, p_psm); + Super::illegal_token(tk, p_psm); } void diff --git a/utest/SchematikaParser.test.cpp b/utest/SchematikaParser.test.cpp index 0b1fea58..6f97d7a0 100644 --- a/utest/SchematikaParser.test.cpp +++ b/utest/SchematikaParser.test.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ namespace xo { using xo::scm::Token; using xo::mm::AGCObject; using xo::scm::DPrimitive_gco_2_gco_gco; + using xo::scm::DList; using xo::scm::DString; using xo::scm::DFloat; using xo::scm::DInteger; @@ -603,6 +605,67 @@ namespace xo { log && fixture.log_memory_layout(&log); } + TEST_CASE("SchematikaParser-interactive-nil", "[reader2][SchematikaParser]") + { + const auto & testname = Catch::getResultCapture().getCurrentTestName(); + + constexpr bool c_debug_flag = false; + 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: + * + * nil ; + * + **/ + + { + auto & result = parser.on_token(Token::nil_token()); + + log && log("after nil 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_expression()); + REQUIRE(result.result_expr()); + + auto expr = obj::from(result.result_expr()); + REQUIRE(expr); + + REQUIRE(expr->value()); + + auto value_list = obj::from(expr->value()); + + REQUIRE(value_list); + + REQUIRE(value_list->is_empty()); + } + + //REQUIRE(result.is_error()); + //// illegal input on token + //REQUIRE(result.error_description()); + + log && fixture.log_memory_layout(&log); + } + TEST_CASE("SchematikaParser-interactive-arith", "[reader2][SchematikaParser]") { const auto & testname = Catch::getResultCapture().getCurrentTestName();