xo-reader: refactor to simplify parser+parserstatemachine

This commit is contained in:
Roland Conybeare 2025-07-22 23:09:55 -05:00
commit 81bbc080fd
10 changed files with 85 additions and 129 deletions

View file

@ -126,6 +126,7 @@ namespace xo {
rp<Expression> def_expr = this->def_expr_;
this->defxs_type_ = defexprstatetype::def_6;
return;
}
constexpr const char * c_self_name = "define_xs::on_expr";

View file

@ -13,7 +13,7 @@ namespace xo {
namespace scm {
bp<LocalEnv>
envframestack::top_envframe() {
envframestack::top_envframe() const {
std::size_t z = stack_.size();
if (z == 0) {

View file

@ -190,7 +190,7 @@ namespace xo {
* arbitrary number of expressions.
*/
*(p_psm->p_result_) = parser_result::expression(expr.promote());
p_psm->result_ = parser_result::expression(expr.promote());
}
void
@ -203,7 +203,7 @@ namespace xo {
* semicolons are sometimes mandatory to avoid ambiguity.
*/
*(p_psm->p_result_) = parser_result::expression(expr.promote());
p_psm->result_ = parser_result::expression(expr.promote());
}
} /*namespace scm*/

View file

@ -321,8 +321,7 @@ namespace xo {
exprstate::on_bool_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 * c_self_name = "exprstate::on_bool";
const char * exp = get_expect_str();
@ -334,8 +333,7 @@ namespace xo {
exprstate::on_i64_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 * c_self_name = "exprstate::on_i64";
const char * exp = get_expect_str();
@ -347,8 +345,7 @@ namespace xo {
exprstate::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 * c_self_name = "exprstate::on_f64";
const char * exp = get_expect_str();
@ -364,7 +361,7 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("tk", tk));
log && log(xtag("state", *this));
log && log(xtag("psm", *p_psm));
log && log(xtag("psm", p_psm));
log && log(xtag("proofoflogging", true));
switch (tk.tk_type()) {

View file

@ -18,50 +18,35 @@
namespace xo {
using xo::ast::Expression;
//using xo::ast::GlobalEnv;
using xo::ast::LocalEnv;
//using xo::ast::DefineExpr;
//using xo::ast::ConvertExpr;
//using xo::ast::Constant;
//using xo::reflect::Reflect;
using xo::reflect::TypeDescr;
namespace scm {
// ----- parser -----
parser::parser(bool debug_flag)
: xs_stack_{}, env_stack_{}, result_{}, debug_flag_{debug_flag}
: psm_{debug_flag}
{
/* top-level environment. initially empty */
rp<LocalEnv> toplevel_env = LocalEnv::make_empty();
this->env_stack_.push_envframe(toplevel_env);
this->psm_.env_stack_.push_envframe(toplevel_env);
}
bool
parser::has_incomplete_expr() const {
/* (don't count toplevel exprseq) */
return xs_stack_.size() > 1;
return psm_.xs_stack_.size() > 1;
}
void
parser::begin_interactive_session() {
parserstatemachine psm(&xs_stack_,
&env_stack_,
&result_,
debug_flag_);
exprseq_xs::start(exprseqtype::toplevel_interactive, &psm);
exprseq_xs::start(exprseqtype::toplevel_interactive, &psm_);
}
void
parser::begin_translation_unit() {
parserstatemachine psm(&xs_stack_,
&env_stack_,
&result_,
debug_flag_);
exprseq_xs::start(exprseqtype::toplevel_batch, &psm);
exprseq_xs::start(exprseqtype::toplevel_batch, &psm_);
}
const parser_result &
@ -70,7 +55,7 @@ namespace xo {
constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag), xtag("tk", tk));
if (xs_stack_.empty()) {
if (psm_.xs_stack_.empty()) {
throw std::runtime_error(tostr("parser::include_token",
": parser not expecting input"
"(call parser.begin_translation_unit()..?)",
@ -79,21 +64,19 @@ namespace xo {
/* stack_ is non-empty */
log && log(xtag("top", xs_stack_.top_exprstate()));
log && log(xtag("top", psm_.xs_stack_.top_exprstate()));
parserstatemachine psm(&xs_stack_, &env_stack_, &result_, debug_flag_);
psm_.xs_stack_.top_exprstate().on_input(tk, &psm_);
xs_stack_.top_exprstate().on_input(tk, &psm);
return result_;
return psm_.result_;
} /*include_token*/
void
parser::reset_to_idle_toplevel()
{
xs_stack_.reset_to_toplevel();
env_stack_.reset_to_toplevel();
result_ = parser_result::none();
psm_.xs_stack_.reset_to_toplevel();
psm_.env_stack_.reset_to_toplevel();
psm_.result_ = parser_result::none();
} /*discard_current_state*/
void
@ -101,7 +84,7 @@ namespace xo {
os << "<parser"
<< std::endl;
xs_stack_.print(os);
psm_.xs_stack_.print(os);
os << ">" << std::endl;
}

View file

@ -17,32 +17,32 @@ namespace xo {
namespace scm {
bp<Variable>
parserstatemachine::lookup_var(const std::string & x) const {
return p_env_stack_->lookup(x);
return env_stack_.lookup(x);
}
void
parserstatemachine::upsert_var(bp<Variable> x) {
p_env_stack_->upsert(x);
env_stack_.upsert(x);
}
std::unique_ptr<exprstate>
parserstatemachine::pop_exprstate() {
return p_stack_->pop_exprstate();
return xs_stack_.pop_exprstate();
}
exprstate &
parserstatemachine::top_exprstate() {
return p_stack_->top_exprstate();
return xs_stack_.top_exprstate();
}
void
parserstatemachine::push_exprstate(std::unique_ptr<exprstate> x) {
p_stack_->push_exprstate(std::move(x));
xs_stack_.push_exprstate(std::move(x));
}
bp<LocalEnv>
parserstatemachine::top_envframe() const {
return p_env_stack_->top_envframe();
return env_stack_.top_envframe();
}
void
@ -52,7 +52,7 @@ namespace xo {
log && log(xtag("frame", x));
p_env_stack_->push_envframe(x);
env_stack_.push_envframe(x);
}
rp<LocalEnv>
@ -60,7 +60,7 @@ namespace xo {
constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag));
return p_env_stack_->pop_envframe();
return env_stack_.pop_envframe();
}
void
@ -70,10 +70,9 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("x", x),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_expr(x, this);
this->xs_stack_.top_exprstate().on_expr(x, this);
}
void
@ -83,12 +82,11 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("x", x),
xtag("psm", *this));
xtag("psm", this));
assert(!this->p_stack_->empty());
assert(!this->xs_stack_.empty());
this->p_stack_
->top_exprstate().on_expr_with_semicolon(x, this);
this->xs_stack_.top_exprstate().on_expr_with_semicolon(x, this);
}
void
@ -98,10 +96,9 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("x", x),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_symbol(x, this);
this->xs_stack_.top_exprstate().on_symbol(x, this);
}
void
@ -111,10 +108,9 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_semicolon_token(tk, this);
this->xs_stack_.top_exprstate().on_semicolon_token(tk, this);
}
void
@ -124,10 +120,9 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_operator_token(tk, this);
this->xs_stack_.top_exprstate().on_operator_token(tk, this);
}
void
@ -137,10 +132,9 @@ namespace xo {
scope log(XO_DEBUG(c_debug_flag));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_leftbrace_token(tk, this);
this->xs_stack_.top_exprstate().on_leftbrace_token(tk, this);
}
void
@ -149,10 +143,9 @@ namespace xo {
scope log(XO_DEBUG(debug_flag_));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_rightbrace_token(tk, this);
this->xs_stack_.top_exprstate().on_rightbrace_token(tk, this);
}
void
@ -161,10 +154,9 @@ namespace xo {
scope log(XO_DEBUG(debug_flag_));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_then_token(tk, this);
this->xs_stack_.top_exprstate().on_then_token(tk, this);
}
void
@ -173,23 +165,22 @@ namespace xo {
scope log(XO_DEBUG(debug_flag_));
log && log(xtag("tk", tk),
xtag("psm", *this));
xtag("psm", this));
this->p_stack_
->top_exprstate().on_else_token(tk, this);
this->xs_stack_.top_exprstate().on_else_token(tk, this);
}
void
parserstatemachine::on_error(const char * self_name, std::string errmsg)
{
*(this->p_result_) = parser_result::error(self_name, std::move(errmsg));
this->result_ = parser_result::error(self_name, std::move(errmsg));
}
void
parserstatemachine::print(std::ostream & os) const {
os << "<psm";
os << xtag("stack", p_stack_);
os << xtag("env_stack", p_env_stack_);
os << xtag("stack", &xs_stack_);
os << xtag("env_stack", &env_stack_);
os << ">";
}
} /*namespace scm*/

View file

@ -19,17 +19,17 @@ namespace xo {
if (!pps->print_upto("<psm"))
return false;
if (!pps->print_upto_tag("stack", x.p_stack_))
if (!pps->print_upto_tag("stack", &x.xs_stack_))
return false;
if (!pps->print_upto_tag("env_stack", x.p_env_stack_))
if (!pps->print_upto_tag("env_stack", &x.env_stack_))
return false;
return pps->print_upto(">");
} else {
pps->write("<psm");
pps->newline_pretty_tag(ppii.ci1(), "stack", x.p_stack_);
pps->newline_pretty_tag(ppii.ci1(), "env_stack", x.p_env_stack_);
pps->newline_pretty_tag(ppii.ci1(), "stack", &x.xs_stack_);
pps->newline_pretty_tag(ppii.ci1(), "env_stack", &x.env_stack_);
pps->write(">");
return false;