160 lines
6.4 KiB
C++
160 lines
6.4 KiB
C++
/***************************************************************************
|
|
|
|
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 <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include "PAst.hpp"
|
|
#include "PErrorHandler.hpp"
|
|
|
|
#include <boost/function.hpp>
|
|
#include <boost/shared_ptr.hpp>
|
|
#include <boost/phoenix/core.hpp>
|
|
#include <boost/phoenix/function.hpp>
|
|
#include <boost/phoenix/operator.hpp>
|
|
|
|
namespace mupp { namespace prog {
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Variable Handler
|
|
///////////////////////////////////////////////////////////////////////////
|
|
class PVarHandler
|
|
{
|
|
public:
|
|
PVarHandler() : fName("") {}
|
|
|
|
void SetName(std::string name) { fName = name; }
|
|
void SetValue(std::vector<double> &dval) { fValue = dval; }
|
|
void SetValue(double dval, unsigned idx);
|
|
void SetError(std::vector<double> &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<double> GetValue() { return fValue; }
|
|
double GetValue(unsigned int idx) { return (idx < fValue.size()) ? fValue[idx] : 0; }
|
|
std::vector<double> GetError() { return fError; }
|
|
double GetError(unsigned int idx) { return (idx < fError.size()) ? fError[idx] : 0; }
|
|
|
|
private:
|
|
std::string fName;
|
|
std::vector<double> fValue;
|
|
std::vector<double> fError;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Program Semantic Analysis
|
|
///////////////////////////////////////////////////////////////////////////
|
|
struct PProgram
|
|
{
|
|
typedef bool result_type;
|
|
|
|
template <typename PErrorHandler>
|
|
PProgram(PErrorHandler& error_handler_)
|
|
{
|
|
using namespace boost::phoenix::arg_names;
|
|
namespace phx = boost::phoenix;
|
|
using boost::phoenix::function;
|
|
error_handler = function<PErrorHandler>(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<double> &val,
|
|
std::vector<double> &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<PVarHandler> getVars() { return fVariable; }
|
|
|
|
private:
|
|
std::vector<PVarHandler> fVariable;
|
|
std::map<int, std::string> fVarPos;
|
|
|
|
boost::function<
|
|
void(int tag, std::string const& what)>
|
|
error_handler;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Program Evaluation
|
|
///////////////////////////////////////////////////////////////////////////
|
|
struct PProgEval
|
|
{
|
|
typedef std::vector<double> result_type;
|
|
|
|
PProgEval(std::vector<PVarHandler> var) : fVariable(var) {}
|
|
|
|
std::vector<double> operator()(ast::nil);
|
|
std::vector<double> operator()(double x);
|
|
std::vector<double> operator()(ast::assignment const &x);
|
|
std::vector<double> operator()(ast::expression const &x);
|
|
std::vector<double> operator()(ast::function const &x);
|
|
std::vector<double> operator()(ast::operation const &x, std::vector<double> lhs);
|
|
std::vector<double> operator()(ast::power const &x);
|
|
std::vector<double> operator()(ast::statement const &x);
|
|
std::vector<double> operator()(ast::statement_list const &x);
|
|
std::vector<double> operator()(ast::unary const &x);
|
|
std::vector<double> operator()(ast::variable const &x);
|
|
std::vector<double> operator()(ast::variable_declaration const &x);
|
|
|
|
PVarHandler getVar(const std::string name, bool &ok);
|
|
void print_result();
|
|
|
|
private:
|
|
std::vector<PVarHandler> fVariable;
|
|
|
|
unsigned int find_var(std::string const &name);
|
|
};
|
|
}}
|
|
|
|
#endif // _PPROGRAM_HPP_
|