mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2025-06-21 00:32:01 +01:00
big cleaning and update: switching to C++11
This commit is contained in:
@ -30,31 +30,24 @@ using namespace Latan;
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
CompiledDoubleFunction::CompiledDoubleFunction(const unsigned nArg)
|
||||
: DoubleFunction(nArg)
|
||||
{
|
||||
interpreter_ = new MathInterpreter;
|
||||
context_ = new RunContext;
|
||||
}
|
||||
{}
|
||||
|
||||
CompiledDoubleFunction::CompiledDoubleFunction(const unsigned nArg,
|
||||
const string &code)
|
||||
: DoubleFunction(nArg)
|
||||
{
|
||||
interpreter_ = new MathInterpreter;
|
||||
context_ = new RunContext;
|
||||
setCode(code);
|
||||
}
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
CompiledDoubleFunction::~CompiledDoubleFunction(void)
|
||||
{
|
||||
delete interpreter_;
|
||||
delete context_;
|
||||
}
|
||||
{}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
void CompiledDoubleFunction::setCode(const string &code)
|
||||
{
|
||||
interpreter_->setCode(code);
|
||||
interpreter_.reset(new MathInterpreter(code));
|
||||
context_.reset(new RunContext);
|
||||
StdMath::addStdMathFunc(context_->fTable);
|
||||
}
|
||||
|
||||
@ -89,7 +82,7 @@ double CompiledDoubleFunction::evaluate(const vector<double> &arg) const
|
||||
}
|
||||
|
||||
// IO //////////////////////////////////////////////////////////////////////////
|
||||
ostream &Latan::operator<<(ostream &out, CompiledDoubleFunction &f)
|
||||
ostream & Latan::operator<<(ostream &out, CompiledDoubleFunction &f)
|
||||
{
|
||||
f.interpreter_->compile();
|
||||
out << *(f.interpreter_);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/Function.hpp>
|
||||
#include <latan/MathInterpreter.hpp>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
@ -46,13 +47,15 @@ public:
|
||||
// function call
|
||||
virtual double evaluate(const std::vector<double> &arg) const;
|
||||
// IO
|
||||
friend std::ostream &operator<<(std::ostream &out,
|
||||
CompiledDoubleFunction &f);
|
||||
friend std::ostream & operator<<(std::ostream &out,
|
||||
CompiledDoubleFunction &f);
|
||||
private:
|
||||
MathInterpreter* interpreter_;
|
||||
RunContext* context_;
|
||||
std::shared_ptr<MathInterpreter> interpreter_;
|
||||
std::shared_ptr<RunContext> context_;
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &out, CompiledDoubleFunction &f);
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // Latan_CompiledFunction_hpp_
|
||||
|
@ -61,21 +61,17 @@ unsigned int Function::getNArg(void) const
|
||||
/******************************************************************************
|
||||
* DoubleFunction implementation *
|
||||
******************************************************************************/
|
||||
DoubleFunction::DoubleFunction(const unsigned nArg, vecFunc *f)
|
||||
DoubleFunction::DoubleFunction(const unsigned nArg, vecFunc f)
|
||||
: Function(nArg)
|
||||
, buffer_(new vector<double>(nArg))
|
||||
, f_(f)
|
||||
{
|
||||
buffer_ = new vector<double>(nArg);
|
||||
}
|
||||
{}
|
||||
|
||||
DoubleFunction::~DoubleFunction(void)
|
||||
{
|
||||
delete buffer_;
|
||||
}
|
||||
{}
|
||||
|
||||
double DoubleFunction::evaluate(const std::vector<double> &arg) const
|
||||
{
|
||||
std::cout << "double()" << endl;
|
||||
return f_(arg);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#define Latan_Function_hpp_
|
||||
|
||||
#include <latan/Global.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
@ -48,18 +50,18 @@ private:
|
||||
class DoubleFunction: public Function
|
||||
{
|
||||
private:
|
||||
typedef double vecFunc(const std::vector<double> &);
|
||||
typedef std::function<double(const std::vector<double> &)> vecFunc;
|
||||
public:
|
||||
// constructor/destructor
|
||||
explicit DoubleFunction(const unsigned nArg, vecFunc *f = NULL);
|
||||
explicit DoubleFunction(const unsigned nArg, vecFunc f = nullptr);
|
||||
virtual ~DoubleFunction(void);
|
||||
// function call
|
||||
virtual double evaluate(const std::vector<double> &arg) const;
|
||||
double operator()(std::stack<double> &arg) const;
|
||||
double operator()(const double x0, ...) const;
|
||||
private:
|
||||
std::vector<double> *buffer_;
|
||||
vecFunc *f_;
|
||||
std::shared_ptr<std::vector<double>> buffer_;
|
||||
vecFunc f_;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
@ -77,13 +77,6 @@ std::string strFrom(const T x)
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
// key test in maps
|
||||
template <typename K, typename T>
|
||||
bool keyExists(const K &key, const std::map<K, T> &map)
|
||||
{
|
||||
return (map.find(key) != map.end());
|
||||
}
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#include <latan/Exceptions.hpp>
|
||||
|
25
latan/Io.cpp
25
latan/Io.cpp
@ -59,11 +59,9 @@ unsigned int File::getMode(void) const
|
||||
// internal functions //////////////////////////////////////////////////////////
|
||||
void File::deleteData(void)
|
||||
{
|
||||
IoDataTable::iterator i;
|
||||
|
||||
for (i=data_.begin();i!=data_.end();++i)
|
||||
for (auto &i : data_)
|
||||
{
|
||||
delete i->second;
|
||||
i.second.reset();
|
||||
}
|
||||
data_.clear();
|
||||
}
|
||||
@ -80,8 +78,8 @@ void File::checkWritability(void)
|
||||
* AsciiFile implementation *
|
||||
******************************************************************************/
|
||||
// AsciiParserState constructor ////////////////////////////////////////////////
|
||||
AsciiFile::AsciiParserState::AsciiParserState(istream* stream, string* name,
|
||||
IoDataTable* data)
|
||||
AsciiFile::AsciiParserState::AsciiParserState(istream *stream, string *name,
|
||||
IoDataTable *data)
|
||||
: ParserState<IoDataTable>(stream, name, data)
|
||||
{
|
||||
initScanner();
|
||||
@ -97,7 +95,7 @@ AsciiFile::AsciiParserState::~AsciiParserState(void)
|
||||
AsciiFile::AsciiFile(void)
|
||||
: File(), fileStream_()
|
||||
, isParsed_(false)
|
||||
, state_(NULL)
|
||||
, state_(nullptr)
|
||||
{}
|
||||
|
||||
AsciiFile::AsciiFile(const string &name, const unsigned int mode)
|
||||
@ -140,8 +138,7 @@ bool AsciiFile::isOpen() const
|
||||
// IO //////////////////////////////////////////////////////////////////////////
|
||||
void AsciiFile::close(void)
|
||||
{
|
||||
delete state_;
|
||||
state_ = NULL;
|
||||
state_.reset(nullptr);
|
||||
if (isOpen())
|
||||
{
|
||||
fileStream_.close();
|
||||
@ -160,7 +157,7 @@ void AsciiFile::open(const string &name, const unsigned int mode)
|
||||
}
|
||||
else
|
||||
{
|
||||
ios_base::openmode stdMode = 0;
|
||||
ios_base::openmode stdMode = static_cast<ios_base::openmode>(0);
|
||||
|
||||
if (mode & Mode::write)
|
||||
{
|
||||
@ -180,11 +177,11 @@ void AsciiFile::open(const string &name, const unsigned int mode)
|
||||
fileStream_.open(name_.c_str(), stdMode);
|
||||
if (mode_ & Mode::read)
|
||||
{
|
||||
state_ = new AsciiParserState(&fileStream_, &name_, &data_);
|
||||
state_.reset(new AsciiParserState(&fileStream_, &name_, &data_));
|
||||
}
|
||||
else
|
||||
{
|
||||
state_ = NULL;
|
||||
state_.reset(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,11 +211,11 @@ void AsciiFile::load(const string &name __dumb)
|
||||
// parser //////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Bison/Flex parser declaration
|
||||
int _ioAscii_parse(AsciiFile::AsciiParserState* state);
|
||||
int _ioAscii_parse(AsciiFile::AsciiParserState *state);
|
||||
|
||||
void AsciiFile::parse()
|
||||
{
|
||||
fileStream_.seekg(0);
|
||||
_ioAscii_parse(state_);
|
||||
_ioAscii_parse(state_.get());
|
||||
isParsed_ = true;
|
||||
}
|
||||
|
31
latan/Io.hpp
31
latan/Io.hpp
@ -21,10 +21,11 @@
|
||||
#define Latan_Io_hpp_
|
||||
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/IoObject.hpp>
|
||||
#include <latan/Mat.hpp>
|
||||
@ -37,7 +38,7 @@ BEGIN_NAMESPACE
|
||||
/******************************************************************************
|
||||
* Generic datafile class *
|
||||
******************************************************************************/
|
||||
typedef std::map<std::string, IoObject *> IoDataTable;
|
||||
typedef std::unordered_map<std::string, std::unique_ptr<IoObject>> IoDataTable;
|
||||
|
||||
class File
|
||||
{
|
||||
@ -98,13 +99,11 @@ const IoT& File::read(const std::string &name)
|
||||
template <typename IoT>
|
||||
const IoT& File::getData(const std::string &name) const
|
||||
{
|
||||
IoDataTable::const_iterator i = data_.find(name);
|
||||
|
||||
if (i != data_.end())
|
||||
try
|
||||
{
|
||||
return dynamic_cast<const IoT&>(*(i->second));
|
||||
return dynamic_cast<const IoT &>(*(data_.at(name)));
|
||||
}
|
||||
else
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
LATAN_ERROR(Definition, "no data with name '" + name + "'");
|
||||
}
|
||||
@ -120,14 +119,16 @@ public:
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
explicit AsciiParserState(std::istream *stream, std::string *name,\
|
||||
explicit AsciiParserState(std::istream *stream, std::string *name,
|
||||
IoDataTable *data);
|
||||
// destructor
|
||||
virtual ~AsciiParserState(void);
|
||||
// public members
|
||||
std::stack<DMat> dMatBuf;
|
||||
std::stack<double> doubleBuf;
|
||||
std::stack<int> intBuf;
|
||||
// parsing buffers
|
||||
DMat dMatBuf;
|
||||
RandGen::State stateBuf;
|
||||
std::stack<DMat> dMatStack;
|
||||
std::stack<double> doubleStack;
|
||||
std::stack<int> intStack;
|
||||
private:
|
||||
// allocation/deallocation functions defined in IoAsciiLexer.lpp
|
||||
virtual void initScanner(void);
|
||||
@ -153,9 +154,9 @@ private:
|
||||
// parser
|
||||
void parse(void);
|
||||
private:
|
||||
std::fstream fileStream_;
|
||||
bool isParsed_;
|
||||
AsciiParserState* state_;
|
||||
std::fstream fileStream_;
|
||||
bool isParsed_;
|
||||
std::unique_ptr<AsciiParserState> state_;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
%{
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/IO.hpp>
|
||||
@ -29,6 +31,8 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
#define STORE(ref) (*state->data)[(ref).first] = std::move((ref).second)
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
@ -42,20 +46,19 @@
|
||||
|
||||
%union
|
||||
{
|
||||
int val_int;
|
||||
double val_double;
|
||||
char val_char;
|
||||
char val_str[256];
|
||||
int val_int;
|
||||
double val_double;
|
||||
char val_char;
|
||||
char val_str[256];
|
||||
}
|
||||
|
||||
%token CLOSE
|
||||
%token <val_char> ERR
|
||||
%token <val_double> FLOAT
|
||||
%token <val_int> INT
|
||||
%token <val_str> ID
|
||||
%token MAT
|
||||
%token RG_STATE
|
||||
%token OPEN
|
||||
%token OPEN CLOSE MAT RG_STATE
|
||||
|
||||
%type <val_str> mat rg_state
|
||||
|
||||
%{
|
||||
int _ioAscii_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
|
||||
@ -82,24 +85,25 @@ datas:
|
||||
|
||||
data:
|
||||
mat
|
||||
{(*state->data)[$1].reset(new DMat(state->dMatBuf));}
|
||||
| rg_state
|
||||
{(*state->data)[$1].reset(new RandGen::State(state->stateBuf));}
|
||||
;
|
||||
|
||||
mat:
|
||||
OPEN MAT ID INT floats CLOSE MAT
|
||||
{
|
||||
const int nRow = state->doubleBuf.size()/$INT, nCol = $INT;
|
||||
(*state->data)[$ID] = new DMat(nRow, nCol);
|
||||
DMat &m = static_cast<DMat &>(*((*state->data)[$ID]));
|
||||
const int nRow = state->doubleStack.size()/$INT, nCol = $INT;
|
||||
int r, i, j;
|
||||
|
||||
r = 0;
|
||||
while (!state->doubleBuf.empty())
|
||||
state->dMatBuf.resize(nRow, nCol);
|
||||
while (!state->doubleStack.empty())
|
||||
{
|
||||
j = r % nCol;
|
||||
i = (r - j)/nCol;
|
||||
m(i, j) = state->doubleBuf.top();
|
||||
state->doubleBuf.pop();
|
||||
state->dMatBuf(i, j) = state->doubleStack.top();
|
||||
state->doubleStack.pop();
|
||||
++r;
|
||||
}
|
||||
if (r != nRow*nCol)
|
||||
@ -107,22 +111,19 @@ mat:
|
||||
LATAN_ERROR(Range, "matrix '" + *state->streamName + ":" + $ID +
|
||||
"' has a wrong size");
|
||||
}
|
||||
strcpy($$, $ID);
|
||||
}
|
||||
;
|
||||
|
||||
rg_state:
|
||||
OPEN RG_STATE ID ints CLOSE RG_STATE
|
||||
{
|
||||
(*state->data)[$ID] = new RandGen::State;
|
||||
RandGen::State &rgState =
|
||||
static_cast<RandGen::State &>(*((*state->data)[$ID]));
|
||||
|
||||
for (int i = 0; i < RLXG_STATE_SIZE; ++i)
|
||||
{
|
||||
if (!state->intBuf.empty())
|
||||
if (!state->intStack.empty())
|
||||
{
|
||||
rgState[i] = state->intBuf.top();
|
||||
state->intBuf.pop();
|
||||
state->stateBuf[i] = state->intStack.top();
|
||||
state->intStack.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -130,22 +131,23 @@ rg_state:
|
||||
*state->streamName + ":" + $ID + "' is too short");
|
||||
}
|
||||
}
|
||||
if (!state->intBuf.empty())
|
||||
if (!state->intStack.empty())
|
||||
{
|
||||
LATAN_ERROR(Range, "random generator state '" +
|
||||
*state->streamName + ":" + $ID + "' is too long");
|
||||
}
|
||||
strcpy($$, $ID);
|
||||
}
|
||||
;
|
||||
|
||||
floats:
|
||||
FLOAT floats {state->doubleBuf.push($1);}
|
||||
| INT floats {state->doubleBuf.push(static_cast<double>($1));}
|
||||
| FLOAT {state->doubleBuf.push($1);}
|
||||
| INT {state->doubleBuf.push(static_cast<double>($1));}
|
||||
FLOAT floats {state->doubleStack.push($1);}
|
||||
| INT floats {state->doubleStack.push(static_cast<double>($1));}
|
||||
| FLOAT {state->doubleStack.push($1);}
|
||||
| INT {state->doubleStack.push(static_cast<double>($1));}
|
||||
;
|
||||
|
||||
ints:
|
||||
INT ints {state->intBuf.push($1);}
|
||||
| INT {state->intBuf.push($1);}
|
||||
INT ints {state->intStack.push($1);}
|
||||
| INT {state->intStack.push($1);}
|
||||
;
|
||||
|
@ -28,20 +28,16 @@ BEGIN_NAMESPACE
|
||||
class IoObject
|
||||
{
|
||||
public:
|
||||
class IoType
|
||||
enum class IoType
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
noType = 0,
|
||||
dMat = 1,
|
||||
dMatSample = 2,
|
||||
rgState = 3
|
||||
};
|
||||
noType = 0,
|
||||
dMat = 1,
|
||||
dMatSample = 2,
|
||||
rgState = 3
|
||||
};
|
||||
public:
|
||||
virtual ~IoObject(void) {};
|
||||
virtual unsigned int getType(void) const = 0;
|
||||
virtual IoType getType(void) const = 0;
|
||||
};
|
||||
|
||||
END_NAMESPACE
|
||||
|
@ -35,7 +35,7 @@ DMat::DMat(const unsigned int nRow, const unsigned int nCol)
|
||||
: Base(nRow, nCol)
|
||||
{}
|
||||
|
||||
unsigned int DMat::getType(void) const
|
||||
IoObject::IoType DMat::getType(void) const
|
||||
{
|
||||
return IoType::dMat;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
template <typename Derived>
|
||||
DMat(const Eigen::EigenBase<Derived> &m);
|
||||
// IO
|
||||
virtual unsigned int getType(void) const;
|
||||
virtual IoType getType(void) const;
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
|
@ -1,504 +0,0 @@
|
||||
#include <latan/MathCompiler.hpp>
|
||||
#include <latan/includes.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
// Math Bison/Flex parser declaration
|
||||
int _math_parse(MathCompiler::MathParserState* state);
|
||||
|
||||
/******************************************************************************
|
||||
* MathNode implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
MathNode::MathNode(const string &name, const unsigned int type)
|
||||
: name_(name)
|
||||
, type_(type)
|
||||
, parent_(NULL)
|
||||
{}
|
||||
|
||||
MathNode::MathNode(const std::string &name, const unsigned int type,\
|
||||
const unsigned int nArg, ...)
|
||||
: name_(name)
|
||||
, type_(type)
|
||||
, arg_(nArg)
|
||||
, parent_(NULL)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, nArg);
|
||||
for (unsigned int i = 0; i < nArg; ++i)
|
||||
{
|
||||
arg_[i] = va_arg(va, MathNode *);
|
||||
arg_[i]->parent_ = this;
|
||||
}
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
MathNode::~MathNode(void)
|
||||
{
|
||||
vector<MathNode *>::iterator i;
|
||||
|
||||
for (i = arg_.begin(); i != arg_.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
const string &MathNode::getName(void) const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
unsigned int MathNode::getType(void) const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
unsigned int MathNode::getNArg(void) const
|
||||
{
|
||||
return static_cast<unsigned int>(arg_.size());
|
||||
}
|
||||
|
||||
const MathNode * MathNode::getParent(void) const
|
||||
{
|
||||
return parent_;
|
||||
}
|
||||
|
||||
unsigned int MathNode::getLevel(void) const
|
||||
{
|
||||
if (getParent())
|
||||
{
|
||||
return getParent()->getLevel() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MathNode::setName(const std::string &name)
|
||||
{
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
void MathNode::pushArg(MathNode *node)
|
||||
{
|
||||
arg_.push_back(node);
|
||||
}
|
||||
|
||||
// operators ///////////////////////////////////////////////////////////////////
|
||||
const MathNode &MathNode::operator[](const unsigned int i) const
|
||||
{
|
||||
return *arg_[i];
|
||||
}
|
||||
|
||||
ostream &Latan::operator<<(ostream &out, const MathNode &n)
|
||||
{
|
||||
unsigned int level = n.getLevel();
|
||||
|
||||
for (unsigned int i = 0; i <= level; ++i)
|
||||
{
|
||||
if (i == level)
|
||||
{
|
||||
out << "_";
|
||||
}
|
||||
else if (i == level - 1)
|
||||
{
|
||||
out << "|";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
out << " " << n.getName() << " (type " << n.getType() << ")" << endl;
|
||||
for (unsigned int i = 0; i < n.getNArg(); ++i)
|
||||
{
|
||||
out << n[i];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Instruction set *
|
||||
******************************************************************************/
|
||||
#define CODE_WIDTH 6
|
||||
#define CODE_MOD setw(CODE_WIDTH) << left
|
||||
|
||||
Instruction::~Instruction(void)
|
||||
{}
|
||||
|
||||
ostream &Latan::operator<<(ostream& out, const Instruction& ins)
|
||||
{
|
||||
ins.print(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Push::Push(const double val)
|
||||
: type_(ArgType::Constant)
|
||||
, val_(val)
|
||||
, name_("")
|
||||
{}
|
||||
|
||||
Push::Push(const string &name)
|
||||
: type_(ArgType::Variable)
|
||||
, val_(0.0)
|
||||
, name_(name)
|
||||
{}
|
||||
|
||||
void Push::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable __dumb)
|
||||
{
|
||||
if (type_ == ArgType::Constant)
|
||||
{
|
||||
dStack.push(val_);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keyExists(name_, vTable))
|
||||
{
|
||||
dStack.push(vTable[name_]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LATAN_ERROR(Range, "unknown variable '" + name_ + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Push::print(std::ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "push";
|
||||
if (type_ == ArgType::Constant)
|
||||
{
|
||||
out << CODE_MOD << val_;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << CODE_MOD << name_;
|
||||
}
|
||||
}
|
||||
|
||||
Pop::Pop(const string &name)
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
void Pop::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable __dumb)
|
||||
{
|
||||
if (!name_.empty())
|
||||
{
|
||||
vTable[name_] = dStack.top();
|
||||
}
|
||||
dStack.pop();
|
||||
}
|
||||
|
||||
void Pop::print(std::ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "pop" << CODE_MOD << name_;
|
||||
}
|
||||
|
||||
Store::Store(const string &name)
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
void Store::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable __dumb)
|
||||
{
|
||||
if (!name_.empty())
|
||||
{
|
||||
vTable[name_] = dStack.top();
|
||||
}
|
||||
}
|
||||
|
||||
void Store::print(std::ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "store" << CODE_MOD << name_;
|
||||
}
|
||||
|
||||
Call::Call(const string &name)
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
void Call::operator()(std::stack<double> &dStack, VarTable &vTable __dumb,
|
||||
FunctionTable &fTable)
|
||||
{
|
||||
if (keyExists(name_, fTable))
|
||||
{
|
||||
dStack.push((*fTable[name_])(dStack));
|
||||
}
|
||||
else
|
||||
{
|
||||
LATAN_ERROR(Range, "unknown function '" + name_ + "'");
|
||||
}
|
||||
}
|
||||
|
||||
void Call::print(std::ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "call" << CODE_MOD << name_;
|
||||
}
|
||||
|
||||
#define DEF_OP(name, nArg, exp, insName)\
|
||||
void name::operator()(stack<double> &dStack, VarTable &vTable __dumb,\
|
||||
FunctionTable &fTable __dumb)\
|
||||
{\
|
||||
double x[nArg];\
|
||||
for (int i = 0; i < nArg; ++i)\
|
||||
{\
|
||||
x[nArg-1-i] = dStack.top();\
|
||||
dStack.pop();\
|
||||
}\
|
||||
dStack.push(exp);\
|
||||
}\
|
||||
void name::print(std::ostream &out) const\
|
||||
{\
|
||||
out << CODE_MOD << insName;\
|
||||
}
|
||||
|
||||
DEF_OP(Neg, 1, -x[0], "neg")
|
||||
DEF_OP(Add, 2, x[0] + x[1], "add")
|
||||
DEF_OP(Sub, 2, x[0] - x[1], "sub")
|
||||
DEF_OP(Mul, 2, x[0]*x[1], "mul")
|
||||
DEF_OP(Div, 2, x[0]/x[1], "div")
|
||||
DEF_OP(Pow, 2, pow(x[0],x[1]), "pow")
|
||||
|
||||
ostream &Latan::operator<<(ostream &out, const VirtualProgram &prog)
|
||||
{
|
||||
for (unsigned int i = 0; i < prog.size(); ++i)
|
||||
{
|
||||
out << *(prog[i]) << endl;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* MathCompiler implementation *
|
||||
******************************************************************************/
|
||||
// MathParserState constructor /////////////////////////////////////////////////
|
||||
MathCompiler::MathParserState::MathParserState(istream *stream, string *name,
|
||||
MathNode **data)
|
||||
: ParserState<MathNode *>(stream, name, data)
|
||||
{
|
||||
initScanner();
|
||||
}
|
||||
|
||||
// MathParserState destructor //////////////////////////////////////////////////
|
||||
MathCompiler::MathParserState::~MathParserState(void)
|
||||
{
|
||||
destroyScanner();
|
||||
}
|
||||
|
||||
// constructors ////////////////////////////////////////////////////////////////
|
||||
MathCompiler::MathCompiler(void)
|
||||
: code_(NULL)
|
||||
, codeName_("<no_code>")
|
||||
, state_(NULL)
|
||||
, root_(NULL)
|
||||
, gotReturn_(false)
|
||||
, out_()
|
||||
, status_(Status::none)
|
||||
{}
|
||||
|
||||
MathCompiler::MathCompiler(const std::string &code)
|
||||
: root_(NULL)
|
||||
, gotReturn_(false)
|
||||
, out_()
|
||||
{
|
||||
init(code);
|
||||
}
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
MathCompiler::~MathCompiler(void)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
const MathNode * MathCompiler::getAST(void) const
|
||||
{
|
||||
if (root_)
|
||||
{
|
||||
return root_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// public methods //////////////////////////////////////////////////////////////
|
||||
void MathCompiler::init(const std::string &code)
|
||||
{
|
||||
if (status_)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
code_ = new stringstream(code);
|
||||
codeName_ = "<string>";
|
||||
state_ = new MathParserState(code_, &codeName_, &root_);
|
||||
status_ = Status::initialised;
|
||||
}
|
||||
|
||||
const VirtualProgram& MathCompiler::operator()(void)
|
||||
{
|
||||
if (!(status_ & Status::parsed))
|
||||
{
|
||||
parse();
|
||||
status_ |= Status::parsed;
|
||||
status_ -= status_ & Status::compiled;
|
||||
}
|
||||
if (!(status_ & Status::compiled))
|
||||
{
|
||||
if (root_)
|
||||
{
|
||||
gotReturn_ = false;
|
||||
compile(*root_);
|
||||
if (!gotReturn_)
|
||||
{
|
||||
LATAN_ERROR(Syntax, "expected 'return' in program '" +
|
||||
codeName_ + "'");
|
||||
}
|
||||
}
|
||||
status_ |= Status::compiled;
|
||||
}
|
||||
|
||||
return out_;
|
||||
}
|
||||
|
||||
// private methods /////////////////////////////////////////////////////////////
|
||||
void MathCompiler::parse(void)
|
||||
{
|
||||
_math_parse(state_);
|
||||
}
|
||||
|
||||
#define IFNODE(name, nArg) if ((n.getName() == (name))&&(n.getNArg() == nArg))
|
||||
#define ELIFNODE(name, nArg) else IFNODE(name, nArg)
|
||||
#define ELSE else
|
||||
void MathCompiler::compile(const MathNode& n)
|
||||
{
|
||||
if (!gotReturn_)
|
||||
{
|
||||
switch (n.getType())
|
||||
{
|
||||
case MathNode::Type::cst:
|
||||
out_.push_back(new Push(strTo<double>(n.getName())));
|
||||
break;
|
||||
case MathNode::Type::var:
|
||||
out_.push_back(new Push(n.getName()));
|
||||
break;
|
||||
case MathNode::Type::op:
|
||||
// semicolon
|
||||
if (n.getName() == ";")
|
||||
{
|
||||
// compile relevant statements
|
||||
for (unsigned int i = 0; i < n.getNArg(); ++i)
|
||||
{
|
||||
bool isAssign =
|
||||
((n[i].getType() == MathNode::Type::op)&&
|
||||
(n[i].getName() == "="));
|
||||
bool isSemiColumn =
|
||||
((n[i].getType() == MathNode::Type::op)&&
|
||||
(n[i].getName() == ";"));
|
||||
bool isKeyword =
|
||||
(n[i].getType() == MathNode::Type::keyw);
|
||||
|
||||
if (isAssign||isSemiColumn||isKeyword)
|
||||
{
|
||||
compile(n[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// assignment
|
||||
else if (n.getName() == "=")
|
||||
{
|
||||
// variable assignement
|
||||
if (n[0].getType() == MathNode::Type::var)
|
||||
{
|
||||
bool hasSemicolonParent = ((n.getParent() != NULL) &&
|
||||
(n.getParent()->getType()
|
||||
== MathNode::Type::op)&&
|
||||
(n.getParent()->getName()
|
||||
== ";"));
|
||||
// compile the RHS
|
||||
compile(n[1]);
|
||||
// pop instruction if at the end of a statement
|
||||
if (hasSemicolonParent)
|
||||
{
|
||||
out_.push_back(new Pop(n[0].getName()));
|
||||
}
|
||||
// store instruction else
|
||||
else
|
||||
{
|
||||
out_.push_back(new Store(n[0].getName()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LATAN_ERROR(Compilation, "invalid LHS for '='");
|
||||
}
|
||||
}
|
||||
// arithmetic operators
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < n.getNArg(); ++i)
|
||||
{
|
||||
compile(n[i]);
|
||||
}
|
||||
IFNODE("-", 1) out_.push_back(new Neg);
|
||||
ELIFNODE("+", 2) out_.push_back(new Add);
|
||||
ELIFNODE("-", 2) out_.push_back(new Sub);
|
||||
ELIFNODE("*", 2) out_.push_back(new Mul);
|
||||
ELIFNODE("/", 2) out_.push_back(new Div);
|
||||
ELIFNODE("^", 2) out_.push_back(new Pow);
|
||||
ELSE LATAN_ERROR(Compilation, "unknown operator '"
|
||||
+ n.getName() + "'");
|
||||
}
|
||||
break;
|
||||
case MathNode::Type::keyw:
|
||||
if (n.getName() == "return")
|
||||
{
|
||||
compile(n[0]);
|
||||
gotReturn_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LATAN_ERROR(Compilation, "unknown keyword '" + n.getName()
|
||||
+ "'");
|
||||
}
|
||||
break;
|
||||
case MathNode::Type::func:
|
||||
for (unsigned int i = 0; i < n.getNArg(); ++i)
|
||||
{
|
||||
compile(n[i]);
|
||||
}
|
||||
out_.push_back(new Call(n.getName()));
|
||||
break;
|
||||
default:
|
||||
LATAN_ERROR(Compilation,
|
||||
"unknown node type (node named '" + n.getName()
|
||||
+ "')");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MathCompiler::reset(void)
|
||||
{
|
||||
delete code_;
|
||||
codeName_ = "<no_code>";
|
||||
delete state_;
|
||||
delete root_;
|
||||
for (VirtualProgram::iterator i = out_.begin(); i != out_.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
out_.clear();
|
||||
status_ = 0;
|
||||
}
|
||||
|
@ -1,241 +0,0 @@
|
||||
#ifndef LATAN_MATHCOMPILER_HPP_
|
||||
#define LATAN_MATHCOMPILER_HPP_
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <latan/Function.hpp>
|
||||
#include <latan/Global.hpp>
|
||||
#include <latan/ParserState.hpp>
|
||||
|
||||
#define MAXIDLENGTH 256
|
||||
|
||||
LATAN_BEGIN_CPPDECL
|
||||
|
||||
/******************************************************************************
|
||||
* Parser classes *
|
||||
******************************************************************************/
|
||||
class MathNode
|
||||
{
|
||||
public:
|
||||
class Type
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
undef = -1,
|
||||
cst = 0,
|
||||
op = 1,
|
||||
var = 2,
|
||||
keyw = 3,
|
||||
func = 4
|
||||
};
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
MathNode(const std::string &name, const unsigned int type);
|
||||
MathNode(const std::string &name, const unsigned int type,
|
||||
const unsigned int nArg, ...);
|
||||
// destructor
|
||||
virtual ~MathNode();
|
||||
// access
|
||||
const std::string& getName(void) const;
|
||||
unsigned int getType(void) const;
|
||||
unsigned int getNArg(void) const;
|
||||
const MathNode * getParent(void) const;
|
||||
unsigned int getLevel(void) const;
|
||||
void setName(const std::string &name);
|
||||
void pushArg(MathNode *node);
|
||||
// operator
|
||||
const MathNode &operator[](const unsigned int i) const;
|
||||
private:
|
||||
// IO
|
||||
std::ostream &print(std::ostream &out) const;
|
||||
private:
|
||||
std::string name_;
|
||||
unsigned int type_;
|
||||
std::vector<MathNode *> arg_;
|
||||
const MathNode * parent_;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const MathNode &n);
|
||||
|
||||
/******************************************************************************
|
||||
* Virtual machine code classes *
|
||||
******************************************************************************/
|
||||
typedef std::map<std::string, double> VarTable;
|
||||
typedef std::map<std::string, DoubleFunction *> FunctionTable;
|
||||
|
||||
// Abstract base
|
||||
class Instruction
|
||||
{
|
||||
public:
|
||||
virtual ~Instruction();
|
||||
// instruction execution
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable) = 0;
|
||||
friend std::ostream& operator<<(std::ostream &out, const Instruction &ins);
|
||||
private:
|
||||
virtual void print(std::ostream &out) const = 0;
|
||||
};
|
||||
|
||||
// Push
|
||||
class Push: public Instruction
|
||||
{
|
||||
private:
|
||||
class ArgType
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Constant = 0,
|
||||
Variable = 1
|
||||
};
|
||||
};
|
||||
public:
|
||||
//constructors
|
||||
explicit Push(const double val);
|
||||
explicit Push(const std::string &name);
|
||||
// instruction execution
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable);
|
||||
private:
|
||||
virtual void print(std::ostream& out) const;
|
||||
private:
|
||||
unsigned int type_;
|
||||
double val_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
// Pop
|
||||
class Pop: public Instruction
|
||||
{
|
||||
public:
|
||||
//constructor
|
||||
explicit Pop(const std::string &name);
|
||||
// instruction execution
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable);
|
||||
private:
|
||||
virtual void print(std::ostream& out) const;
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
// Store
|
||||
class Store: public Instruction
|
||||
{
|
||||
public:
|
||||
//constructor
|
||||
explicit Store(const std::string &name);
|
||||
// instruction execution
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable);
|
||||
private:
|
||||
virtual void print(std::ostream& out) const;
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
// Call function
|
||||
class Call: public Instruction
|
||||
{
|
||||
public:
|
||||
//constructor
|
||||
explicit Call(const std::string &name);
|
||||
// instruction execution
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||
FunctionTable &fTable);
|
||||
private:
|
||||
virtual void print(std::ostream& out) const;
|
||||
private:
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
// Floating point operations
|
||||
#define DECL_OP(name)\
|
||||
class name: public Instruction\
|
||||
{\
|
||||
public:\
|
||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,\
|
||||
FunctionTable &fTable);\
|
||||
private:\
|
||||
virtual void print(std::ostream &out) const;\
|
||||
}
|
||||
|
||||
DECL_OP(Neg);
|
||||
DECL_OP(Add);
|
||||
DECL_OP(Sub);
|
||||
DECL_OP(Mul);
|
||||
DECL_OP(Div);
|
||||
DECL_OP(Pow);
|
||||
|
||||
// Virtual program type
|
||||
typedef std::vector<Instruction *> VirtualProgram;
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const VirtualProgram &program);
|
||||
|
||||
/******************************************************************************
|
||||
* Compiler class *
|
||||
******************************************************************************/
|
||||
class MathCompiler
|
||||
{
|
||||
public:
|
||||
// parser state
|
||||
class MathParserState: public ParserState<MathNode *>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
explicit MathParserState(std::istream *stream, std::string *name,
|
||||
MathNode **data);
|
||||
// destructor
|
||||
virtual ~MathParserState(void);
|
||||
private:
|
||||
// allocation/deallocation functions defined in MathLexer.lpp
|
||||
virtual void initScanner(void);
|
||||
virtual void destroyScanner(void);
|
||||
};
|
||||
private:
|
||||
// status flags
|
||||
class Status
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
none = 0,
|
||||
initialised = 1 << 0,
|
||||
parsed = 1 << 1,
|
||||
compiled = 1 << 2
|
||||
};
|
||||
};
|
||||
public:
|
||||
// constructors
|
||||
MathCompiler(void);
|
||||
MathCompiler(const std::string &code);
|
||||
// destructor
|
||||
~MathCompiler(void);
|
||||
// access
|
||||
const MathNode * getAST(void) const;
|
||||
// initialization
|
||||
void init(const std::string &code);
|
||||
// compilation
|
||||
const VirtualProgram &operator()(void);
|
||||
private:
|
||||
void parse(void);
|
||||
void compile(const MathNode &node);
|
||||
void reset(void);
|
||||
private:
|
||||
std::istream *code_;
|
||||
std::string codeName_;
|
||||
MathParserState *state_;
|
||||
MathNode *root_;
|
||||
bool gotReturn_;
|
||||
VirtualProgram out_;
|
||||
unsigned int status_;
|
||||
};
|
||||
|
||||
LATAN_END_CPPDECL
|
||||
|
||||
#endif
|
@ -26,26 +26,26 @@ using namespace Latan;
|
||||
/******************************************************************************
|
||||
* MathNode implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
MathNode::MathNode(const string &name, const unsigned int type)
|
||||
// constructors ////////////////////////////////////////////////////////////////
|
||||
MathNode::MathNode(const string &name, const Type type)
|
||||
: name_(name)
|
||||
, type_(type)
|
||||
, parent_(NULL)
|
||||
, parent_(nullptr)
|
||||
{}
|
||||
|
||||
MathNode::MathNode(const std::string &name, const unsigned int type,\
|
||||
MathNode::MathNode(const std::string &name, const Type type,\
|
||||
const unsigned int nArg, ...)
|
||||
: name_(name)
|
||||
, type_(type)
|
||||
, arg_(nArg)
|
||||
, parent_(NULL)
|
||||
, parent_(nullptr)
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start(va, nArg);
|
||||
for (unsigned int i = 0; i < nArg; ++i)
|
||||
{
|
||||
arg_[i] = va_arg(va, MathNode *);
|
||||
arg_[i].reset(va_arg(va, MathNode *));
|
||||
arg_[i]->parent_ = this;
|
||||
}
|
||||
va_end(va);
|
||||
@ -53,14 +53,7 @@ MathNode::MathNode(const std::string &name, const unsigned int type,\
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
MathNode::~MathNode(void)
|
||||
{
|
||||
vector<MathNode *>::iterator i;
|
||||
|
||||
for (i = arg_.begin(); i != arg_.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
const string &MathNode::getName(void) const
|
||||
@ -68,7 +61,7 @@ const string &MathNode::getName(void) const
|
||||
return name_;
|
||||
}
|
||||
|
||||
unsigned int MathNode::getType(void) const
|
||||
MathNode::Type MathNode::getType(void) const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
@ -102,7 +95,7 @@ void MathNode::setName(const std::string &name)
|
||||
|
||||
void MathNode::pushArg(MathNode *node)
|
||||
{
|
||||
arg_.push_back(node);
|
||||
arg_.push_back(unique_ptr<MathNode>(node));
|
||||
}
|
||||
|
||||
// operators ///////////////////////////////////////////////////////////////////
|
||||
@ -130,7 +123,8 @@ ostream &Latan::operator<<(ostream &out, const MathNode &n)
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
out << " " << n.getName() << " (type " << n.getType() << ")" << endl;
|
||||
out << " " << n.getName() << " (type " << static_cast<int>(n.getType())
|
||||
<< ")" << endl;
|
||||
for (unsigned int i = 0; i < n.getNArg(); ++i)
|
||||
{
|
||||
out << n[i];
|
||||
@ -175,11 +169,11 @@ void Push::operator()(RunContext &context) const
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keyExists(name_, context.vTable))
|
||||
try
|
||||
{
|
||||
context.dStack.push(context.vTable[name_]);
|
||||
context.dStack.push(context.vTable.at(name_));
|
||||
}
|
||||
else
|
||||
catch (out_of_range)
|
||||
{
|
||||
LATAN_ERROR(Range, "unknown variable '" + name_ + "'");
|
||||
}
|
||||
@ -187,7 +181,7 @@ void Push::operator()(RunContext &context) const
|
||||
context.insIndex++;
|
||||
}
|
||||
|
||||
void Push::print(std::ostream &out) const
|
||||
void Push::print(ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "push";
|
||||
if (type_ == ArgType::Constant)
|
||||
@ -214,7 +208,7 @@ void Pop::operator()(RunContext &context) const
|
||||
context.insIndex++;
|
||||
}
|
||||
|
||||
void Pop::print(std::ostream &out) const
|
||||
void Pop::print(ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "pop" << CODE_MOD << name_;
|
||||
}
|
||||
@ -232,7 +226,7 @@ void Store::operator()(RunContext &context) const
|
||||
context.insIndex++;
|
||||
}
|
||||
|
||||
void Store::print(std::ostream &out) const
|
||||
void Store::print(ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "store" << CODE_MOD << name_;
|
||||
}
|
||||
@ -243,18 +237,18 @@ Call::Call(const string &name)
|
||||
|
||||
void Call::operator()(RunContext &context) const
|
||||
{
|
||||
if (keyExists(name_, context.fTable))
|
||||
try
|
||||
{
|
||||
context.dStack.push((*context.fTable[name_])(context.dStack));
|
||||
context.dStack.push((*context.fTable.at(name_))(context.dStack));
|
||||
}
|
||||
else
|
||||
catch (out_of_range)
|
||||
{
|
||||
LATAN_ERROR(Range, "unknown function '" + name_ + "'");
|
||||
}
|
||||
context.insIndex++;
|
||||
}
|
||||
|
||||
void Call::print(std::ostream &out) const
|
||||
void Call::print(ostream &out) const
|
||||
{
|
||||
out << CODE_MOD << "call" << CODE_MOD << name_;
|
||||
}
|
||||
@ -271,7 +265,7 @@ void name::operator()(RunContext &context) const\
|
||||
context.dStack.push(exp);\
|
||||
context.insIndex++;\
|
||||
}\
|
||||
void name::print(std::ostream &out) const\
|
||||
void name::print(ostream &out) const\
|
||||
{\
|
||||
out << CODE_MOD << insName;\
|
||||
}
|
||||
@ -287,9 +281,9 @@ DEF_OP(Pow, 2, pow(x[0],x[1]), "pow")
|
||||
* MathInterpreter implementation *
|
||||
******************************************************************************/
|
||||
// MathParserState constructor /////////////////////////////////////////////////
|
||||
MathInterpreter::MathParserState::MathParserState(istream *stream, string *name,
|
||||
MathNode **data)
|
||||
: ParserState<MathNode *>(stream, name, data)
|
||||
MathInterpreter::MathParserState::MathParserState
|
||||
(istream *stream, string *name, std::unique_ptr<MathNode> *data)
|
||||
: ParserState<std::unique_ptr<MathNode>>(stream, name, data)
|
||||
{
|
||||
initScanner();
|
||||
}
|
||||
@ -302,19 +296,19 @@ MathInterpreter::MathParserState::~MathParserState(void)
|
||||
|
||||
// constructors ////////////////////////////////////////////////////////////////
|
||||
MathInterpreter::MathInterpreter(void)
|
||||
: code_(NULL)
|
||||
: code_(nullptr)
|
||||
, codeName_("<no_code>")
|
||||
, state_(NULL)
|
||||
, root_(NULL)
|
||||
, state_(nullptr)
|
||||
, root_(nullptr)
|
||||
, gotReturn_(false)
|
||||
, status_(Status::none)
|
||||
{}
|
||||
|
||||
MathInterpreter::MathInterpreter(const std::string &code)
|
||||
: code_(NULL)
|
||||
: code_(nullptr)
|
||||
, codeName_("<string>")
|
||||
, state_(NULL)
|
||||
, root_(NULL)
|
||||
, state_(nullptr)
|
||||
, root_(nullptr)
|
||||
, gotReturn_(false)
|
||||
, status_(Status::none)
|
||||
{
|
||||
@ -323,31 +317,22 @@ MathInterpreter::MathInterpreter(const std::string &code)
|
||||
|
||||
// destructor //////////////////////////////////////////////////////////////////
|
||||
MathInterpreter::~MathInterpreter(void)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
{}
|
||||
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
const Instruction * MathInterpreter::operator[](const unsigned int i) const
|
||||
{
|
||||
return program_[i];
|
||||
return program_[i].get();
|
||||
}
|
||||
|
||||
const MathNode * MathInterpreter::getAST(void) const
|
||||
{
|
||||
if (root_)
|
||||
{
|
||||
return root_;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return root_.get();
|
||||
}
|
||||
|
||||
void MathInterpreter::push(const Instruction *i)
|
||||
{
|
||||
program_.push_back(i);
|
||||
program_.push_back(unique_ptr<const Instruction>(i));
|
||||
}
|
||||
|
||||
// initialization //////////////////////////////////////////////////////////////
|
||||
@ -357,24 +342,18 @@ void MathInterpreter::setCode(const std::string &code)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
code_ = new stringstream(code);
|
||||
code_.reset(new stringstream(code));
|
||||
codeName_ = "<string>";
|
||||
state_ = new MathParserState(code_, &codeName_, &root_);
|
||||
state_.reset(new MathParserState(code_.get(), &codeName_, &root_));
|
||||
status_ = Status::initialised;
|
||||
}
|
||||
|
||||
void MathInterpreter::reset(void)
|
||||
{
|
||||
InstructionContainer::iterator i;
|
||||
|
||||
delete code_;
|
||||
code_.reset(nullptr);
|
||||
codeName_ = "<no_code>";
|
||||
delete state_;
|
||||
delete root_;
|
||||
for (i = program_.begin(); i != program_.end(); ++i)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
state_.reset(nullptr);
|
||||
root_.reset(nullptr);
|
||||
program_.clear();
|
||||
status_ = 0;
|
||||
}
|
||||
@ -382,11 +361,11 @@ void MathInterpreter::reset(void)
|
||||
// parser //////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Bison/Flex parser declaration
|
||||
int _math_parse(MathInterpreter::MathParserState* state);
|
||||
int _math_parse(MathInterpreter::MathParserState *state);
|
||||
|
||||
void MathInterpreter::parse(void)
|
||||
{
|
||||
_math_parse(state_);
|
||||
_math_parse(state_.get());
|
||||
}
|
||||
|
||||
// interpreter /////////////////////////////////////////////////////////////////
|
||||
@ -414,6 +393,9 @@ void MathInterpreter::compile(void)
|
||||
#define ELIFNODE(name, nArg) else IFNODE(name, nArg)
|
||||
#define ELSE else
|
||||
|
||||
#define PUSH_INS(type, ...) \
|
||||
program_.push_back(unique_ptr<type>(new (type)(__VA_ARGS__)))
|
||||
|
||||
void MathInterpreter::compileNode(const MathNode& n)
|
||||
{
|
||||
if (!gotReturn_)
|
||||
@ -421,10 +403,10 @@ void MathInterpreter::compileNode(const MathNode& n)
|
||||
switch (n.getType())
|
||||
{
|
||||
case MathNode::Type::cst:
|
||||
program_.push_back(new Push(strTo<double>(n.getName())));
|
||||
PUSH_INS(Push, strTo<double>(n.getName()));
|
||||
break;
|
||||
case MathNode::Type::var:
|
||||
program_.push_back(new Push(n.getName()));
|
||||
PUSH_INS(Push, n.getName());
|
||||
break;
|
||||
case MathNode::Type::op:
|
||||
// semicolon
|
||||
@ -464,12 +446,12 @@ void MathInterpreter::compileNode(const MathNode& n)
|
||||
// pop instruction if at the end of a statement
|
||||
if (hasSemicolonParent)
|
||||
{
|
||||
program_.push_back(new Pop(n[0].getName()));
|
||||
program_.push_back(unique_ptr<Pop>(new Pop(n[0].getName())));
|
||||
}
|
||||
// store instruction else
|
||||
else
|
||||
{
|
||||
program_.push_back(new Store(n[0].getName()));
|
||||
PUSH_INS(Store, n[0].getName());
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -484,12 +466,12 @@ void MathInterpreter::compileNode(const MathNode& n)
|
||||
{
|
||||
compileNode(n[i]);
|
||||
}
|
||||
IFNODE("-", 1) program_.push_back(new Neg);
|
||||
ELIFNODE("+", 2) program_.push_back(new Add);
|
||||
ELIFNODE("-", 2) program_.push_back(new Sub);
|
||||
ELIFNODE("*", 2) program_.push_back(new Mul);
|
||||
ELIFNODE("/", 2) program_.push_back(new Div);
|
||||
ELIFNODE("^", 2) program_.push_back(new Pow);
|
||||
IFNODE("-", 1) PUSH_INS(Neg,);
|
||||
ELIFNODE("+", 2) PUSH_INS(Add,);
|
||||
ELIFNODE("-", 2) PUSH_INS(Sub,);
|
||||
ELIFNODE("*", 2) PUSH_INS(Mul,);
|
||||
ELIFNODE("/", 2) PUSH_INS(Div,);
|
||||
ELIFNODE("^", 2) PUSH_INS(Pow,);
|
||||
ELSE LATAN_ERROR(Compilation, "unknown operator '"
|
||||
+ n.getName() + "'");
|
||||
}
|
||||
@ -511,7 +493,7 @@ void MathInterpreter::compileNode(const MathNode& n)
|
||||
{
|
||||
compileNode(n[i]);
|
||||
}
|
||||
program_.push_back(new Call(n.getName()));
|
||||
PUSH_INS(Call, n.getName());
|
||||
break;
|
||||
default:
|
||||
LATAN_ERROR(Compilation,
|
||||
|
@ -39,29 +39,25 @@ BEGIN_NAMESPACE
|
||||
class MathNode
|
||||
{
|
||||
public:
|
||||
class Type
|
||||
enum class Type
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
undef = -1,
|
||||
cst = 0,
|
||||
op = 1,
|
||||
var = 2,
|
||||
keyw = 3,
|
||||
func = 4
|
||||
};
|
||||
undef = -1,
|
||||
cst = 0,
|
||||
op = 1,
|
||||
var = 2,
|
||||
keyw = 3,
|
||||
func = 4
|
||||
};
|
||||
public:
|
||||
// constructor
|
||||
MathNode(const std::string &name, const unsigned int type);
|
||||
MathNode(const std::string &name, const unsigned int type,
|
||||
// constructors
|
||||
MathNode(const std::string &name, const Type type);
|
||||
MathNode(const std::string &name, const Type type,
|
||||
const unsigned int nArg, ...);
|
||||
// destructor
|
||||
virtual ~MathNode();
|
||||
// access
|
||||
const std::string& getName(void) const;
|
||||
unsigned int getType(void) const;
|
||||
Type getType(void) const;
|
||||
unsigned int getNArg(void) const;
|
||||
const MathNode * getParent(void) const;
|
||||
unsigned int getLevel(void) const;
|
||||
@ -70,10 +66,10 @@ public:
|
||||
// operator
|
||||
const MathNode &operator[](const unsigned int i) const;
|
||||
private:
|
||||
std::string name_;
|
||||
unsigned int type_;
|
||||
std::vector<MathNode *> arg_;
|
||||
const MathNode * parent_;
|
||||
std::string name_;
|
||||
Type type_;
|
||||
std::vector<std::unique_ptr<MathNode>> arg_;
|
||||
const MathNode * parent_;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const MathNode &n);
|
||||
@ -99,23 +95,21 @@ public:
|
||||
virtual ~Instruction();
|
||||
// instruction execution
|
||||
virtual void operator()(RunContext &context) const = 0;
|
||||
friend std::ostream& operator<<(std::ostream &out, const Instruction &ins);
|
||||
friend std::ostream & operator<<(std::ostream &out, const Instruction &ins);
|
||||
private:
|
||||
virtual void print(std::ostream &out) const = 0;
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &out, const Instruction &ins);
|
||||
|
||||
// Push
|
||||
class Push: public Instruction
|
||||
{
|
||||
private:
|
||||
class ArgType
|
||||
enum class ArgType
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Constant = 0,
|
||||
Variable = 1
|
||||
};
|
||||
Constant = 0,
|
||||
Variable = 1
|
||||
};
|
||||
public:
|
||||
//constructors
|
||||
@ -126,7 +120,7 @@ public:
|
||||
private:
|
||||
virtual void print(std::ostream& out) const;
|
||||
private:
|
||||
unsigned int type_;
|
||||
ArgType type_;
|
||||
double val_;
|
||||
std::string name_;
|
||||
};
|
||||
@ -198,12 +192,12 @@ class MathInterpreter
|
||||
|
||||
public:
|
||||
// parser state
|
||||
class MathParserState: public ParserState<MathNode *>
|
||||
class MathParserState: public ParserState<std::unique_ptr<MathNode>>
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
explicit MathParserState(std::istream *stream, std::string *name,
|
||||
MathNode **data);
|
||||
std::unique_ptr<MathNode> *data);
|
||||
// destructor
|
||||
virtual ~MathParserState(void);
|
||||
private:
|
||||
@ -225,7 +219,7 @@ private:
|
||||
};
|
||||
};
|
||||
// instruction container
|
||||
typedef std::vector<const Instruction *> InstructionContainer;
|
||||
typedef std::vector<std::unique_ptr<const Instruction>> Program;
|
||||
public:
|
||||
// constructors
|
||||
MathInterpreter(void);
|
||||
@ -242,8 +236,8 @@ public:
|
||||
// execution
|
||||
void operator()(RunContext &context);
|
||||
// IO
|
||||
friend std::ostream &operator<<(std::ostream &out,
|
||||
const MathInterpreter &program);
|
||||
friend std::ostream & operator<<(std::ostream &out,
|
||||
const MathInterpreter &program);
|
||||
private:
|
||||
// initialization
|
||||
void reset(void);
|
||||
@ -256,15 +250,17 @@ private:
|
||||
// execution
|
||||
void execute(RunContext &context) const;
|
||||
private:
|
||||
std::istream *code_;
|
||||
std::string codeName_;
|
||||
MathParserState *state_;
|
||||
MathNode *root_;
|
||||
bool gotReturn_;
|
||||
InstructionContainer program_;
|
||||
unsigned int status_;
|
||||
std::unique_ptr<std::istream> code_;
|
||||
std::string codeName_;
|
||||
std::unique_ptr<MathParserState> state_;
|
||||
std::unique_ptr<MathNode> root_;
|
||||
bool gotReturn_;
|
||||
Program program_;
|
||||
unsigned int status_;
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &out, const MathInterpreter &program);
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // Latan_MathInterpreter_hpp_
|
||||
|
@ -39,9 +39,9 @@
|
||||
|
||||
%union
|
||||
{
|
||||
double val_double;
|
||||
char val_char;
|
||||
char val_str[MAXIDLENGTH];
|
||||
double val_double;
|
||||
char val_char;
|
||||
char val_str[MAXIDLENGTH];
|
||||
Latan::MathNode *val_node;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
|
||||
program:
|
||||
/* empty string */
|
||||
| stmt_list {*(state->data) = $1;}
|
||||
| stmt_list {(*(state->data)).reset($1);}
|
||||
;
|
||||
|
||||
stmt:
|
||||
|
@ -40,10 +40,10 @@ private:
|
||||
virtual void initScanner(void) = 0;
|
||||
virtual void destroyScanner(void) = 0;
|
||||
public:
|
||||
DataObj *data;
|
||||
void *scanner;
|
||||
std::istream *stream;
|
||||
std::string *streamName;
|
||||
DataObj *data;
|
||||
void *scanner;
|
||||
std::istream *stream;
|
||||
std::string *streamName;
|
||||
|
||||
};
|
||||
|
||||
@ -51,7 +51,7 @@ template <typename DataObj>
|
||||
ParserState<DataObj>::ParserState(std::istream *streamPt, std::string *namePt,
|
||||
DataObj *dataPt)
|
||||
: data(dataPt)
|
||||
, scanner(NULL)
|
||||
, scanner(nullptr)
|
||||
, stream(streamPt)
|
||||
, streamName(namePt)
|
||||
{}
|
||||
|
@ -115,6 +115,8 @@ private:
|
||||
std::vector<std::string> plotCommand_;
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream &out, const Plot &plot);
|
||||
|
||||
END_NAMESPACE
|
||||
|
||||
#endif // Latan_Plot_hpp_
|
||||
|
@ -37,7 +37,7 @@ RandGen::State::State(void)
|
||||
RandGen::State::~State(void)
|
||||
{}
|
||||
|
||||
unsigned int RandGen::State::getType(void) const
|
||||
IoObject::IoType RandGen::State::getType(void) const
|
||||
{
|
||||
return IoType::rgState;
|
||||
}
|
||||
|
@ -36,13 +36,15 @@ class RandGen
|
||||
public:
|
||||
class State: public Eigen::Array<int, RLXG_STATE_SIZE, 1>, public IoObject
|
||||
{
|
||||
private:
|
||||
typedef Eigen::Array<int, RLXG_STATE_SIZE, 1> Base;
|
||||
public:
|
||||
// constructor
|
||||
State(void);
|
||||
// destructor
|
||||
~State(void);
|
||||
// IO type
|
||||
unsigned int getType(void) const;
|
||||
IoType getType(void) const;
|
||||
};
|
||||
private:
|
||||
// Martin Luescher's ranlxd generator interface
|
||||
|
@ -24,7 +24,7 @@ using namespace Latan;
|
||||
using namespace std;
|
||||
|
||||
template <>
|
||||
unsigned int Sample<DMat>::getType(void) const
|
||||
IoObject::IoType Sample<DMat>::getType(void) const
|
||||
{
|
||||
return IoType::dMatSample;
|
||||
}
|
||||
|
@ -48,14 +48,14 @@ public:
|
||||
// operators
|
||||
T& operator[](const int s);
|
||||
// IO type
|
||||
virtual unsigned int getType(void) const;
|
||||
virtual IoType getType(void) const;
|
||||
private:
|
||||
// index of the first element to take into account for statistics
|
||||
virtual unsigned int getOffset(void) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
unsigned int Sample<DMat>::getType(void) const;
|
||||
IoObject::IoType Sample<DMat>::getType(void) const;
|
||||
|
||||
// specialization aliases
|
||||
typedef Sample<DMat> DMatSample;
|
||||
@ -101,7 +101,7 @@ T& Sample<T>::operator[](const int s)
|
||||
|
||||
// IO type /////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
unsigned int Sample<T>::getType(void) const
|
||||
IoObject::IoType Sample<T>::getType(void) const
|
||||
{
|
||||
return IoType::noType;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <cfloat>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
|
Reference in New Issue
Block a user