1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-09-19 21:25:36 +01:00

big cleaning and update: switching to C++11

This commit is contained in:
Antonin Portelli 2014-02-13 19:23:39 +00:00
parent f9e355e3ea
commit 47b9789f84
33 changed files with 426 additions and 1057 deletions

11
.gitignore vendored
View File

@ -48,3 +48,14 @@ latan/*Parser.hpp
# Eigen headers
latan/Eigen/*
latan/eigen_files.mk
# Examples
examples/exCompiledDoubleFunction
examples/exMat
examples/exMathInterpreter
examples/exPlot
examples/exRand
examples/exRand.seed
# Utils
utils/latan_sample_read

View File

@ -1,3 +1,3 @@
SUBDIRS = latan examples
SUBDIRS = latan utils examples
ACLOCAL_AMFLAGS = -I .buildutils/m4

View File

@ -91,4 +91,145 @@ done
])
])
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
struct Base {
virtual void f() {}
};
struct Child : public Base {
virtual void f() override {}
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
auto l = [](){};
]])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

View File

@ -5,6 +5,7 @@ AC_PREREQ([2.64])
AC_INIT([LatAnalyze],[3.0alpha1],[antonin.portelli@me.com],[latan])
AC_CONFIG_AUX_DIR([.buildutils])
AC_CONFIG_SRCDIR([latan/Global.cpp])
AC_CONFIG_SRCDIR([utils/sample_read.cpp])
AC_CONFIG_SRCDIR([examples/exMathInterpreter.cpp])
AC_CONFIG_MACRO_DIR([.buildutils/m4])
AM_INIT_AUTOMAKE([-Wall -Werror])
@ -42,12 +43,12 @@ AC_DEFINE_UNQUOTED([C_COMP_VENDOR],["$ax_cv_c_compiler_vendor"],
AM_CONDITIONAL([CC_GNU],[test $ax_cv_c_compiler_vendor = "gnu"])
AM_CONDITIONAL([CC_INTEL],[test $ax_cv_c_compiler_vendor = "intel"])
AC_LANG([C++])
AX_CXX_COMPILE_STDCXX_11([noext],[mandatory])
AX_COMPILER_VENDOR
AC_DEFINE_UNQUOTED([CXX_COMP_VENDOR],["$ax_cv_cxx_compiler_vendor"],
[vendor of C++ compiler that will compile the code])
AM_CONDITIONAL([CXX_GNU],[test $ax_cv_cxx_compiler_vendor = "gnu"])
AM_CONDITIONAL([CXX_INTEL],[test $ax_cv_cxx_compiler_vendor = "intel"])
AC_LANG([C])
AX_GCC_VERSION
AC_DEFINE_UNQUOTED([GCC_VERSION],["$GCC_VERSION"],
[version of gcc that will compile the code])
@ -56,9 +57,7 @@ AC_DEFINE_UNQUOTED([GXX_VERSION],["$GXX_VERSION"],
[version of g++ that will compile the code])
# Checks for libraries.
AC_LANG([C++])
AC_CHECK_LIB([m],[cos],[],[AC_MSG_ERROR([libm library not found])])
AC_CHECK_LIB([stdc++],[main],[LIBS="-lstdc++ $LIBS"],[AC_MSG_ERROR([libstdc++ library not found])])
# Checks for header files.
AC_HEADER_STDC
@ -67,5 +66,5 @@ AC_SUBST([LIBS])
AC_SUBST([AM_CFLAGS])
AC_SUBST([AM_LDFLAGS])
AC_CONFIG_FILES([Makefile latan/Makefile examples/Makefile])
AC_CONFIG_FILES([Makefile latan/Makefile utils/Makefile examples/Makefile])
AC_OUTPUT

20
examples/exMat.dat Normal file
View File

@ -0,0 +1,20 @@
#L latan_begin mat A
2
2.3 5
4.5 -1.15281
#L latan_end mat
#L latan_begin mat B
3
1.1
1.2
1.3
2
2.2
2.3
#L latan_end mat
#L latan_begin mat AB
3
12.53 13.76 14.49
2.64438 2.86382 3.19854
#L latan_end mat

View File

@ -1,70 +0,0 @@
#include <iostream>
#include <latan/Math.hpp>
#include <latan/MathCompiler.hpp>
using namespace std;
using namespace Latan;
int main(int argc, char* argv[])
{
string source;
if (argc != 2)
{
cerr << "usage: " << argv[0] << " <program>" << endl;
}
source = argv[1];
MathCompiler C(source);
VarTable vtable;
FunctionTable ftable;
stack<double> dstack;
const VirtualProgram& P = C();
cout << "-- Source code:" << endl << source << endl << endl;
cout << "-- Abstract Syntax Tree:" << endl << *C.getAST() << endl;
cout << "-- Program:" << endl << P << endl;
StdMath::addStdMathFunc(ftable);
for (unsigned int i=0;i<P.size();++i)
{
(*(P[i]))(dstack, vtable, ftable);
}
if (!dstack.empty())
{
cout << "-- Result: " << dstack.top() << endl;
}
return EXIT_SUCCESS;
}
/*int main(void)
{
ASCIIFile F;
DMat A,B;
F.Open("foo.boot",FileMode::Read);
A = F.Read<DMat>("bla");
B = F.Read<DMat>("bli");
cout << A << endl;
cout << B << endl;
cout << A*B << endl;
return EXIT_SUCCESS;
}*/
/*
int main(void)
{
DMat m(2,2);
m(0,6) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
cout << "Here is the matrix m:\n" << m << endl;
DVec v(2);
v(0) = 4;
v(1) = v(0) - 1;
cout << "Here is the vector v:\n" << v << endl;
}
*/

View File

@ -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_);

View File

@ -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,
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_

View File

@ -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);
}

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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);
@ -155,7 +156,7 @@ private:
private:
std::fstream fileStream_;
bool isParsed_;
AsciiParserState* state_;
std::unique_ptr<AsciiParserState> state_;
};
END_NAMESPACE

View File

@ -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
@ -48,14 +52,13 @@
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);}
;

View File

@ -28,20 +28,16 @@ BEGIN_NAMESPACE
class IoObject
{
public:
class IoType
{
public:
enum
enum class IoType
{
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

View File

@ -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;
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -39,10 +39,7 @@ BEGIN_NAMESPACE
class MathNode
{
public:
class Type
{
public:
enum
enum class Type
{
undef = -1,
cst = 0,
@ -51,17 +48,16 @@ public:
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;
@ -71,8 +67,8 @@ public:
const MathNode &operator[](const unsigned int i) const;
private:
std::string name_;
unsigned int type_;
std::vector<MathNode *> arg_;
Type type_;
std::vector<std::unique_ptr<MathNode>> arg_;
const MathNode * parent_;
};
@ -99,24 +95,22 @@ 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
{
public:
enum
enum class ArgType
{
Constant = 0,
Variable = 1
};
};
public:
//constructors
explicit Push(const double val);
@ -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,7 +236,7 @@ public:
// execution
void operator()(RunContext &context);
// IO
friend std::ostream &operator<<(std::ostream &out,
friend std::ostream & operator<<(std::ostream &out,
const MathInterpreter &program);
private:
// initialization
@ -256,15 +250,17 @@ private:
// execution
void execute(RunContext &context) const;
private:
std::istream *code_;
std::unique_ptr<std::istream> code_;
std::string codeName_;
MathParserState *state_;
MathNode *root_;
std::unique_ptr<MathParserState> state_;
std::unique_ptr<MathNode> root_;
bool gotReturn_;
InstructionContainer program_;
Program program_;
unsigned int status_;
};
std::ostream & operator<<(std::ostream &out, const MathInterpreter &program);
END_NAMESPACE
#endif // Latan_MathInterpreter_hpp_

View File

@ -78,7 +78,7 @@
program:
/* empty string */
| stmt_list {*(state->data) = $1;}
| stmt_list {(*(state->data)).reset($1);}
;
stmt:

View File

@ -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)
{}

View File

@ -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_

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -24,6 +24,7 @@
#include <iostream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <cfloat>
#include <climits>
#include <cmath>

24
utils/Makefile.am Normal file
View File

@ -0,0 +1,24 @@
if CC_GNU
COM_CFLAGS = -Wall -W -pedantic
else
if CC_INTEL
COM_CFLAGS = -Wall
endif
endif
if CXX_GNU
COM_CXXFLAGS = -Wall -W -pedantic
else
if CXX_INTEL
COM_CXXFLAGS = -Wall
endif
endif
noinst_PROGRAMS = \
latan_sample_read
latan_sample_read_SOURCES = sample_read.cpp
latan_sample_read_CFLAGS = -g -O2
latan_sample_read_LDFLAGS = -L../latan/.libs -llatan
ACLOCAL_AMFLAGS = -I .buildutils/m4

1
utils/latan Symbolic link
View File

@ -0,0 +1 @@
../latan

22
utils/sample_read.cpp Normal file
View File

@ -0,0 +1,22 @@
#include <iostream>
#include <latan/Dataset.hpp>
#include <latan/Io.hpp>
#include <latan/Sample.hpp>
using namespace std;
using namespace Latan;
int main(void)
{
Dataset<DMat, AsciiFile> dataset;
DMatSample s, r;
RandGen g;
dataset.load("man", "HVP_2_2_000_00_0_0");
s = dataset.bootstrapMean(100, g);
cout << "central value:\n" << s[central] << endl;
cout << "standard deviation:\n" << s.variance().cwiseSqrt() << endl;
return EXIT_SUCCESS;
}