mirror of
				https://github.com/aportelli/LatAnalyze.git
				synced 2025-11-04 08:04:32 +00:00 
			
		
		
		
	big cleaning and update: switching to C++11
This commit is contained in:
		
							
								
								
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
SUBDIRS = latan examples
 | 
			
		||||
SUBDIRS = latan utils examples
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I .buildutils/m4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										141
									
								
								acinclude.m4
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								acinclude.m4
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										20
									
								
								examples/exMat.dat
									
									
									
									
									
										Normal 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 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
#include <latan/Global.hpp>
 | 
			
		||||
#include <latan/Function.hpp>
 | 
			
		||||
#include <latan/MathInterpreter.hpp>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <stack>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cstdarg>
 | 
			
		||||
@@ -49,10 +50,12 @@ public:
 | 
			
		||||
    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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								latan/Io.cpp
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -219,6 +216,6 @@ int _ioAscii_parse(AsciiFile::AsciiParserState* state);
 | 
			
		||||
void AsciiFile::parse()
 | 
			
		||||
{
 | 
			
		||||
    fileStream_.seekg(0);
 | 
			
		||||
    _ioAscii_parse(state_);
 | 
			
		||||
    _ioAscii_parse(state_.get());
 | 
			
		||||
    isParsed_ = true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								latan/Io.hpp
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								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);
 | 
			
		||||
@@ -155,7 +156,7 @@ private:
 | 
			
		||||
private:
 | 
			
		||||
    std::fstream                      fileStream_;
 | 
			
		||||
    bool                              isParsed_;
 | 
			
		||||
    AsciiParserState* state_;
 | 
			
		||||
    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
 | 
			
		||||
@@ -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);}
 | 
			
		||||
    ;
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -386,7 +365,7 @@ 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,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_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -104,19 +100,17 @@ 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);
 | 
			
		||||
@@ -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_
 | 
			
		||||
 
 | 
			
		||||
@@ -78,7 +78,7 @@
 | 
			
		||||
 | 
			
		||||
program:
 | 
			
		||||
     /* empty string */
 | 
			
		||||
    | stmt_list {*(state->data) = $1;}
 | 
			
		||||
    | stmt_list {(*(state->data)).reset($1);}
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
stmt:
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								utils/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								utils/Makefile.am
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										1
									
								
								utils/latan
									
									
									
									
									
										Symbolic link
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
../latan
 | 
			
		||||
							
								
								
									
										22
									
								
								utils/sample_read.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								utils/sample_read.cpp
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user