diff --git a/include/xo/reader/expect_expr_xs.hpp b/include/xo/reader/expect_expr_xs.hpp index 91cc7f31..6f6513e3 100644 --- a/include/xo/reader/expect_expr_xs.hpp +++ b/include/xo/reader/expect_expr_xs.hpp @@ -68,6 +68,9 @@ namespace xo { virtual void on_f64_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_string_token(const token_type & tk, + parserstatemachine * p_psm) final override; + /** update exprstate in response to a successfully-parsed subexpression **/ virtual void on_expr(bp expr, parserstatemachine * p_psm) override; diff --git a/include/xo/reader/exprseq_xs.hpp b/include/xo/reader/exprseq_xs.hpp index 22b07f9e..60b483ad 100644 --- a/include/xo/reader/exprseq_xs.hpp +++ b/include/xo/reader/exprseq_xs.hpp @@ -59,6 +59,8 @@ namespace xo { parserstatemachine * p_psm) override; virtual void on_f64_token(const token_type & tk, parserstatemachine * p_psm) override; + virtual void on_string_token(const token_type & tk, + parserstatemachine * p_psm) final override; // ----- victory methods ----- diff --git a/include/xo/reader/exprstate.hpp b/include/xo/reader/exprstate.hpp index c21f453f..ed3187c3 100644 --- a/include/xo/reader/exprstate.hpp +++ b/include/xo/reader/exprstate.hpp @@ -218,6 +218,10 @@ namespace xo { virtual void on_f64_token(const token_type & tk, parserstatemachine * p_psm); + /** handle incoming string-literal token **/ + virtual void on_string_token(const token_type & tk, + parserstatemachine * p_psm); + protected: /** throw exception when next token is inconsistent with * parsing state diff --git a/src/reader/expect_expr_xs.cpp b/src/reader/expect_expr_xs.cpp index c297b969..10caafeb 100644 --- a/src/reader/expect_expr_xs.cpp +++ b/src/reader/expect_expr_xs.cpp @@ -173,7 +173,7 @@ namespace xo { */ progress_xs::start(var.promote(), p_psm); -#ifdef NOT_YET + #ifdef NOT_YET p_stack->push_exprstate(exprstate(exprstatetype::expr_progress, Variable::make(name, type))); #endif @@ -227,6 +227,21 @@ namespace xo { p_psm); } + void + expect_expr_xs::on_string_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + /* e.g. + * def msg = "hello, world"; + * \----tk----/ + */ + progress_xs::start + (Constant::make(tk.text()), + p_psm); + } + void expect_expr_xs::on_expr(bp expr, parserstatemachine * p_psm) diff --git a/src/reader/expect_type_xs.cpp b/src/reader/expect_type_xs.cpp index 93fd1bbd..62d797f5 100644 --- a/src/reader/expect_type_xs.cpp +++ b/src/reader/expect_type_xs.cpp @@ -45,6 +45,8 @@ namespace xo { if (tk.text() == "bool") td = Reflect::require(); + else if (tk.text() == "str") + td = Reflect::require(); else if (tk.text() == "f64") td = Reflect::require(); else if(tk.text() == "f32") diff --git a/src/reader/exprseq_xs.cpp b/src/reader/exprseq_xs.cpp index 7bbb30b6..48307d77 100644 --- a/src/reader/exprseq_xs.cpp +++ b/src/reader/exprseq_xs.cpp @@ -181,7 +181,7 @@ namespace xo { scope log(XO_DEBUG(p_psm->debug_flag())); - constexpr const char * c_self_name = "exprseq_xs::on_i64_token"; + constexpr const char * c_self_name = "exprseq_xs::on_f64_token"; if (xseqtype_ == exprseqtype::toplevel_interactive) { @@ -199,6 +199,44 @@ namespace xo { } } + void + exprseq_xs::on_string_token(const token_type & tk, + parserstatemachine * p_psm) + { + using xo::scm::Constant; + + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * c_self_name = "exprseq_xs::on_string_token"; + + if (xseqtype_ == exprseqtype::toplevel_interactive) + { + // remark: + // 1. Constant is an expression. At present (nov 2025) these are + // reference-counted (+ leak in xo-interpreter). + // 2. Could fix leak by adding a finalization feature to GC. + // Do intend to eventually support finalization, + // but not to use it here. + // 3. Instead mean to change allocation strategy for Expression + // to use GC instead. + // 4. As intermediate step try migrating Expression hierarchy + // to support arena allocation. + // See xo/alloc/ArenaAllocT.hpp + assoc'd unit test + // + progress_xs::start(Constant::make(tk.text()), p_psm); + } else { + /* policy: don't allow literals as toplevel expressions + * unless interactive session. + */ + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, + tk, + exp, + p_psm); + } + } + void exprseq_xs::on_typedescr(TypeDescr /*td*/, parserstatemachine * /*p_psm*/) diff --git a/src/reader/exprstate.cpp b/src/reader/exprstate.cpp index 3b631e26..5bbfcb86 100644 --- a/src/reader/exprstate.cpp +++ b/src/reader/exprstate.cpp @@ -336,7 +336,7 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - constexpr const char * c_self_name = "exprstate::on_bool"; + constexpr const char * c_self_name = "exprstate::on_bool_token"; const char * exp = get_expect_str(); this->illegal_input_on_token(c_self_name, tk, exp, p_psm); @@ -348,7 +348,7 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - constexpr const char * c_self_name = "exprstate::on_i64"; + constexpr const char * c_self_name = "exprstate::on_i64_token"; const char * exp = get_expect_str(); this->illegal_input_on_token(c_self_name, tk, exp, p_psm); @@ -360,7 +360,19 @@ namespace xo { { scope log(XO_DEBUG(p_psm->debug_flag())); - constexpr const char * c_self_name = "exprstate::on_f64"; + constexpr const char * c_self_name = "exprstate::on_f64_token"; + const char * exp = get_expect_str(); + + this->illegal_input_on_token(c_self_name, tk, exp, p_psm); + } + + void + exprstate::on_string_token(const token_type & tk, + parserstatemachine * p_psm) + { + scope log(XO_DEBUG(p_psm->debug_flag())); + + constexpr const char * c_self_name = "exprstate::on_string_token"; const char * exp = get_expect_str(); this->illegal_input_on_token(c_self_name, tk, exp, p_psm); @@ -399,7 +411,7 @@ namespace xo { return; case tokentype::tk_string: - assert(false); + this->on_string_token(tk, p_psm); return; case tokentype::tk_symbol: