xo-reader xo-expression xo-tokenizer xo-jit: comparison + apply
This commit is contained in:
parent
7a9357954d
commit
93b2daab6c
28 changed files with 720 additions and 171 deletions
|
|
@ -11,6 +11,7 @@ set(SELF_SRCS
|
|||
define_xs.cpp
|
||||
if_else_xs.cpp
|
||||
progress_xs.cpp
|
||||
apply_xs.cpp
|
||||
paren_xs.cpp
|
||||
sequence_xs.cpp
|
||||
exprseq_xs.cpp
|
||||
|
|
|
|||
174
xo-reader/src/reader/apply_xs.cpp
Normal file
174
xo-reader/src/reader/apply_xs.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/* @file apply_xs.cpp */
|
||||
|
||||
#include "apply_xs.hpp"
|
||||
#include "parserstatemachine.hpp"
|
||||
#include "expect_expr_xs.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
// ----- applyexprstatetype -----
|
||||
|
||||
const char *
|
||||
applyexprstatetype_descr(applyexprstatetype x) {
|
||||
switch (x) {
|
||||
case applyexprstatetype::invalid: return "invalid";
|
||||
case applyexprstatetype::apply_0: return "apply_0";
|
||||
case applyexprstatetype::apply_1: return "apply_1";
|
||||
case applyexprstatetype::apply_2: return "apply_2";
|
||||
case applyexprstatetype::apply_3: return "apply_3";
|
||||
case applyexprstatetype::n_applyexprstatetype: break;
|
||||
}
|
||||
|
||||
return "???applyexprstatetype";
|
||||
}
|
||||
|
||||
std::ostream &
|
||||
operator<<(std::ostream & os, applyexprstatetype x) {
|
||||
os << applyexprstatetype_descr(x);
|
||||
return os;
|
||||
}
|
||||
|
||||
// ----- apply_xs -----
|
||||
|
||||
std::unique_ptr<apply_xs>
|
||||
apply_xs::make() {
|
||||
return std::make_unique<apply_xs>(apply_xs());
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::start(rp<Expression> fn_expr,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
p_psm->push_exprstate(apply_xs::make());
|
||||
p_psm->top_exprstate().on_expr(fn_expr.get(), p_psm);
|
||||
p_psm->top_exprstate().on_leftparen_token(token_type::leftparen(), p_psm);
|
||||
}
|
||||
|
||||
apply_xs::apply_xs()
|
||||
: exprstate(exprstatetype::applyexpr)
|
||||
{}
|
||||
|
||||
const char *
|
||||
apply_xs::get_expect_str() const {
|
||||
switch(applyxs_type_) {
|
||||
case applyexprstatetype::invalid: return "invalid";
|
||||
case applyexprstatetype::apply_0: return "expr";
|
||||
case applyexprstatetype::apply_1: return "lparen";
|
||||
case applyexprstatetype::apply_2: return "expr";
|
||||
case applyexprstatetype::apply_3: return "comma|rparen";
|
||||
case applyexprstatetype::n_applyexprstatetype: break;
|
||||
}
|
||||
|
||||
return "?expect";
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::on_expr(bp<Expression> expr,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
switch (applyxs_type_) {
|
||||
case applyexprstatetype::invalid:
|
||||
case applyexprstatetype::n_applyexprstatetype:
|
||||
// unreachable
|
||||
break;
|
||||
case applyexprstatetype::apply_0:
|
||||
this->fn_expr_ = expr.promote();
|
||||
this->applyxs_type_ = applyexprstatetype::apply_1;
|
||||
return;
|
||||
case applyexprstatetype::apply_1:
|
||||
// error, expecting lparen
|
||||
break;
|
||||
case applyexprstatetype::apply_2:
|
||||
this->args_expr_v_.push_back(expr.promote());
|
||||
this->applyxs_type_ = applyexprstatetype::apply_3;
|
||||
return;
|
||||
case applyexprstatetype::apply_3:
|
||||
// error, expecting comma|rparen
|
||||
break;
|
||||
}
|
||||
|
||||
/* control here --implies-> error state */
|
||||
|
||||
constexpr const char * c_self_name = "apply_xs::on_expr";
|
||||
const char * exp = this->get_expect_str();
|
||||
|
||||
this->illegal_input_on_expr(c_self_name, expr, exp, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::on_comma_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
if (this->applyxs_type_ == applyexprstatetype::apply_3) {
|
||||
this->applyxs_type_ = applyexprstatetype::apply_2;
|
||||
} else {
|
||||
constexpr const char * c_self_name = "apply_xs::on_comma_token";
|
||||
const char * exp = this->get_expect_str();
|
||||
|
||||
this->illegal_input_on_token(c_self_name, tk, exp, p_psm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::on_leftparen_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log("applyxs_type", applyxs_type_);
|
||||
|
||||
if (this->applyxs_type_ == applyexprstatetype::apply_1) {
|
||||
this->applyxs_type_ = applyexprstatetype::apply_2;
|
||||
} else {
|
||||
constexpr const char * c_self_name = "apply_xs::on_leftparen_token";
|
||||
const char * exp = this->get_expect_str();
|
||||
|
||||
this->illegal_input_on_token(c_self_name, tk, exp, p_psm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::on_rightparen_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log("applyxs_type", applyxs_type_);
|
||||
|
||||
if (this->applyxs_type_ == applyexprstatetype::apply_3) {
|
||||
/* (done) state */
|
||||
|
||||
rp<Apply> apply_expr = Apply::make(this->fn_expr_, this->args_expr_v_);
|
||||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
p_psm->top_exprstate().on_expr(apply_expr, p_psm);
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr const char * c_self_name = "apply_xs::on_rightparen_token";
|
||||
const char * exp = this->get_expect_str();
|
||||
|
||||
this->illegal_input_on_token(c_self_name, tk, exp, p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
apply_xs::print(std::ostream & os) const
|
||||
{
|
||||
os << "<apply_xs"
|
||||
<< xtag("this", (void*)this)
|
||||
<< xtag("applyxs_type", applyxs_type_);
|
||||
os << ">";
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/* end apply_xs.cpp */
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
/* @file define_xs.cpp */
|
||||
|
||||
#include "define_xs.hpp"
|
||||
#include "exprstatestack.hpp"
|
||||
#include "parserstatemachine.hpp"
|
||||
#include "expect_symbol_xs.hpp"
|
||||
#include "expect_expr_xs.hpp"
|
||||
|
|
@ -45,8 +44,7 @@ namespace xo {
|
|||
void
|
||||
define_xs::start(parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
p_psm->push_exprstate(define_xs::make());
|
||||
p_psm->top_exprstate().on_def_token(token_type::def(), p_psm);
|
||||
|
|
@ -103,8 +101,7 @@ namespace xo {
|
|||
define_xs::on_expr(bp<Expression> expr,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log(xtag("defxs_type", defxs_type_));
|
||||
|
||||
|
|
@ -118,10 +115,12 @@ namespace xo {
|
|||
*/
|
||||
rp<Expression> rhs_value = expr.promote();
|
||||
|
||||
if (this->cvt_expr_)
|
||||
if (this->cvt_expr_) {
|
||||
this->cvt_expr_->assign_arg(rhs_value);
|
||||
else
|
||||
this->def_expr_->assign_rhs(rhs_value);;
|
||||
} else {
|
||||
/* note: establishes .def_expr_ valuetype */
|
||||
this->def_expr_->assign_rhs(rhs_value);
|
||||
}
|
||||
|
||||
rp<Expression> def_expr = this->def_expr_;
|
||||
|
||||
|
|
@ -139,8 +138,7 @@ namespace xo {
|
|||
define_xs::on_expr_with_semicolon(bp<Expression> expr,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log(xtag("defxs_type", defxs_type_));
|
||||
|
||||
|
|
@ -153,14 +151,40 @@ namespace xo {
|
|||
define_xs::on_symbol(const std::string & symbol_name,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log("defxs_type", defxs_type_);
|
||||
|
||||
if (this->defxs_type_ == defexprstatetype::def_1) {
|
||||
this->defxs_type_ = defexprstatetype::def_2;
|
||||
this->def_expr_->assign_lhs_name(symbol_name);
|
||||
|
||||
// if this is a genuine top-level define (i.e. nesting level = 0),
|
||||
// then we need to upsert so we can refer to rhs later.
|
||||
//
|
||||
// In other contexts (e.g. body-of-lambda) will be rewriting
|
||||
// {
|
||||
// def y = foo(x,x);
|
||||
// bar(y,y);
|
||||
// }
|
||||
// into something like
|
||||
// {
|
||||
// (lambda (y123) bar(y123,y123))(foo(x,x));
|
||||
// }
|
||||
//
|
||||
// This works in the body of lambda, because we don't evaluate anything
|
||||
// until lambda definition is complete.
|
||||
//
|
||||
// For interactive top-level defs we want to evaluate as we go,
|
||||
// so need incremental bindings.
|
||||
|
||||
if (p_psm->env_stack_size() == 2) {
|
||||
/* remember variable binding in lexical context,
|
||||
* so we can refer to it later
|
||||
*/
|
||||
p_psm->upsert_var(this->def_expr_->lhs_variable());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -174,8 +198,7 @@ namespace xo {
|
|||
define_xs::on_typedescr(TypeDescr td,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log("defxs_type", defxs_type_);
|
||||
|
||||
|
|
@ -183,6 +206,7 @@ namespace xo {
|
|||
this->defxs_type_ = defexprstatetype::def_4;
|
||||
this->cvt_expr_ = ConvertExprAccess::make(td /*dest_type*/,
|
||||
nullptr /*source_expr*/);
|
||||
/* note: establishes .def_expr_ valuetype */
|
||||
this->def_expr_->assign_rhs(this->cvt_expr_);
|
||||
return;
|
||||
}
|
||||
|
|
@ -243,8 +267,7 @@ namespace xo {
|
|||
{
|
||||
/* def expr consumes semicolon */
|
||||
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log("defxs_type", defxs_type_);
|
||||
|
||||
|
|
@ -253,32 +276,6 @@ namespace xo {
|
|||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
// if this is a genuine top-level define (i.e. nesting level = 0),
|
||||
// then we need to upsert so we can refer to rhs later.
|
||||
//
|
||||
// In other contexts (e.g. body-of-lambda) will be rewriting
|
||||
// {
|
||||
// def y = foo(x,x);
|
||||
// bar(y,y);
|
||||
// }
|
||||
// into something like
|
||||
// {
|
||||
// (lambda (y123) bar(y123,y123))(foo(x,x));
|
||||
// }
|
||||
//
|
||||
// This works in the body of lambda, because we don't evaluate anything
|
||||
// until lambda definition is complete.
|
||||
//
|
||||
// For interactive top-level defs we want to evaluate as we go,
|
||||
// so need incremental bindings.
|
||||
|
||||
if (p_psm->env_stack_size() == 1) {
|
||||
/* remember variable binding in lexical context,
|
||||
* so we can refer to it later
|
||||
*/
|
||||
p_psm->upsert_var(def_expr->lhs_variable());
|
||||
}
|
||||
|
||||
p_psm->top_exprstate().on_expr(def_expr, p_psm);
|
||||
return;
|
||||
}
|
||||
|
|
@ -357,11 +354,6 @@ namespace xo {
|
|||
<< xtag("this", (void*)this)
|
||||
//<< xtag("type", exs_type_)
|
||||
<< xtag("defxs_type", defxs_type_);
|
||||
|
||||
//if (def_expr_)
|
||||
// os << xtag("def_expr", def_expr_);
|
||||
//if (cvt_expr_)
|
||||
// os << xtag("cvt_expr", cvt_expr_);
|
||||
os << ">";
|
||||
}
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@
|
|||
#include "expect_expr_xs.hpp"
|
||||
#include "parserstatemachine.hpp"
|
||||
#include "exprstatestack.hpp"
|
||||
#include "lambda_xs.hpp"
|
||||
#include "define_xs.hpp"
|
||||
#include "lambda_xs.hpp"
|
||||
#include "if_else_xs.hpp"
|
||||
#include "paren_xs.hpp"
|
||||
#include "sequence_xs.hpp"
|
||||
#include "progress_xs.hpp"
|
||||
|
|
@ -52,12 +53,21 @@ namespace xo {
|
|||
cxl_on_rightbrace_{cxl_on_rightbrace}
|
||||
{}
|
||||
|
||||
const char *
|
||||
expect_expr_xs::get_expect_str() const
|
||||
{
|
||||
if (allow_defs_) {
|
||||
return "def|lambda|lparen|lbrace|literal|var";
|
||||
} else {
|
||||
return "lambda|lparen|lbrace|literal|var";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
expect_expr_xs::on_def_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
if (allow_defs_) {
|
||||
define_xs::start(p_psm);
|
||||
|
|
@ -70,20 +80,25 @@ namespace xo {
|
|||
expect_expr_xs::on_lambda_token(const token_type & /*tk*/,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
//constexpr const char * self_name = "exprstate::on_leftparen";
|
||||
|
||||
lambda_xs::start(p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
expect_expr_xs::on_if_token(const token_type & /*tk*/,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
if_else_xs::start(p_psm);
|
||||
}
|
||||
|
||||
void
|
||||
expect_expr_xs::on_leftparen_token(const token_type & /*tk*/,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
//constexpr const char * self_name = "exprstate::on_leftparen";
|
||||
|
||||
|
|
@ -95,8 +110,7 @@ namespace xo {
|
|||
expect_expr_xs::on_leftbrace_token(const token_type & /*tk*/,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
/* push lparen_0 to remember to look for subsequent rightparen. */
|
||||
sequence_xs::start(p_psm);
|
||||
|
|
@ -124,8 +138,7 @@ namespace xo {
|
|||
expect_expr_xs::on_symbol_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
log && log(xtag("tk", tk));
|
||||
|
||||
|
|
@ -199,8 +212,7 @@ namespace xo {
|
|||
expect_expr_xs::on_f64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
//constexpr const char * self_name = "exprstate::on_f64_token";
|
||||
|
||||
|
|
@ -243,6 +255,14 @@ namespace xo {
|
|||
p_psm->on_expr_with_semicolon(expr);
|
||||
} /*on_expr_with_semicolon*/
|
||||
|
||||
void
|
||||
expect_expr_xs::print(std::ostream & os) const {
|
||||
os << "<expect_expr_xs"
|
||||
<< xtag("allow_defs", allow_defs_)
|
||||
<< xtag("cxl_on_rightbrace", cxl_on_rightbrace_)
|
||||
<< ">";
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ namespace xo {
|
|||
|
||||
/* TODO: replace with typetable lookup */
|
||||
|
||||
if (tk.text() == "f64")
|
||||
if (tk.text() == "bool")
|
||||
td = Reflect::require<bool>();
|
||||
else if (tk.text() == "f64")
|
||||
td = Reflect::require<double>();
|
||||
else if(tk.text() == "f32")
|
||||
td = Reflect::require<float>();
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace xo {
|
|||
{
|
||||
/* in interactive session, allow top-level if-expressions.
|
||||
* Could be:
|
||||
* if sometest() do_something() do_otherthing();
|
||||
* if sometest() then do_something() else do_otherthing();
|
||||
*/
|
||||
if_else_xs::start(p_psm);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ namespace xo {
|
|||
return "defexpr";
|
||||
case exprstatetype::lambdaexpr:
|
||||
return "lambdaexpr";
|
||||
case exprstatetype::applyexpr:
|
||||
return "applyexpr";
|
||||
case exprstatetype::parenexpr:
|
||||
return "parenexpr";
|
||||
case exprstatetype::sequenceexpr:
|
||||
|
|
@ -450,6 +452,8 @@ namespace xo {
|
|||
case tokentype::tk_minus:
|
||||
case tokentype::tk_star:
|
||||
case tokentype::tk_slash:
|
||||
case tokentype::tk_cmpeq:
|
||||
case tokentype::tk_cmpne:
|
||||
this->on_operator_token(tk, p_psm);
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* @file progress_xs.cpp */
|
||||
|
||||
#include "progress_xs.hpp"
|
||||
#include "apply_xs.hpp"
|
||||
#include "exprstatestack.hpp"
|
||||
#include "expect_expr_xs.hpp"
|
||||
#include "parserstatemachine.hpp"
|
||||
|
|
@ -23,6 +24,18 @@ namespace xo {
|
|||
return "?optype";
|
||||
case optype::op_assign:
|
||||
return "op:=";
|
||||
case optype::op_less:
|
||||
return "op<";
|
||||
case optype::op_less_equal:
|
||||
return "op<=";
|
||||
case optype::op_equal:
|
||||
return "op==";
|
||||
case optype::op_not_equal:
|
||||
return "op!=";
|
||||
case optype::op_great:
|
||||
return "op>";
|
||||
case optype::op_great_equal:
|
||||
return "op>=";
|
||||
case optype::op_add:
|
||||
return "op+";
|
||||
case optype::op_subtract:
|
||||
|
|
@ -47,13 +60,21 @@ namespace xo {
|
|||
case optype::op_assign:
|
||||
return 1;
|
||||
|
||||
case optype::op_less:
|
||||
case optype::op_less_equal:
|
||||
case optype::op_equal:
|
||||
case optype::op_not_equal:
|
||||
case optype::op_great:
|
||||
case optype::op_great_equal:
|
||||
return 2;
|
||||
|
||||
case optype::op_add:
|
||||
case optype::op_subtract:
|
||||
return 2;
|
||||
return 3;
|
||||
|
||||
case optype::op_multiply:
|
||||
case optype::op_divide:
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -145,21 +166,27 @@ namespace xo {
|
|||
this->rhs_);
|
||||
}
|
||||
|
||||
case optype::op_equal:
|
||||
return Apply::make_cmp_eq_i64(lhs_, rhs_);
|
||||
|
||||
case optype::op_less:
|
||||
case optype::op_less_equal:
|
||||
case optype::op_not_equal:
|
||||
case optype::op_great:
|
||||
case optype::op_great_equal:
|
||||
assert(false);
|
||||
|
||||
case optype::op_add:
|
||||
return Apply::make_add2_f64(this->lhs_,
|
||||
this->rhs_);
|
||||
return Apply::make_add2_f64(lhs_, rhs_);
|
||||
|
||||
case optype::op_subtract:
|
||||
return Apply::make_sub2_f64(this->lhs_,
|
||||
this->rhs_);
|
||||
return Apply::make_sub2_f64(lhs_, rhs_);
|
||||
|
||||
case optype::op_multiply:
|
||||
return Apply::make_mul2_f64(this->lhs_,
|
||||
this->rhs_);
|
||||
return Apply::make_mul2_f64(lhs_, rhs_);
|
||||
|
||||
case optype::op_divide:
|
||||
return Apply::make_div2_f64(this->lhs_,
|
||||
this->rhs_);
|
||||
return Apply::make_div2_f64(lhs_, rhs_);
|
||||
|
||||
case optype::n_optype:
|
||||
/* unreachable */
|
||||
|
|
@ -301,8 +328,25 @@ namespace xo {
|
|||
progress_xs::on_leftparen_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
/* input like:
|
||||
* 'foo(' -> expect function call. might continue 'foo(a,b,c)'
|
||||
* 'foo+(' -> expect parenthesized expression. might continue 'foo+(bar/2)'
|
||||
*/
|
||||
|
||||
if (op_type_ == optype::invalid) {
|
||||
/* start function call */
|
||||
assert(rhs_.get() == nullptr);
|
||||
|
||||
/* unwind this progress_xs + replace with function call */
|
||||
|
||||
rp<Expression> fn_expr = lhs_;
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
apply_xs::start(fn_expr, p_psm);
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr const char * c_self_name = "exprstate::on_leftparen";
|
||||
const char * exp = get_expect_str();
|
||||
|
|
@ -320,7 +364,7 @@ namespace xo {
|
|||
|
||||
constexpr const char * self_name = "progress_xs::on_rightparen";
|
||||
|
||||
auto p_stack = p_psm->p_stack_;
|
||||
auto & xs_stack = p_psm->xs_stack_;
|
||||
|
||||
/* stack may be something like:
|
||||
*
|
||||
|
|
@ -338,12 +382,12 @@ namespace xo {
|
|||
|
||||
std::unique_ptr<exprstate> self = p_psm->pop_exprstate();
|
||||
|
||||
if (p_stack->empty()) {
|
||||
if (xs_stack.empty()) {
|
||||
throw std::runtime_error(tostr(self_name,
|
||||
": expected non-empty parsing stack"));
|
||||
}
|
||||
|
||||
log && log(xtag("stack", p_stack));
|
||||
log && log(xtag("stack", &xs_stack));
|
||||
|
||||
p_psm->top_exprstate().on_expr(expr, p_psm);
|
||||
|
||||
|
|
@ -406,6 +450,10 @@ namespace xo {
|
|||
return optype::op_multiply;
|
||||
case tokentype::tk_slash:
|
||||
return optype::op_divide;
|
||||
case tokentype::tk_cmpeq:
|
||||
return optype::op_equal;
|
||||
case tokentype::tk_cmpne:
|
||||
return optype::op_not_equal;
|
||||
default:
|
||||
assert(false);
|
||||
return optype::invalid;
|
||||
|
|
@ -487,6 +535,22 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_bool_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
{
|
||||
scope log(XO_DEBUG(p_psm->debug_flag()));
|
||||
|
||||
constexpr const char * c_self_name = "progress_xs::on_bool_token";
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
if (this->op_type_ == optype::invalid) {
|
||||
this->illegal_input_on_token(c_self_name, tk, exp, p_psm);
|
||||
} else {
|
||||
exprstate::on_bool_token(tk, p_psm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
progress_xs::on_i64_token(const token_type & tk,
|
||||
parserstatemachine * p_psm)
|
||||
|
|
@ -494,7 +558,7 @@ namespace xo {
|
|||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
constexpr const char * c_self_name = "progress_xs::on_i64";
|
||||
constexpr const char * c_self_name = "progress_xs::on_i64_token";
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
if (this->op_type_ == optype::invalid) {
|
||||
|
|
@ -511,7 +575,7 @@ namespace xo {
|
|||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
constexpr const char * c_self_name = "progress_xs::on_f64";
|
||||
constexpr const char * c_self_name = "progress_xs::on_f64_token";
|
||||
const char * exp = get_expect_str();
|
||||
|
||||
if (this->op_type_ == optype::invalid) {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,8 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
log && log(xtag("outcome", "noop"));
|
||||
log && log(xtag("outcome", "noop"),
|
||||
xtag("parser.stack_size", parser_.stack_size()));
|
||||
|
||||
return reader_result(nullptr, expr_span, parser_.stack_size(), reader_error());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue