/*************************************************************************** PProgram.hpp Author: Andreas Suter e-mail: andreas.suter@psi.ch Based on Joel de Guzman example on calc7, see https://github.com/boostorg/spirit ***************************************************************************/ /*************************************************************************** * Copyright (C) 2020 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _PPROGRAM_HPP_ #define _PPROGRAM_HPP_ #include #include #include #include "PAst.hpp" #include "PErrorHandler.hpp" #include #include #include #include #include namespace mupp { namespace prog { /////////////////////////////////////////////////////////////////////////// // Variable Handler /////////////////////////////////////////////////////////////////////////// class PVarHandler { public: PVarHandler() : fName("") {} void SetName(std::string name) { fName = name; } void SetValue(std::vector &dval) { fValue = dval; } void SetValue(double dval, unsigned idx); void SetError(std::vector &dval) { fError = dval; } void SetError(double dval, unsigned idx); std::string GetName() { return fName; } unsigned int GetSize() { return (fValue.size() == fError.size()) ? fValue.size() : 0; } std::vector GetValue() { return fValue; } double GetValue(unsigned int idx) { return (idx < fValue.size()) ? fValue[idx] : 0; } std::vector GetError() { return fError; } double GetError(unsigned int idx) { return (idx < fError.size()) ? fError[idx] : 0; } private: std::string fName; std::vector fValue; std::vector fError; }; /////////////////////////////////////////////////////////////////////////// // Program Semantic Analysis /////////////////////////////////////////////////////////////////////////// struct PProgram { typedef bool result_type; template PProgram(PErrorHandler& error_handler_) { using namespace boost::phoenix::arg_names; namespace phx = boost::phoenix; using boost::phoenix::function; error_handler = function(error_handler_)( "**ERROR** ", _2, phx::cref(error_handler_.iters)[_1]); } bool operator()(ast::nil) { BOOST_ASSERT(0); return false; } bool operator()(double x); bool operator()(ast::assignment const &x); bool operator()(ast::expression const &x); bool operator()(ast::function const &x); bool operator()(ast::operation const &x); bool operator()(ast::power const &x); bool operator()(ast::statement const &x); bool operator()(ast::statement_list const &x); bool operator()(ast::unary const &x); bool operator()(ast::variable const &x); bool operator()(ast::variable_declaration const &x); void add_predef_var_values(const std::string &name, std::vector &val, std::vector &err); void add_var(std::string const& name); bool find_var(std::string const &name); bool find_var(std::string const &name, unsigned int &idx); std::string pos_to_var(std::string const &name, bool &ok); std::vector getVars() { return fVariable; } private: std::vector fVariable; std::map fVarPos; boost::function< void(int tag, std::string const& what)> error_handler; }; /////////////////////////////////////////////////////////////////////////// // Program Evaluation /////////////////////////////////////////////////////////////////////////// struct PProgEval { typedef std::vector result_type; PProgEval(std::vector var) : fVariable(var) {} std::vector operator()(ast::nil); std::vector operator()(double x); std::vector operator()(ast::assignment const &x); std::vector operator()(ast::expression const &x); std::vector operator()(ast::function const &x); std::vector operator()(ast::operation const &x, std::vector lhs); std::vector operator()(ast::power const &x); std::vector operator()(ast::statement const &x); std::vector operator()(ast::statement_list const &x); std::vector operator()(ast::unary const &x); std::vector operator()(ast::variable const &x); std::vector operator()(ast::variable_declaration const &x); PVarHandler getVar(const std::string name, bool &ok); void print_result(); private: std::vector fVariable; unsigned int find_var(std::string const &name); }; }} #endif // _PPROGRAM_HPP_