xo-reader: feat: mvp lambda parsing [untested]

This commit is contained in:
Roland Conybeare 2024-08-17 13:26:57 -04:00
commit 1628d8f44c
5 changed files with 134 additions and 27 deletions

View file

@ -11,34 +11,63 @@
namespace xo { namespace xo {
namespace scm { namespace scm {
/**
* ( name(1) : type(1) , ..., )
* ^ ^ ^ ^ ^
* | | | | |
* | | | | argl_1b
* | argl_1a | argla
* argl_0 argl_1b
*
* argl_0 --on_leftparen_token()--> argl_1a
* argl_1a --on_formal()--> argl_1b
* argl_1b -+-on_comma_token()--> argl_1a
* \-on_rightparen_token()--> (done)
**/
enum class formalarglstatetype { enum class formalarglstatetype {
invalid = -1, invalid = -1,
argl_0, argl_0,
argl_1, argl_1a,
argl_1b,
n_formalarglstatetype, n_formalarglstatetype,
}; };
extern const char *
formalarglstatetype_descr(formalarglstatetype x);
inline std::ostream &
operator<< (std::ostream & os, formalarglstatetype x) {
os << formalarglstatetype_descr(x);
return os;
}
/** @class expect_formal_arglist /** @class expect_formal_arglist
* @brief parser state-machine for a formal parameter list * @brief parser state-machine for a formal parameter list
*
* ( name(1) : type(1), ..., )
* ^
* |
* argl_0
**/ **/
class expect_formal_arglist_xs : public exprstate { class expect_formal_arglist_xs : public exprstate {
public:
using Variable = xo::ast::Variable;
public: public:
expect_formal_arglist_xs(); expect_formal_arglist_xs();
static std::unique_ptr<expect_formal_arglist_xs> make(); static std::unique_ptr<expect_formal_arglist_xs> make();
const std::vector<formal_arg> & argl() const { return argl_; }
virtual void on_leftparen_token(const token_type & tk, virtual void on_leftparen_token(const token_type & tk,
exprstatestack * p_stack, exprstatestack * p_stack,
rp<Expression> * p_emit_expr) override; rp<Expression> * p_emit_expr) override;
virtual void on_formal(const rp<Variable> & formal,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr) override;
virtual void on_comma_token(const token_type & tk,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr) override;
virtual void on_rightparen_token(const token_type & tk,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr) override;
virtual void print(std::ostream & os) const override;
private: private:
/** parsing state-machine state **/ /** parsing state-machine state **/
@ -46,7 +75,7 @@ namespace xo {
/** populate with (parmaeter-name, parameter-type) list /** populate with (parmaeter-name, parameter-type) list
* as they're encountered * as they're encountered
**/ **/
std::vector<formal_arg> argl_; std::vector<rp<Variable>> argl_;
}; };
} /*namespace scm*/ } /*namespace scm*/
} /*namespace xo*/ } /*namespace xo*/

View file

@ -17,6 +17,9 @@ namespace xo {
* | formal_1 * | formal_1
* formal_0 * formal_0
* *
* formal_0 --on_symbol()--> formal_1
* formal_1 --on_colon_token()--> formal_2
* formal_2 --on_typedescr()--> (done)
**/ **/
enum class formalstatetype { enum class formalstatetype {
invalid = -1, invalid = -1,
@ -44,6 +47,8 @@ namespace xo {
public: public:
expect_formal_xs() = default; expect_formal_xs() = default;
static std::unique_ptr<expect_formal_xs> make();
virtual void on_symbol(const std::string & symbol_name, virtual void on_symbol(const std::string & symbol_name,
exprstatestack * p_stack, exprstatestack * p_stack,
rp<Expression> * p_emit_expr) override; rp<Expression> * p_emit_expr) override;
@ -68,7 +73,7 @@ namespace xo {
private: private:
/** parsing state-machine state **/ /** parsing state-machine state **/
formalstatetype formalxs_type_; formalstatetype formalxs_type_ = formalstatetype::formal_0;
/** populate with {parameter-name, parameter-type} /** populate with {parameter-name, parameter-type}
* as they're encountered * as they're encountered
**/ **/

View file

@ -4,9 +4,30 @@
*/ */
#include "expect_formal_arglist_xs.hpp" #include "expect_formal_arglist_xs.hpp"
#include "expect_formal_xs.hpp"
#include "xo/expression/Variable.hpp"
#include "xo/indentlog/print/vector.hpp"
namespace xo { namespace xo {
namespace scm { namespace scm {
const char *
formalarglstatetype_descr(formalarglstatetype x) {
switch (x) {
case formalarglstatetype::invalid:
return "invalid";
case formalarglstatetype::argl_0:
return "argl_0";
case formalarglstatetype::argl_1a:
return "argl_1a";
case formalarglstatetype::argl_1b:
return "argl_1b";
case formalarglstatetype::n_formalarglstatetype:
break;
}
return "?formalarglstatetype";
}
std::unique_ptr<expect_formal_arglist_xs> std::unique_ptr<expect_formal_arglist_xs>
expect_formal_arglist_xs::make() { expect_formal_arglist_xs::make() {
return std::make_unique<expect_formal_arglist_xs> return std::make_unique<expect_formal_arglist_xs>
@ -23,13 +44,62 @@ namespace xo {
rp<Expression> * p_emit_expr) rp<Expression> * p_emit_expr)
{ {
if (farglxs_type_ == formalarglstatetype::argl_0) { if (farglxs_type_ == formalarglstatetype::argl_0) {
this->farglxs_type_ = formalarglstatetype::argl_1; this->farglxs_type_ = formalarglstatetype::argl_1a;
return; p_stack->push_exprstate(expect_formal_xs::make());
} else {
exprstate::on_leftparen_token(tk, p_stack, p_emit_expr);
} }
exprstate::on_leftparen_token(tk, p_stack, p_emit_expr);
} }
void
expect_formal_arglist_xs::on_formal(const rp<Variable> & formal,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr)
{
if (farglxs_type_ == formalarglstatetype::argl_1a) {
this->farglxs_type_ = formalarglstatetype::argl_1b;
this->argl_.push_back(formal);
} else {
exprstate::on_formal(formal, p_stack, p_emit_expr);
}
}
void
expect_formal_arglist_xs::on_comma_token(const token_type & tk,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr)
{
if (farglxs_type_ == formalarglstatetype::argl_1b) {
this->farglxs_type_ = formalarglstatetype::argl_1a;
p_stack->push_exprstate(expect_formal_xs::make());
} else {
exprstate::on_comma_token(tk, p_stack, p_emit_expr);
}
}
void
expect_formal_arglist_xs::on_rightparen_token(const token_type & tk,
exprstatestack * p_stack,
rp<Expression> * p_emit_expr)
{
if (farglxs_type_ == formalarglstatetype::argl_1b) {
std::unique_ptr<exprstate> self = p_stack->pop_exprstate();
p_stack->top_exprstate().on_formal_arglist(this->argl_,
p_stack, p_emit_expr);
} else {
exprstate::on_rightparen_token(tk, p_stack, p_emit_expr);
}
}
void
expect_formal_arglist_xs::print(std::ostream & os) const {
os << "<expect_formal_arglist_xs"
<< xtag("type", farglxs_type_);
os << xtag("farglxs_type", farglxs_type_);
os << xtag("argl", argl_);
os << ">";
}
} /*namespace scm*/ } /*namespace scm*/
} /*namespace xo*/ } /*namespace xo*/

View file

@ -4,8 +4,10 @@
*/ */
#include "expect_formal_xs.hpp" #include "expect_formal_xs.hpp"
#include "xo/expression/Variable.hpp"
namespace xo { namespace xo {
using xo::ast::Variable;
using xo::reflect::TypeDescr; using xo::reflect::TypeDescr;
namespace scm{ namespace scm{
@ -26,6 +28,11 @@ namespace xo {
return "???formalstatetype"; return "???formalstatetype";
} }
std::unique_ptr<expect_formal_xs>
expect_formal_xs::make() {
return std::make_unique<expect_formal_xs>(expect_formal_xs());
}
void void
expect_formal_xs::on_symbol(const std::string & symbol_name, expect_formal_xs::on_symbol(const std::string & symbol_name,
exprstatestack * p_stack, exprstatestack * p_stack,
@ -64,7 +71,10 @@ namespace xo {
std::unique_ptr<exprstate> self = p_stack->pop_exprstate(); std::unique_ptr<exprstate> self = p_stack->pop_exprstate();
//p_stack->top_exprstate().on_formal(result_, p_stack, p_emit_expr); rp<Variable> var = Variable::make(result_.name(),
result_.td());
p_stack->top_exprstate().on_formal(var, p_stack, p_emit_expr);
} else { } else {
exprstate::on_typedescr(td, p_stack, p_emit_expr); exprstate::on_typedescr(td, p_stack, p_emit_expr);
} }

View file

@ -24,12 +24,9 @@ namespace xo {
if (lmxs_type_ == lambdastatetype::lm_0) { if (lmxs_type_ == lambdastatetype::lm_0) {
this->lmxs_type_ = lambdastatetype::lm_1; this->lmxs_type_ = lambdastatetype::lm_1;
p_stack->push_exprstate(expect_formal_arglist_xs::make()); p_stack->push_exprstate(expect_formal_arglist_xs::make());
return; } else {
exprstate::on_lambda_token(tk, p_stack, p_emit_expr);
} }
exprstate::on_lambda_token(tk,
p_stack,
p_emit_expr);
} }
void void
@ -41,12 +38,9 @@ namespace xo {
this->lmxs_type_ = lambdastatetype::lm_2; this->lmxs_type_ = lambdastatetype::lm_2;
this->argl_ = argl; this->argl_ = argl;
p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression()); p_stack->push_exprstate(expect_expr_xs::expect_rhs_expression());
return; } else {
exprstate::on_formal_arglist(argl, p_stack, p_emit_expr);
} }
exprstate::on_formal_arglist(argl,
p_stack,
p_emit_expr);
} }
void void
@ -57,10 +51,9 @@ namespace xo {
if (lmxs_type_ == lambdastatetype::lm_2) { if (lmxs_type_ == lambdastatetype::lm_2) {
this->lmxs_type_ = lambdastatetype::lm_3; this->lmxs_type_ = lambdastatetype::lm_3;
this->body_ = expr.promote(); this->body_ = expr.promote();
return; } else {
exprstate::on_expr(expr, p_stack, p_emit_expr);
} }
exprstate::on_expr(expr, p_stack, p_emit_expr);
} }
void void