From 4132a66165529704b9d4b24c7b27b662b0c71856 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 1 Aug 2024 09:44:52 +1000 Subject: [PATCH] xo-parser: + expect_type + exprir::td_ etc. --- include/xo/parser/parser.hpp | 14 ++++++-- src/parser/parser.cpp | 64 +++++++++++++++++++++++++++++++----- utest/parser.test.cpp | 28 ++++++++-------- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/include/xo/parser/parser.hpp b/include/xo/parser/parser.hpp index 92b8e046..e5e87194 100644 --- a/include/xo/parser/parser.hpp +++ b/include/xo/parser/parser.hpp @@ -20,6 +20,7 @@ namespace xo { empty, symbol, expression, + typedescr, n_exprirtype }; @@ -43,6 +44,7 @@ namespace xo { class exprir { public: using Expression = xo::ast::Expression; + using TypeDescr = xo::reflect::TypeDescr; public: exprir() = default; @@ -52,10 +54,14 @@ namespace xo { exprir(exprirtype xir_type, rp expr) : xir_type_{xir_type}, expr_{std::move(expr)} {} + exprir(exprirtype xir_type, + TypeDescr td) + : xir_type_{xir_type}, td_{td} {} exprirtype xir_type() const { return xir_type_; } const std::string & symbol_name() const { return symbol_name_; } const rp & expr() const { return expr_; } + TypeDescr td() const { return td_; } void print(std::ostream & os) const; @@ -66,6 +72,8 @@ namespace xo { std::string symbol_name_; /** xir_type=expression: a completed expression **/ rp expr_; + /** xir_type=typedescr: object identifying/describing a datatype **/ + TypeDescr td_ = nullptr; }; inline std::ostream & @@ -88,6 +96,7 @@ namespace xo { expect_rhs_expression, expect_symbol, + expect_type, n_exprstatetype }; @@ -184,6 +193,7 @@ namespace xo { public: using exprtype = xo::ast::exprtype; using token_type = token; + using TypeDescr = xo::reflect::TypeDescr; public: exprstate() = default; @@ -240,7 +250,7 @@ namespace xo { * | | | | | | (done) * | | | | | def_4:expect_rhs_expression * | | | | def_3 - * | | | def_2:expect_symbol + * | | | def_2:expect_type * | | def_1 * | def_0:expect_symbol * expect_toplevel_expression_sequence @@ -262,7 +272,7 @@ namespace xo { /** e.g. f64 in * def foo : f64 = 1 **/ - std::string def_lhs_type_; + TypeDescr def_lhs_td_ = nullptr; }; /*exprstate*/ inline std::ostream & diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index ab6404fd..9bd6b8f6 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -6,13 +6,15 @@ #include "parser.hpp" #include "xo/expression/DefineExpr.hpp" #include "xo/expression/Constant.hpp" -#include +//#include #include namespace xo { using xo::ast::Expression; using xo::ast::DefineExpr; using xo::ast::Constant; + using xo::reflect::Reflect; + using xo::reflect::TypeDescr; namespace scm { const char * @@ -26,6 +28,8 @@ namespace xo { return "symbol"; case exprirtype::expression: return "expression"; + case exprirtype::typedescr: + return "typedescr"; case exprirtype::n_exprirtype: break; } @@ -38,8 +42,10 @@ namespace xo { os << ""; + << xtag("expr", expr_); + if (td_) + os << xtag("td", td_->short_name()); + os << ">"; } const char * @@ -63,6 +69,8 @@ namespace xo { return "expect_rhs_expression"; case exprstatetype::expect_symbol: return "expect_symbol"; + case exprstatetype::expect_type: + return "expect_type"; case exprstatetype::n_exprstatetype: break; } @@ -147,6 +155,7 @@ namespace xo { case exprstatetype::expect_rhs_expression: return false; case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: case exprstatetype::n_exprstatetype: @@ -173,6 +182,10 @@ namespace xo { case exprstatetype::expect_symbol: return true; + case exprstatetype::expect_type: + /* treat symbol as typename */ + return true; + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -198,6 +211,7 @@ namespace xo { * may not begin with a colon */ case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -225,6 +239,7 @@ namespace xo { * may not begin with singleassign '=' */ case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -249,6 +264,7 @@ namespace xo { return true; case exprstatetype::expect_symbol: + case exprstatetype::expect_type: return false; case exprstatetype::invalid: @@ -324,6 +340,36 @@ namespace xo { exprstatetype::invalid /*not used*/, exprstatetype::invalid /*not used*/); + case exprstatetype::expect_type: { + TypeDescr td = nullptr; + + /* TODO: replace with typetable lookup */ + + if (tk.text() == "f64") + td = Reflect::require(); + else if(tk.text() == "f32") + td = Reflect::require(); + else if(tk.text() == "i16") + td = Reflect::require(); + else if(tk.text() == "i32") + td = Reflect::require(); + else if(tk.text() == "i64") + td = Reflect::require(); + + if (!td) { + throw std::runtime_error + (tostr(self_name, + ": unknown type name", + " (expecting f64|f32|i16|i32|i64)", + xtag("typename", tk.text()))); + } + + return expraction(expractiontype::pop, + exprir(exprirtype::typedescr, td), + exprstatetype::invalid /*not used*/, + exprstatetype::invalid /*not used*/); + } + case exprstatetype::invalid: case exprstatetype::n_exprstatetype: /* unreachable */ @@ -352,7 +398,7 @@ namespace xo { return expraction(expractiontype::push1, exprir(), - exprstatetype::expect_symbol, + exprstatetype::expect_type, exprstatetype::invalid /*not used*/); } else { assert(false); @@ -520,7 +566,7 @@ namespace xo { return expraction(); case exprstatetype::def_2: this->exs_type_ = exprstatetype::def_3; - this->def_lhs_type_ = ir.symbol_name(); + this->def_lhs_td_ = ir.td(); return expraction::keep(); case exprstatetype::def_3: @@ -553,6 +599,7 @@ namespace xo { } case exprstatetype::expect_rhs_expression: + case exprstatetype::expect_type: case exprstatetype::expect_symbol: /* unreachable * (this exprstate issues pop instruction from exprstate::on_input() @@ -571,9 +618,10 @@ namespace xo { exprstate::print(std::ostream & os) const { os << ""; + << xtag("def_lhs_symbol", def_lhs_symbol_); + if (def_lhs_td_) + os << xtag("def_lhs_td", def_lhs_td_->short_name()); + os << ">"; } // ----- parser ----- diff --git a/utest/parser.test.cpp b/utest/parser.test.cpp index d5be7db7..e656d9de 100644 --- a/utest/parser.test.cpp +++ b/utest/parser.test.cpp @@ -96,7 +96,7 @@ namespace xo { */ CHECK(parser.stack_size() == 3); if (parser.stack_size() > 0) - CHECK(parser.i_exstype(0) == exprstatetype::expect_symbol); + CHECK(parser.i_exstype(0) == exprstatetype::expect_type); if (parser.stack_size() > 1) CHECK(parser.i_exstype(1) == exprstatetype::def_2); if (parser.stack_size() > 2) @@ -105,14 +105,14 @@ namespace xo { } /* input: - * def foo : footype - * ^ ^ - * 0 1 + * def foo : f64 + * ^ ^ + * 0 1 */ { - auto r4 = parser.include_token(token_type::symbol_token("footype")); + auto r4 = parser.include_token(token_type::symbol_token("f64")); - cerr << "parser state after [def foo : footype]" << endl; + cerr << "parser state after [def foo : f64]" << endl; cerr << parser << endl; REQUIRE(r4.get() == nullptr); @@ -138,14 +138,14 @@ namespace xo { } /* input: - * def foo : footype = - * ^ ^ - * 0 1 + * def foo : f64 = + * ^ ^ + * 0 1 */ { auto r5 = parser.include_token(token_type::singleassign()); - cerr << "parser state after [def foo : footype =]" << endl; + cerr << "parser state after [def foo : f64 =]" << endl; cerr << parser << endl; REQUIRE(r5.get() == nullptr); @@ -169,14 +169,14 @@ namespace xo { } /* input: - * def foo : footype = 3.14159265 - * ^ ^ - * 0 1 + * def foo : f64 = 3.14159265 + * ^ ^ + * 0 1 */ { auto r6 = parser.include_token(token_type::f64_token("3.14159265")); - cerr << "parser state after [def foo : footype = 3.14159265]" << endl; + cerr << "parser state after [def foo : f64 = 3.14159265]" << endl; cerr << parser << endl; REQUIRE(r6.get() != nullptr);