diff --git a/include/xo/reader/parser.hpp b/include/xo/reader/parser.hpp index 715bc23f..ebdf2076 100644 --- a/include/xo/reader/parser.hpp +++ b/include/xo/reader/parser.hpp @@ -83,26 +83,26 @@ namespace xo { gen_expr_{std::move(candidate_expr)}, def_expr_{std::move(def_expr)} {} - static exprstate expect_toplevel_expression_sequence() { - return exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr); + static std::unique_ptr expect_toplevel_expression_sequence() { + return std::make_unique(exprstate(exprstatetype::expect_toplevel_expression_sequence, nullptr, nullptr)); } - static exprstate expect_rhs_expression() { - return exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr); + static std::unique_ptr expect_rhs_expression() { + return std::make_unique(exprstate(exprstatetype::expect_rhs_expression, nullptr, nullptr)); } - static exprstate expect_symbol() { - return exprstate(exprstatetype::expect_symbol, nullptr, nullptr); + static std::unique_ptr expect_symbol() { + return std::make_unique(exprstate(exprstatetype::expect_symbol, nullptr, nullptr)); } - static exprstate expect_type() { - return exprstate(exprstatetype::expect_type, nullptr, nullptr); + static std::unique_ptr expect_type() { + return std::make_unique(exprstate(exprstatetype::expect_type, nullptr, nullptr)); } - static exprstate make_expr_progress(rp expr) { - return exprstate(exprstatetype::expr_progress, expr, nullptr); + static std::unique_ptr make_expr_progress(rp expr) { + return std::make_unique(exprstate(exprstatetype::expr_progress, expr, nullptr)); } - static exprstate def_0(rp def_expr) { - return exprstate(exprstatetype::def_0, nullptr, def_expr); + static std::unique_ptr def_0(rp def_expr) { + return std::make_unique(exprstate(exprstatetype::def_0, nullptr, def_expr)); } - static exprstate lparen_0() { - return exprstate(exprstatetype::lparen_0, nullptr, nullptr); + static std::unique_ptr lparen_0() { + return std::make_unique(exprstate(exprstatetype::lparen_0, nullptr, nullptr)); } exprstatetype exs_type() const { return exs_type_; } @@ -217,13 +217,13 @@ namespace xo { std::size_t size() const { return stack_.size(); } exprstate & top_exprstate(); - void push_exprstate(const exprstate & exs); - void pop_exprstate(); + void push_exprstate(std::unique_ptr exs); + std::unique_ptr pop_exprstate(); /** relative to top-of-stack. * 0 -> top (last in), z-1 -> bottom (first in) **/ - exprstate & operator[](std::size_t i) { + std::unique_ptr & operator[](std::size_t i) { std::size_t z = stack_.size(); assert(i < z); @@ -231,7 +231,7 @@ namespace xo { return stack_[z - i - 1]; } - const exprstate & operator[](std::size_t i) const { + const std::unique_ptr & operator[](std::size_t i) const { std::size_t z = stack_.size(); assert(i < z); @@ -242,7 +242,7 @@ namespace xo { void print (std::ostream & os) const; private: - std::vector stack_; + std::vector> stack_; }; inline std::ostream & @@ -251,6 +251,12 @@ namespace xo { return os; } + inline std::ostream & + operator<< (std::ostream & os, const exprstatestack * x) { + x->print(os); + return os; + } + /** schematica parser * * Examples: @@ -401,7 +407,7 @@ namespace xo { std::size_t z = xs_stack_.size(); if (i < z) { - return xs_stack_[i].exs_type(); + return xs_stack_[i]->exs_type(); } /* out of bounds */ diff --git a/src/reader/parser.cpp b/src/reader/parser.cpp index a03199ad..6cef967b 100644 --- a/src/reader/parser.cpp +++ b/src/reader/parser.cpp @@ -507,7 +507,8 @@ namespace xo { /* have to do pop first, before sending symbol to * the o.g. symbol-requester */ - p_stack->pop_exprstate(); + std::unique_ptr self = p_stack->pop_exprstate(); + p_stack->top_exprstate().on_symbol(tk.text(), p_stack, p_emit_expr); return; @@ -537,7 +538,7 @@ namespace xo { xtag("typename", tk.text()))); } - p_stack->pop_exprstate(); + std::unique_ptr self = p_stack->pop_exprstate(); p_stack->top_exprstate().on_typedescr(td, p_stack, p_emit_expr); return; } @@ -657,7 +658,7 @@ namespace xo { if (this->exs_type_ == exprstatetype::expr_progress) { rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -681,7 +682,7 @@ namespace xo { } else if (this->exs_type_ == exprstatetype::def_5) { rp expr = this->def_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -770,14 +771,14 @@ namespace xo { /* right paren confirms stack expression */ rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ if (p_stack->empty()) { throw std::runtime_error(tostr(self_name, ": expected non-empty parsing stack")); } - log && log(xtag("stack", *p_stack)); + log && log(xtag("stack", p_stack)); p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); @@ -786,7 +787,7 @@ namespace xo { } else if (this->exs_type_ == exprstatetype::lparen_1) { rp expr = this->gen_expr_; - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, p_emit_expr); } @@ -981,7 +982,7 @@ namespace xo { case exprstatetype::expect_rhs_expression: { - p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ + std::unique_ptr self = p_stack->pop_exprstate(); /* NOT KOSHER. invalidates *this */ p_stack->top_exprstate().on_expr(expr, p_stack, @@ -1088,23 +1089,23 @@ namespace xo { ("parser::top_exprstate: unexpected empty stack"); } - return stack_[z-1]; + return *(stack_[z-1]); } void - exprstatestack::push_exprstate(const exprstate & exs) { + exprstatestack::push_exprstate(std::unique_ptr exs) { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), - xtag("exs", exs)); + xtag("exs", *exs)); std::size_t z = stack_.size(); stack_.resize(z+1); - stack_[z] = exs; + stack_[z] = std::move(exs); } - void + std::unique_ptr exprstatestack::pop_exprstate() { constexpr bool c_debug_flag = true; scope log(XO_DEBUG(c_debug_flag), @@ -1112,8 +1113,15 @@ namespace xo { std::size_t z = stack_.size(); - if (z > 0) + if (z > 0) { + std::unique_ptr top = std::move(stack_[z-1]); + stack_.resize(z-1); + + return top; + } else { + return nullptr; + } } void