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 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 {
invalid = -1,
argl_0,
argl_1,
argl_1a,
argl_1b,
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
* @brief parser state-machine for a formal parameter list
*
* ( name(1) : type(1), ..., )
* ^
* |
* argl_0
**/
class expect_formal_arglist_xs : public exprstate {
public:
using Variable = xo::ast::Variable;
public:
expect_formal_arglist_xs();
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,
exprstatestack * p_stack,
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:
/** parsing state-machine state **/
@ -46,7 +75,7 @@ namespace xo {
/** populate with (parmaeter-name, parameter-type) list
* as they're encountered
**/
std::vector<formal_arg> argl_;
std::vector<rp<Variable>> argl_;
};
} /*namespace scm*/
} /*namespace xo*/

View file

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

View file

@ -4,9 +4,30 @@
*/
#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 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>
expect_formal_arglist_xs::make() {
return std::make_unique<expect_formal_arglist_xs>
@ -23,13 +44,62 @@ namespace xo {
rp<Expression> * p_emit_expr)
{
if (farglxs_type_ == formalarglstatetype::argl_0) {
this->farglxs_type_ = formalarglstatetype::argl_1;
return;
this->farglxs_type_ = formalarglstatetype::argl_1a;
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 xo*/

View file

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

View file

@ -24,12 +24,9 @@ namespace xo {
if (lmxs_type_ == lambdastatetype::lm_0) {
this->lmxs_type_ = lambdastatetype::lm_1;
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
@ -41,12 +38,9 @@ namespace xo {
this->lmxs_type_ = lambdastatetype::lm_2;
this->argl_ = argl;
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
@ -57,10 +51,9 @@ namespace xo {
if (lmxs_type_ == lambdastatetype::lm_2) {
this->lmxs_type_ = lambdastatetype::lm_3;
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