xo-interpreter: apply expressions + llvm builtins working!
This commit is contained in:
parent
7ca1366bec
commit
1d1e72adf3
31 changed files with 531 additions and 50 deletions
|
|
@ -76,13 +76,16 @@ namespace xo {
|
|||
// unreachable
|
||||
break;
|
||||
case applyexprstatetype::apply_0:
|
||||
log && log("stash fn -> new state apply_1");
|
||||
this->fn_expr_ = expr.promote();
|
||||
this->applyxs_type_ = applyexprstatetype::apply_1;
|
||||
return;
|
||||
case applyexprstatetype::apply_1:
|
||||
log && log("error: was expecting lparen");
|
||||
// error, expecting lparen
|
||||
break;
|
||||
case applyexprstatetype::apply_2:
|
||||
log && log(xtag("expr", expr), xtag("do", "stash expr -> new state apply_3"));
|
||||
this->args_expr_v_.push_back(expr.promote());
|
||||
this->applyxs_type_ = applyexprstatetype::apply_3;
|
||||
return;
|
||||
|
|
@ -145,6 +148,7 @@ namespace xo {
|
|||
|
||||
if (this->applyxs_type_ == applyexprstatetype::apply_3) {
|
||||
/* (done) state */
|
||||
log("apply complete -> pop + send expr");
|
||||
|
||||
rp<Apply> apply_expr = Apply::make(this->fn_expr_, this->args_expr_v_);
|
||||
|
||||
|
|
@ -169,6 +173,15 @@ namespace xo {
|
|||
os << ">";
|
||||
}
|
||||
|
||||
bool
|
||||
apply_xs::pretty_print(const xo::print::ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "apply_xs",
|
||||
refrtag("applyxs_type", applyxs_type_),
|
||||
refrtag("fn_expr", fn_expr_),
|
||||
refrtag("args_expr_v", args_expr_v_));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -201,7 +201,9 @@ namespace xo {
|
|||
expect_expr_xs::on_i64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()),
|
||||
xtag("tk", tk),
|
||||
xtag("do", "push progress xs w/ tk value"));
|
||||
|
||||
progress_xs::start
|
||||
(Constant<int64_t>::make(tk.i64_value()),
|
||||
|
|
@ -233,6 +235,7 @@ namespace xo {
|
|||
|
||||
log && log(xtag("exstype", this->exs_type_),
|
||||
xtag("expr", expr.promote()));
|
||||
log && log("pop expect_expr_xs, forward to parent");
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
|
|
@ -247,6 +250,7 @@ namespace xo {
|
|||
|
||||
log && log(xtag("exstype", this->exs_type_),
|
||||
xtag("expr", expr.promote()));
|
||||
log && log("pop expect_expr_xs, forward to parent");
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace xo {
|
|||
if (!td) {
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
std::string errmsg = tostr("unexpected token for parsing state",
|
||||
std::string errmsg = tostr("expect_type_xs: unexpected token for parsing state",
|
||||
xtag("expecting", exp),
|
||||
xtag("token", tk.tk_type()),
|
||||
xtag("text", tk.text()),
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ namespace xo {
|
|||
* a = 1; // single assignment
|
||||
* a == 1; // rhs expression
|
||||
* a + b; // rhs expression
|
||||
* a(1,2); // apply expression
|
||||
* Variable must have been defined!
|
||||
*/
|
||||
bp<Variable> var = p_psm->lookup_var(tk.text());
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ namespace xo {
|
|||
const char * expect_str,
|
||||
parserstatemachine * p_psm) const
|
||||
{
|
||||
std::string errmsg = tostr("unexpected token for parsing state",
|
||||
std::string errmsg = tostr("exprstate::illegal_input_on_token: unexpected token for parsing state",
|
||||
xtag("expecting", expect_str),
|
||||
xtag("token", tk.tk_type()),
|
||||
xtag("text", tk.text()),
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ namespace xo {
|
|||
if (lmxs_type_ == lambdastatetype::lm_1) {
|
||||
this->lmxs_type_ = lambdastatetype::lm_2;
|
||||
this->parent_env_ = p_psm->top_envframe().promote();
|
||||
this->local_env_ = LocalEnv::make(argl, parent_env_);
|
||||
this->local_env_ = LocalSymtab::make(argl, parent_env_);
|
||||
|
||||
p_psm->push_envframe(local_env_);
|
||||
|
||||
|
|
@ -268,6 +268,31 @@ namespace xo {
|
|||
exprstate::on_semicolon_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
lambda_xs::on_f64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr const char * c_self_name = "lambda_xs::on_f64_token";
|
||||
|
||||
/* f64 literal can begin lambda body, otherwise illegal.
|
||||
* for example:
|
||||
* def foo = lambda (x: bool) 3.14;
|
||||
*/
|
||||
if (lmxs_type_ == lambdastatetype::lm_2) {
|
||||
/* omitting return type.
|
||||
* omitting left brace.
|
||||
*/
|
||||
this->lmxs_type_ = lambdastatetype::lm_4;
|
||||
|
||||
expect_expr_xs::start(p_psm);
|
||||
p_psm->on_f64_token(tk);
|
||||
} else {
|
||||
this->illegal_input_on_token(c_self_name, tk, this->get_expect_str(), p_psm);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: on_i64_token, on_bool token
|
||||
|
||||
void
|
||||
lambda_xs::print(std::ostream & os) const {
|
||||
os << "<lambda_xs"
|
||||
|
|
@ -279,7 +304,8 @@ namespace xo {
|
|||
lambda_xs::pretty_print(const xo::print::ppindentinfo & ppii) const
|
||||
{
|
||||
return ppii.pps()->pretty_struct(ppii, "lambda_xs",
|
||||
refrtag("lmxs_type", lmxs_type_));
|
||||
refrtag("lmxs_type", lmxs_type_),
|
||||
refrtag("body", body_));
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -172,6 +172,17 @@ namespace xo {
|
|||
this->xs_stack_.top_exprstate().on_else_token(tk, this);
|
||||
}
|
||||
|
||||
void
|
||||
parserstatemachine::on_f64_token(const token_type & tk)
|
||||
{
|
||||
scope log(XO_DEBUG(debug_flag_));
|
||||
|
||||
log && log(xtag("tk", tk),
|
||||
xtag("psm", this));
|
||||
|
||||
this->xs_stack_.top_exprstate().on_f64_token(tk, this);
|
||||
}
|
||||
|
||||
void
|
||||
parserstatemachine::on_error(const char * self_name, std::string errmsg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -310,6 +310,8 @@ namespace xo {
|
|||
progress_xs::on_expr(bp<Expression> expr,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()), xtag("expr", expr));
|
||||
|
||||
/* note: previous token probably an operator,
|
||||
* handled from progress_xs::on_operator_token(),
|
||||
* which pushes expect_expr_xs::expect_rhs_expression()
|
||||
|
|
@ -318,21 +320,33 @@ namespace xo {
|
|||
constexpr const char * c_self_name = "progress_xs::on_expr";
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
if (op_type_ == optype::invalid) {
|
||||
this->illegal_input_on_expr(c_self_name, expr, exp, p_psm);
|
||||
}
|
||||
if (lhs_) {
|
||||
if (op_type_ == optype::invalid) {
|
||||
/* two consecutive expression without an operator */
|
||||
this->illegal_input_on_expr(c_self_name, expr, exp, p_psm);
|
||||
}
|
||||
|
||||
#ifdef NOT_QUITE
|
||||
assert(result.get());
|
||||
assert(result.get());
|
||||
|
||||
/* this expression complete.. */
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
/* this expression complete.. */
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
/* ..but more operators could follow, so don't commit yet */
|
||||
p_stack->push_exprstate(progress_xs::make(result));
|
||||
/* ..but more operators could follow, so don't commit yet */
|
||||
p_stack->push_exprstate(progress_xs::make(result));
|
||||
#endif
|
||||
|
||||
this->rhs_ = expr.promote();
|
||||
this->rhs_ = expr.promote();
|
||||
} else {
|
||||
/* control here on input like
|
||||
* add(1,2)...
|
||||
*
|
||||
* add(1,2) needs to be handled inside a progress_xs
|
||||
* instance because may be followed by an operator:
|
||||
* add(1,2) + ...
|
||||
*/
|
||||
this->lhs_ = expr.promote();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -375,6 +389,46 @@ namespace xo {
|
|||
assert(false);
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_comma_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
/* note: implementation parllels .on_semicolon_token(), .on_rightparen_token() */
|
||||
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
constexpr const char * self_name = "progress::xs::on_comma_token";
|
||||
|
||||
auto & xs_stack = p_psm->xs_stack_;
|
||||
|
||||
/* stack may be something like
|
||||
*
|
||||
* applyexpr
|
||||
* expect_expr_xs
|
||||
* progress_xs
|
||||
* <-- comma
|
||||
*
|
||||
* 1. comma completes expression-in-progress
|
||||
*/
|
||||
|
||||
/* comma confirms stack expression */
|
||||
rp<Expression> expr = this->assemble_expr(p_psm);
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
if (xs_stack.empty()) {
|
||||
throw std::runtime_error(tostr(self_name,
|
||||
": expected non-empty parsing state"));
|
||||
}
|
||||
|
||||
log && log(xtag("stack", &xs_stack));
|
||||
|
||||
p_psm->top_exprstate().on_expr(expr, p_psm);
|
||||
|
||||
/* now deliver comma */
|
||||
p_psm->top_exprstate().on_comma_token(tk, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_typedescr(TypeDescr /*td*/,
|
||||
parserstatemachine * /*p_psm*/)
|
||||
|
|
@ -441,6 +495,7 @@ namespace xo {
|
|||
this->on_operator_token(tk, p_psm);
|
||||
}
|
||||
|
||||
/* editor bait: on_lparen */
|
||||
void
|
||||
progress_xs::on_leftparen_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
|
|
@ -456,12 +511,24 @@ namespace xo {
|
|||
/* start function call */
|
||||
assert(rhs_.get() == nullptr);
|
||||
|
||||
/* unwind this progress_xs + replace with function call */
|
||||
|
||||
rp<Expression> fn_expr = lhs_;
|
||||
|
||||
/* reset this progress_xs back to empty state;
|
||||
* apply_xs will be responsible for lhs_.
|
||||
*/
|
||||
lhs_ = nullptr;
|
||||
|
||||
#ifdef OBSOLETE
|
||||
/* don't unwind! want to handle input like
|
||||
* f(x,y)+g(z)
|
||||
*/
|
||||
/* unwind this progress_xs + replace with function call */
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
#endif
|
||||
|
||||
apply_xs::start(fn_expr, p_psm);
|
||||
|
||||
/* control will reenter progress_xs via .on_expr() */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -486,7 +553,7 @@ namespace xo {
|
|||
/* stack may be something like:
|
||||
*
|
||||
* lparen_0
|
||||
* expect_rhs_expression
|
||||
* expect_expr_xs
|
||||
* expr_progress
|
||||
* <-- rightparen
|
||||
*
|
||||
|
|
@ -497,6 +564,9 @@ namespace xo {
|
|||
/* right paren confirms stack expression */
|
||||
rp<Expression> expr = this->assemble_expr(p_psm);
|
||||
|
||||
log && log(xtag("expr", expr),
|
||||
xtag("do", "pop self + send {expr, rparen} -> parent"));
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
if (xs_stack.empty()) {
|
||||
|
|
@ -756,7 +826,7 @@ namespace xo {
|
|||
&& (rhs_ ? ppii.pps()->print_upto(refrtag("rhs", rhs_)) : true)
|
||||
&& ppii.pps()->print_upto(">"));
|
||||
} else {
|
||||
ppii.pps()->write("<progress_xs");
|
||||
ppii.pps()->write("<progress_xs ");
|
||||
if (lhs_)
|
||||
ppii.pps()->pretty(refrtag("lhs", lhs_));
|
||||
if (op_type_ != optype::invalid)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue