xo-parser: + expect_type + exprir::td_ etc.

This commit is contained in:
Roland Conybeare 2024-08-01 09:44:52 +10:00
commit 4132a66165
3 changed files with 82 additions and 24 deletions

View file

@ -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<Expression> 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<Expression> & 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<Expression> 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<char>;
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 &

View file

@ -6,13 +6,15 @@
#include "parser.hpp"
#include "xo/expression/DefineExpr.hpp"
#include "xo/expression/Constant.hpp"
#include <regex>
//#include <regex>
#include <stdexcept>
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 << "<exprir"
<< xtag("type", xir_type_)
<< xtag("symbol_name", symbol_name_)
<< xtag("expr", expr_)
<< ">";
<< 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<double>();
else if(tk.text() == "f32")
td = Reflect::require<float>();
else if(tk.text() == "i16")
td = Reflect::require<std::int16_t>();
else if(tk.text() == "i32")
td = Reflect::require<std::int32_t>();
else if(tk.text() == "i64")
td = Reflect::require<std::int64_t>();
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 << "<exprstate"
<< xtag("type", exs_type_)
<< xtag("def_lhs_symbol", def_lhs_symbol_)
<< xtag("def_lhs_type", def_lhs_type_)
<< ">";
<< xtag("def_lhs_symbol", def_lhs_symbol_);
if (def_lhs_td_)
os << xtag("def_lhs_td", def_lhs_td_->short_name());
os << ">";
}
// ----- parser -----

View file

@ -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);