diff --git a/include/xo/reader/envframestack.hpp b/include/xo/reader/envframestack.hpp index d27713ac..ac933dae 100644 --- a/include/xo/reader/envframestack.hpp +++ b/include/xo/reader/envframestack.hpp @@ -13,12 +13,21 @@ namespace xo { * @brief A stack of envframe objects **/ class envframestack { + public: + using Variable = xo::ast::Variable; + public: envframestack() {} bool empty() const { return stack_.empty(); } std::size_t size() const { return stack_.size(); } + /** lookup variable in environment stack. + * Visit frames in fifo order, report first match; + * nullptr if no matches. + **/ + rp lookup(const std::string & x) const; + envframe & top_envframe(); void push_envframe(envframe x); void pop_envframe(); diff --git a/include/xo/reader/parserstatemachine.hpp b/include/xo/reader/parserstatemachine.hpp index e39021f3..3ad71b13 100644 --- a/include/xo/reader/parserstatemachine.hpp +++ b/include/xo/reader/parserstatemachine.hpp @@ -20,6 +20,7 @@ namespace xo { class parserstatemachine { public: using Expression = xo::ast::Expression; + using Variable = xo::ast::Variable; public: parserstatemachine(exprstatestack * p_stack, @@ -33,6 +34,14 @@ namespace xo { exprstate & top_exprstate(); void push_exprstate(std::unique_ptr x); + /** lookup variable name in lexical context represented by + * this psm. nullptr if not found + **/ + rp lookup_var(const std::string & x) const; + + void push_envframe(envframe x); + void pop_envframe(); + public: /** stack of incomplete parser work. * generally speaking, push when to start new work for nested content; diff --git a/src/reader/envframestack.cpp b/src/reader/envframestack.cpp index 52543dc4..047e1789 100644 --- a/src/reader/envframestack.cpp +++ b/src/reader/envframestack.cpp @@ -6,6 +6,8 @@ #include "envframestack.hpp" namespace xo { + using xo::ast::Variable; + namespace scm { envframe & envframestack::top_envframe() { @@ -50,6 +52,20 @@ namespace xo { } } + rp + envframestack::lookup(const std::string & x) const { + for (std::size_t i = 0, z = this->size(); i < z; ++i) { + const auto & frame = (*this)[i]; + + auto retval = frame.lookup(x); + + if (retval) + return retval; + } + + return nullptr; + } + void envframestack::print(std::ostream & os) const { os << " + parserstatemachine::lookup_var(const std::string & x) const { + return p_env_stack_->lookup(x); + } + std::unique_ptr parserstatemachine::pop_exprstate() { return p_stack_->pop_exprstate(); @@ -22,6 +29,16 @@ namespace xo { parserstatemachine::push_exprstate(std::unique_ptr x) { p_stack_->push_exprstate(std::move(x)); } + + void + parserstatemachine::push_envframe(envframe x) { + p_env_stack_->push_envframe(std::move(x)); + } + + void + parserstatemachine::pop_envframe() { + p_env_stack_->pop_envframe(); + } } /*namespace scm*/ } /*namespace xo*/