/* file parserstatemachine.hpp * * author: Roland Conybeare, Aug 2024 */ #pragma once #include "exprstate.hpp" #include "envframestack.hpp" namespace xo { namespace scm { /** @class parserstatemachine * @brief public parser state. * * Schematica parser state; sent to subsidiary single-feature state machines. * For example entry points for the lambda feature (@ref lambda_xs) * will accept a non-const parserstatemachine pointer argument **/ class parserstatemachine { public: using Expression = xo::ast::Expression; using Variable = xo::ast::Variable; using LocalEnv = xo::ast::LocalEnv; using token_type = token; public: parserstatemachine(exprstatestack * p_stack, envframestack * p_env_stack, rp * p_emit_expr) : p_stack_{p_stack}, p_env_stack_{p_env_stack}, p_emit_expr_{p_emit_expr} {} std::unique_ptr pop_exprstate(); exprstate & top_exprstate(); void push_exprstate(std::unique_ptr x); /** lookup variable name in lexical context represented by * this psm. nullptr if not found **/ bp lookup_var(const std::string & x) const; /** update/replace binding for variable @p x in lexical context * represented by this psm. Always acts on innermost frame. **/ void upsert_var(bp x); bp top_envframe() const; void push_envframe(const rp & x); rp pop_envframe(); size_t env_stack_size() const { return p_env_stack_->size(); } // ----- parsing outputs ----- void on_expr(bp expr); void on_expr_with_semicolon(bp expr); void on_symbol(const std::string & symbol); // ---- parsing inputs ----- void on_semicolon_token(const token_type & tk); void on_operator_token(const token_type & tk); void on_leftbrace_token(const token_type & tk); void on_rightbrace_token(const token_type & tk); /** write human-readable representation on @p os **/ void print(std::ostream & os) const; public: /** stack of incomplete parser work. * generally speaking, push when to start new work for nested content; * pop when work complete **/ exprstatestack * p_stack_; /** stack of environment frames, one for each enclosing lambda **/ envframestack * p_env_stack_; /** if non-null, store next non-nested complete expressions in * *p_emit_expr **/ rp * p_emit_expr_; }; inline std::ostream & operator<<(std::ostream & os, const parserstatemachine & x) { x.print(os); return os; } } /*namespace scm*/ } /*namespace xo*/ /* end parserstatemachine.hpp */