mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2025-04-11 03:20:46 +01:00
math compiler supports function calls + standard C math library wrapper
This commit is contained in:
parent
fa5ca7273c
commit
36bc0bc9b0
@ -1,4 +1,5 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <latan/Function.hpp>
|
||||||
#include <latan/MathCompiler.hpp>
|
#include <latan/MathCompiler.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -8,15 +9,21 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
MathCompiler C(argv[1]);
|
MathCompiler C(argv[1]);
|
||||||
VarTable vtable;
|
VarTable vtable;
|
||||||
|
FunctionTable ftable;
|
||||||
stack<double> dstack;
|
stack<double> dstack;
|
||||||
const VirtualProgram& P = C();
|
const VirtualProgram& P = C();
|
||||||
|
|
||||||
|
ftable["exp"] = &StdMath::exp;
|
||||||
|
ftable["atan2"] = &StdMath::atan2;
|
||||||
cout << P << endl;
|
cout << P << endl;
|
||||||
for (int i=0;i<P.size();++i)
|
for (unsigned int i=0;i<P.size();++i)
|
||||||
{
|
{
|
||||||
(*(P[i]))(dstack,vtable);
|
(*(P[i]))(dstack,vtable,ftable);
|
||||||
|
}
|
||||||
|
if (!dstack.empty())
|
||||||
|
{
|
||||||
|
cout << "result= " << dstack.top() << endl;
|
||||||
}
|
}
|
||||||
cout << "result= " << dstack.top() << endl;
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
81
latan/Function.cpp
Normal file
81
latan/Function.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include <latan/Function.hpp>
|
||||||
|
#include <latan/includes.hpp>
|
||||||
|
|
||||||
|
#define DEF_STD_FUNC_1ARG(name, funcName) \
|
||||||
|
name##Function::name##Function(void): DoubleFunction(1) {}\
|
||||||
|
name##Function::~name##Function(void) {}\
|
||||||
|
double name##Function::operator()(std::vector<double> &arg)\
|
||||||
|
{\
|
||||||
|
return funcName(arg[0]);\
|
||||||
|
}\
|
||||||
|
name##Function STDMATH_NAMESPACE::funcName;
|
||||||
|
|
||||||
|
#define DEF_STD_FUNC_2ARG(name, funcName) \
|
||||||
|
name##Function::name##Function(void): DoubleFunction(2) {}\
|
||||||
|
name##Function::~name##Function(void) {}\
|
||||||
|
double name##Function::operator()(std::vector<double> &arg)\
|
||||||
|
{\
|
||||||
|
return funcName(arg[0], arg[1]);\
|
||||||
|
}\
|
||||||
|
name##Function STDMATH_NAMESPACE::funcName;
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Latan;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Function implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor/destructor //////////////////////////////////////////////////////
|
||||||
|
Function::Function(const unsigned nArg)
|
||||||
|
: nArg_(nArg)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Function::~Function(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
unsigned int Function::getNArg(void)
|
||||||
|
{
|
||||||
|
return nArg_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* DoubleFunction implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
DoubleFunction::DoubleFunction(const unsigned nArg)
|
||||||
|
: Function(nArg), buffer_(nArg)
|
||||||
|
{}
|
||||||
|
|
||||||
|
DoubleFunction::~DoubleFunction(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
double DoubleFunction::operator()(std::stack<double> &arg)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < getNArg(); ++i)
|
||||||
|
{
|
||||||
|
buffer_[getNArg() - i - 1] = arg.top();
|
||||||
|
arg.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this)(buffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
double DoubleFunction::operator()(const double x0, ...)
|
||||||
|
{
|
||||||
|
buffer_[0] = x0;
|
||||||
|
if (getNArg() > 1)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
va_start(va, x0);
|
||||||
|
for (unsigned int i = 1; i < getNArg(); ++i)
|
||||||
|
{
|
||||||
|
buffer_[i] = va_arg(va, double);
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this)(buffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
45
latan/Function.hpp
Normal file
45
latan/Function.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef LATAN_FUNCTION_HPP_
|
||||||
|
#define LATAN_FUNCTION_HPP_
|
||||||
|
|
||||||
|
#include <latan/Global.hpp>
|
||||||
|
#include <stack>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
LATAN_BEGIN_CPPDECL
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Base function class *
|
||||||
|
******************************************************************************/
|
||||||
|
class Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor/destructor
|
||||||
|
explicit Function(const unsigned nArg);
|
||||||
|
~Function(void);
|
||||||
|
// access
|
||||||
|
unsigned int getNArg(void);
|
||||||
|
private:
|
||||||
|
const unsigned int nArg_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Double function class *
|
||||||
|
******************************************************************************/
|
||||||
|
class DoubleFunction: public Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructor/destructor
|
||||||
|
explicit DoubleFunction(const unsigned nArg);
|
||||||
|
virtual ~DoubleFunction(void);
|
||||||
|
// function call
|
||||||
|
virtual double operator()(std::vector<double> &arg) = 0;
|
||||||
|
double operator()(std::stack<double> &arg);
|
||||||
|
double operator()(const double x0, ...);
|
||||||
|
private:
|
||||||
|
std::vector<double> buffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
LATAN_END_CPPDECL
|
||||||
|
|
||||||
|
#endif
|
@ -26,12 +26,14 @@ lib_LTLIBRARIES = liblatan.la
|
|||||||
|
|
||||||
liblatan_la_SOURCES = \
|
liblatan_la_SOURCES = \
|
||||||
Exceptions.cpp \
|
Exceptions.cpp \
|
||||||
|
Function.cpp \
|
||||||
Global.cpp \
|
Global.cpp \
|
||||||
includes.hpp \
|
includes.hpp \
|
||||||
Io.cpp \
|
Io.cpp \
|
||||||
IoAsciiParser.ypp \
|
IoAsciiParser.ypp \
|
||||||
IoAsciiLexer.lpp \
|
IoAsciiLexer.lpp \
|
||||||
Mat.cpp \
|
Mat.cpp \
|
||||||
|
Math.cpp \
|
||||||
MathCompiler.cpp \
|
MathCompiler.cpp \
|
||||||
MathParser.ypp \
|
MathParser.ypp \
|
||||||
MathLexer.lpp \
|
MathLexer.lpp \
|
||||||
@ -39,10 +41,12 @@ liblatan_la_SOURCES = \
|
|||||||
../config.h
|
../config.h
|
||||||
liblatan_ladir = $(pkgincludedir)
|
liblatan_ladir = $(pkgincludedir)
|
||||||
liblatan_la_HEADERS = \
|
liblatan_la_HEADERS = \
|
||||||
|
Function.hpp \
|
||||||
Global.hpp \
|
Global.hpp \
|
||||||
Io.hpp \
|
Io.hpp \
|
||||||
IoObject.hpp \
|
IoObject.hpp \
|
||||||
Mat.hpp \
|
Mat.hpp \
|
||||||
|
Math.hpp \
|
||||||
MathCompiler.hpp \
|
MathCompiler.hpp \
|
||||||
Sample.hpp
|
Sample.hpp
|
||||||
liblatan_la_CFLAGS = $(COM_CFLAGS)
|
liblatan_la_CFLAGS = $(COM_CFLAGS)
|
||||||
|
95
latan/Math.cpp
Normal file
95
latan/Math.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include <latan/Math.hpp>
|
||||||
|
#include <latan/includes.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Latan;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Standard C functions *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define DEF_STD_FUNC_1ARG(name, funcName) \
|
||||||
|
name##Function::name##Function(void): DoubleFunction(1) {}\
|
||||||
|
name##Function::~name##Function(void) {}\
|
||||||
|
double name##Function::operator()(std::vector<double> &arg)\
|
||||||
|
{\
|
||||||
|
return funcName(arg[0]);\
|
||||||
|
}\
|
||||||
|
name##Function STDMATH_NAMESPACE::funcName;
|
||||||
|
|
||||||
|
#define DEF_STD_FUNC_2ARG(name, funcName) \
|
||||||
|
name##Function::name##Function(void): DoubleFunction(2) {}\
|
||||||
|
name##Function::~name##Function(void) {}\
|
||||||
|
double name##Function::operator()(std::vector<double> &arg)\
|
||||||
|
{\
|
||||||
|
return funcName(arg[0], arg[1]);\
|
||||||
|
}\
|
||||||
|
name##Function STDMATH_NAMESPACE::funcName;
|
||||||
|
|
||||||
|
// Trigonometric functions
|
||||||
|
DEF_STD_FUNC_1ARG(Cos, cos)
|
||||||
|
DEF_STD_FUNC_1ARG(Sin, sin)
|
||||||
|
DEF_STD_FUNC_1ARG(Tan, tan)
|
||||||
|
DEF_STD_FUNC_1ARG(ACos, acos)
|
||||||
|
DEF_STD_FUNC_1ARG(ASin, asin)
|
||||||
|
DEF_STD_FUNC_1ARG(ATan, atan)
|
||||||
|
DEF_STD_FUNC_2ARG(ATan2, atan2)
|
||||||
|
|
||||||
|
// Hyperbolic functions
|
||||||
|
DEF_STD_FUNC_1ARG(Cosh, cosh)
|
||||||
|
DEF_STD_FUNC_1ARG(Sinh, sinh)
|
||||||
|
DEF_STD_FUNC_1ARG(Tanh, tanh)
|
||||||
|
|
||||||
|
// Exponential and logarithmic functions
|
||||||
|
DEF_STD_FUNC_1ARG(Exp, exp)
|
||||||
|
DEF_STD_FUNC_1ARG(Log, log)
|
||||||
|
|
||||||
|
// Power functions
|
||||||
|
DEF_STD_FUNC_2ARG(Pow, pow)
|
||||||
|
DEF_STD_FUNC_1ARG(Sqrt, sqrt)
|
||||||
|
|
||||||
|
// Rounding and remainder functions
|
||||||
|
DEF_STD_FUNC_1ARG(Ceil, ceil)
|
||||||
|
DEF_STD_FUNC_1ARG(Floor, floor)
|
||||||
|
DEF_STD_FUNC_2ARG(FMod, fmod)
|
||||||
|
|
||||||
|
// Minimum, maximum, difference functions
|
||||||
|
DEF_STD_FUNC_2ARG(FDim, fdim)
|
||||||
|
DEF_STD_FUNC_2ARG(FMax, fmax)
|
||||||
|
DEF_STD_FUNC_2ARG(FMin, fmin)
|
||||||
|
|
||||||
|
// Absolute value
|
||||||
|
DEF_STD_FUNC_1ARG(Abs, abs)
|
||||||
|
|
||||||
|
#define ADD_FUNC(func) fTable[#func] = &STDMATH_NAMESPACE::func
|
||||||
|
void STDMATH_NAMESPACE::addStdMathFunc(FunctionTable &fTable)
|
||||||
|
{
|
||||||
|
// Trigonometric functions
|
||||||
|
ADD_FUNC(cos);
|
||||||
|
ADD_FUNC(sin);
|
||||||
|
ADD_FUNC(tan);
|
||||||
|
ADD_FUNC(acos);
|
||||||
|
ADD_FUNC(asin);
|
||||||
|
ADD_FUNC(atan);
|
||||||
|
ADD_FUNC(atan2);
|
||||||
|
// Hyperbolic functions
|
||||||
|
ADD_FUNC(cosh);
|
||||||
|
ADD_FUNC(sinh);
|
||||||
|
ADD_FUNC(tanh);
|
||||||
|
// Exponential and logarithmic functions
|
||||||
|
ADD_FUNC(exp);
|
||||||
|
ADD_FUNC(log);
|
||||||
|
// Power functions
|
||||||
|
ADD_FUNC(pow);
|
||||||
|
ADD_FUNC(sqrt);
|
||||||
|
// Rounding and remainder functions
|
||||||
|
ADD_FUNC(ceil);
|
||||||
|
ADD_FUNC(floor);
|
||||||
|
ADD_FUNC(fmod);
|
||||||
|
// Minimum, maximum, difference functions
|
||||||
|
ADD_FUNC(fdim);
|
||||||
|
ADD_FUNC(fmax);
|
||||||
|
ADD_FUNC(fmin);
|
||||||
|
// Absolute value
|
||||||
|
ADD_FUNC(abs);
|
||||||
|
}
|
73
latan/Math.hpp
Normal file
73
latan/Math.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#ifndef LATAN_MATH_HPP_
|
||||||
|
#define LATAN_MATH_HPP_
|
||||||
|
|
||||||
|
#include <latan/Global.hpp>
|
||||||
|
#include <latan/Function.hpp>
|
||||||
|
#include <latan/MathCompiler.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
LATAN_BEGIN_CPPDECL
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Standard C functions *
|
||||||
|
******************************************************************************/
|
||||||
|
#define STDMATH_NAMESPACE StdMath
|
||||||
|
|
||||||
|
#define DECL_STD_FUNC(name, funcName) \
|
||||||
|
class name##Function: public DoubleFunction\
|
||||||
|
{\
|
||||||
|
public:\
|
||||||
|
name##Function(void);\
|
||||||
|
virtual ~name##Function(void);\
|
||||||
|
using DoubleFunction::operator();\
|
||||||
|
virtual double operator()(std::vector<double> &arg);\
|
||||||
|
};\
|
||||||
|
namespace STDMATH_NAMESPACE\
|
||||||
|
{\
|
||||||
|
extern name##Function funcName;\
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigonometric functions
|
||||||
|
DECL_STD_FUNC(Cos, cos)
|
||||||
|
DECL_STD_FUNC(Sin, sin)
|
||||||
|
DECL_STD_FUNC(Tan, tan)
|
||||||
|
DECL_STD_FUNC(ACos, acos)
|
||||||
|
DECL_STD_FUNC(ASin, asin)
|
||||||
|
DECL_STD_FUNC(ATan, atan)
|
||||||
|
DECL_STD_FUNC(ATan2, atan2)
|
||||||
|
|
||||||
|
// Hyperbolic functions
|
||||||
|
DECL_STD_FUNC(Cosh, cosh)
|
||||||
|
DECL_STD_FUNC(Sinh, sinh)
|
||||||
|
DECL_STD_FUNC(Tanh, tanh)
|
||||||
|
|
||||||
|
// Exponential and logarithmic functions
|
||||||
|
DECL_STD_FUNC(Exp, exp)
|
||||||
|
DECL_STD_FUNC(Log, log)
|
||||||
|
|
||||||
|
// Power functions
|
||||||
|
DECL_STD_FUNC(Pow, pow)
|
||||||
|
DECL_STD_FUNC(Sqrt, sqrt)
|
||||||
|
|
||||||
|
// Rounding and remainder functions
|
||||||
|
DECL_STD_FUNC(Ceil, ceil)
|
||||||
|
DECL_STD_FUNC(Floor, floor)
|
||||||
|
DECL_STD_FUNC(FMod, fmod)
|
||||||
|
|
||||||
|
// Minimum, maximum, difference functions
|
||||||
|
DECL_STD_FUNC(FDim, fdim)
|
||||||
|
DECL_STD_FUNC(FMax, fmax)
|
||||||
|
DECL_STD_FUNC(FMin, fmin)
|
||||||
|
|
||||||
|
// Absolute value
|
||||||
|
DECL_STD_FUNC(Abs, abs)
|
||||||
|
|
||||||
|
// Add standard math functions to a table for the math compiler
|
||||||
|
namespace STDMATH_NAMESPACE
|
||||||
|
{
|
||||||
|
void addStdMathFunc(FunctionTable &fTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
LATAN_END_CPPDECL
|
||||||
|
|
||||||
|
#endif
|
@ -29,7 +29,7 @@ MathNode::MathNode(const std::string &name, const unsigned int type,\
|
|||||||
va_start(va, nArg);
|
va_start(va, nArg);
|
||||||
for (unsigned int i = 0; i < nArg; ++i)
|
for (unsigned int i = 0; i < nArg; ++i)
|
||||||
{
|
{
|
||||||
arg_[i] = va_arg(va, MathNode*);
|
arg_[i] = va_arg(va, MathNode *);
|
||||||
arg_[i]->parent_ = this;
|
arg_[i]->parent_ = this;
|
||||||
}
|
}
|
||||||
va_end(va);
|
va_end(va);
|
||||||
@ -62,6 +62,16 @@ unsigned int MathNode::getNArg(void) const
|
|||||||
return static_cast<unsigned int>(arg_.size());
|
return static_cast<unsigned int>(arg_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MathNode::setName(const std::string &name)
|
||||||
|
{
|
||||||
|
name_ = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MathNode::pushArg(MathNode *node)
|
||||||
|
{
|
||||||
|
arg_.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
// operator ////////////////////////////////////////////////////////////////////
|
// operator ////////////////////////////////////////////////////////////////////
|
||||||
const MathNode &MathNode::operator[](const unsigned int i) const
|
const MathNode &MathNode::operator[](const unsigned int i) const
|
||||||
{
|
{
|
||||||
@ -102,7 +112,8 @@ Push::Push(const string &name)
|
|||||||
, name_(name)
|
, name_(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Push::operator()(std::stack<double> &dStack, VarTable &vTable)
|
void Push::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
|
FunctionTable &fTable __dumb)
|
||||||
{
|
{
|
||||||
if (type_ == ArgType::Constant)
|
if (type_ == ArgType::Constant)
|
||||||
{
|
{
|
||||||
@ -138,8 +149,8 @@ Pop::Pop(const string &name)
|
|||||||
: name_(name)
|
: name_(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void Pop::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
void Pop::operator()(std::stack<double> &dStack, VarTable &vTable)
|
FunctionTable &fTable __dumb)
|
||||||
{
|
{
|
||||||
if (!name_.empty())
|
if (!name_.empty())
|
||||||
{
|
{
|
||||||
@ -157,8 +168,8 @@ Store::Store(const string &name)
|
|||||||
: name_(name)
|
: name_(name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void Store::operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
void Store::operator()(std::stack<double> &dStack, VarTable &vTable)
|
FunctionTable &fTable __dumb)
|
||||||
{
|
{
|
||||||
if (!name_.empty())
|
if (!name_.empty())
|
||||||
{
|
{
|
||||||
@ -171,8 +182,31 @@ void Store::print(std::ostream &out) const
|
|||||||
out << CODE_MOD << "store" << CODE_MOD << name_;
|
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)\
|
#define DEF_OP(name, nArg, exp, insName)\
|
||||||
void name::operator()(stack<double> &dStack, VarTable &vTable __dumb)\
|
void name::operator()(stack<double> &dStack, VarTable &vTable __dumb,\
|
||||||
|
FunctionTable &fTable __dumb)\
|
||||||
{\
|
{\
|
||||||
double x[nArg];\
|
double x[nArg];\
|
||||||
for (int i = 0; i < nArg; ++i)\
|
for (int i = 0; i < nArg; ++i)\
|
||||||
@ -320,14 +354,21 @@ void MathCompiler::compile(const MathNode& n)
|
|||||||
case MathNode::Type::op:
|
case MathNode::Type::op:
|
||||||
if (n.getName() == "=")
|
if (n.getName() == "=")
|
||||||
{
|
{
|
||||||
compile(n[1]);
|
if (n[0].getType() == MathNode::Type::var)
|
||||||
if (n.isRoot())
|
|
||||||
{
|
{
|
||||||
out_.push_back(new Pop(n[0].getName()));
|
compile(n[1]);
|
||||||
|
if (n.isRoot())
|
||||||
|
{
|
||||||
|
out_.push_back(new Pop(n[0].getName()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out_.push_back(new Store(n[0].getName()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out_.push_back(new Store(n[0].getName()));
|
LATAN_ERROR(Compilation, "invalid LHS for '='");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -352,6 +393,13 @@ void MathCompiler::compile(const MathNode& n)
|
|||||||
compile(n[i]);
|
compile(n[i]);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
LATAN_ERROR(Compilation,
|
LATAN_ERROR(Compilation,
|
||||||
"unknown node type (node '" + n.getName() + "')");
|
"unknown node type (node '" + n.getName() + "')");
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <latan/Function.hpp>
|
||||||
#include <latan/Global.hpp>
|
#include <latan/Global.hpp>
|
||||||
#include <latan/ParserState.hpp>
|
#include <latan/ParserState.hpp>
|
||||||
|
|
||||||
@ -27,7 +28,8 @@ public:
|
|||||||
cst = 0,
|
cst = 0,
|
||||||
op = 1,
|
op = 1,
|
||||||
var = 2,
|
var = 2,
|
||||||
keyw = 3
|
keyw = 3,
|
||||||
|
func = 4
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
@ -41,6 +43,8 @@ public:
|
|||||||
const std::string& getName(void) const;
|
const std::string& getName(void) const;
|
||||||
unsigned int getType(void) const;
|
unsigned int getType(void) const;
|
||||||
unsigned int getNArg(void) const;
|
unsigned int getNArg(void) const;
|
||||||
|
void setName(const std::string &name);
|
||||||
|
void pushArg(MathNode *node);
|
||||||
// operator
|
// operator
|
||||||
const MathNode &operator[](const unsigned int i) const;
|
const MathNode &operator[](const unsigned int i) const;
|
||||||
// test
|
// test
|
||||||
@ -55,7 +59,8 @@ private:
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Virtual machine code classes *
|
* Virtual machine code classes *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
typedef std::map<std::string, double> VarTable;
|
typedef std::map<std::string, double> VarTable;
|
||||||
|
typedef std::map<std::string, DoubleFunction *> FunctionTable;
|
||||||
|
|
||||||
// Abstract base
|
// Abstract base
|
||||||
class Instruction
|
class Instruction
|
||||||
@ -63,13 +68,14 @@ class Instruction
|
|||||||
public:
|
public:
|
||||||
virtual ~Instruction();
|
virtual ~Instruction();
|
||||||
// instruction execution
|
// instruction execution
|
||||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable) = 0;
|
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
|
FunctionTable &fTable) = 0;
|
||||||
friend std::ostream& operator<<(std::ostream &out, const Instruction &ins);
|
friend std::ostream& operator<<(std::ostream &out, const Instruction &ins);
|
||||||
private:
|
private:
|
||||||
virtual void print(std::ostream &out) const = 0;
|
virtual void print(std::ostream &out) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// push, pop and store
|
// Push
|
||||||
class Push: public Instruction
|
class Push: public Instruction
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -87,7 +93,8 @@ public:
|
|||||||
explicit Push(const double val);
|
explicit Push(const double val);
|
||||||
explicit Push(const std::string &name);
|
explicit Push(const std::string &name);
|
||||||
// instruction execution
|
// instruction execution
|
||||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable);
|
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
|
FunctionTable &fTable);
|
||||||
private:
|
private:
|
||||||
virtual void print(std::ostream& out) const;
|
virtual void print(std::ostream& out) const;
|
||||||
private:
|
private:
|
||||||
@ -96,38 +103,58 @@ private:
|
|||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pop
|
||||||
class Pop: public Instruction
|
class Pop: public Instruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//constructor
|
//constructor
|
||||||
explicit Pop(const std::string &name);
|
explicit Pop(const std::string &name);
|
||||||
// instruction execution
|
// instruction execution
|
||||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable);
|
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
|
FunctionTable &fTable);
|
||||||
private:
|
private:
|
||||||
virtual void print(std::ostream& out) const;
|
virtual void print(std::ostream& out) const;
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Store
|
||||||
class Store: public Instruction
|
class Store: public Instruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//constructor
|
//constructor
|
||||||
explicit Store(const std::string &name);
|
explicit Store(const std::string &name);
|
||||||
// instruction execution
|
// instruction execution
|
||||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable);
|
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,
|
||||||
|
FunctionTable &fTable);
|
||||||
private:
|
private:
|
||||||
virtual void print(std::ostream& out) const;
|
virtual void print(std::ostream& out) const;
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Float operations
|
// 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)\
|
#define DECL_OP(name)\
|
||||||
class name: public Instruction\
|
class name: public Instruction\
|
||||||
{\
|
{\
|
||||||
public:\
|
public:\
|
||||||
virtual void operator()(std::stack<double> &dStack, VarTable &vTable);\
|
virtual void operator()(std::stack<double> &dStack, VarTable &vTable,\
|
||||||
|
FunctionTable &fTable);\
|
||||||
private:\
|
private:\
|
||||||
virtual void print(std::ostream &out) const;\
|
virtual void print(std::ostream &out) const;\
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,9 @@ DIGIT [0-9]
|
|||||||
ALPHA [a-zA-Z_]
|
ALPHA [a-zA-Z_]
|
||||||
FLOAT (({DIGIT}+(\.{DIGIT}*)?)|({DIGIT}*\.{DIGIT}+))([eE][+-]?{DIGIT}+)?
|
FLOAT (({DIGIT}+(\.{DIGIT}*)?)|({DIGIT}*\.{DIGIT}+))([eE][+-]?{DIGIT}+)?
|
||||||
KEYWORD return
|
KEYWORD return
|
||||||
END ;
|
PUNC [;,()]
|
||||||
OP [+\-*/^=]
|
OP [+\-*/^=]
|
||||||
PAR [()]
|
PAR []
|
||||||
BLANK [ \t]
|
BLANK [ \t]
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@ -55,12 +55,11 @@ BLANK [ \t]
|
|||||||
}
|
}
|
||||||
{OP} {RET(*yytext);}
|
{OP} {RET(*yytext);}
|
||||||
{KEYWORD} {RET(*yytext);}
|
{KEYWORD} {RET(*yytext);}
|
||||||
{PAR} {RET(*yytext);}
|
{PUNC} {RET(*yytext);}
|
||||||
{ALPHA}({ALPHA}|{DIGIT})* {
|
{ALPHA}({ALPHA}|{DIGIT})* {
|
||||||
strncpy(yylval->val_str,yytext,MAXIDLENGTH);
|
strncpy(yylval->val_str,yytext,MAXIDLENGTH);
|
||||||
RETTOK(ID);
|
RETTOK(ID);
|
||||||
}
|
}
|
||||||
{END} {RETTOK(END);}
|
|
||||||
<*>\n {yylloc->last_column = 0;}
|
<*>\n {yylloc->last_column = 0;}
|
||||||
<*>{BLANK}
|
<*>{BLANK}
|
||||||
<*>. {yylval->val_char = yytext[0]; RETTOK(ERR);}
|
<*>. {yylval->val_char = yytext[0]; RETTOK(ERR);}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
Latan::MathNode *val_node;
|
Latan::MathNode *val_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token END
|
|
||||||
%token <val_char> ERR
|
%token <val_char> ERR
|
||||||
%token <val_str> FLOAT
|
%token <val_str> FLOAT
|
||||||
%token <val_str> ID
|
%token <val_str> ID
|
||||||
@ -39,6 +38,7 @@
|
|||||||
%nonassoc UMINUS
|
%nonassoc UMINUS
|
||||||
|
|
||||||
%type <val_node> expr
|
%type <val_node> expr
|
||||||
|
%type <val_node> funcargs
|
||||||
|
|
||||||
%{
|
%{
|
||||||
int _math_lex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
|
int _math_lex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
|
||||||
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
program:
|
program:
|
||||||
/* empty string */
|
/* empty string */
|
||||||
| program expr END {state->data->push_back($2);}
|
| program expr ';' {state->data->push_back($2);}
|
||||||
;
|
;
|
||||||
|
|
||||||
expr:
|
expr:
|
||||||
@ -68,12 +68,15 @@ expr:
|
|||||||
{$$ = new MathNode($FLOAT, MathNode::Type::cst);}
|
{$$ = new MathNode($FLOAT, MathNode::Type::cst);}
|
||||||
| ID
|
| ID
|
||||||
{$$ = new MathNode($ID,MathNode::Type::var);}
|
{$$ = new MathNode($ID,MathNode::Type::var);}
|
||||||
|
| ID '=' expr
|
||||||
|
{
|
||||||
|
$$ = new MathNode("=", MathNode::Type::op, 2, \
|
||||||
|
new MathNode($ID,MathNode::Type::var), $3);
|
||||||
|
}
|
||||||
| 'r' expr
|
| 'r' expr
|
||||||
{$$ = new MathNode("return", MathNode::Type::keyw, 1, $2);}
|
{$$ = new MathNode("return", MathNode::Type::keyw, 1, $2);}
|
||||||
| '-' expr %prec UMINUS
|
| '-' expr %prec UMINUS
|
||||||
{$$ = new MathNode("-", MathNode::Type::op, 1, $2);}
|
{$$ = new MathNode("-", MathNode::Type::op, 1, $2);}
|
||||||
| expr '=' expr
|
|
||||||
{$$ = new MathNode("=", MathNode::Type::op, 2, $1, $3);}
|
|
||||||
| expr '+' expr
|
| expr '+' expr
|
||||||
{$$ = new MathNode("+", MathNode::Type::op, 2, $1, $3);}
|
{$$ = new MathNode("+", MathNode::Type::op, 2, $1, $3);}
|
||||||
| expr '-' expr
|
| expr '-' expr
|
||||||
@ -86,4 +89,16 @@ expr:
|
|||||||
{$$ = new MathNode("^", MathNode::Type::op, 2, $1, $3);}
|
{$$ = new MathNode("^", MathNode::Type::op, 2, $1, $3);}
|
||||||
| '(' expr ')'
|
| '(' expr ')'
|
||||||
{$$ = $2;}
|
{$$ = $2;}
|
||||||
|
| ID '(' funcargs ')'
|
||||||
|
{$$ = $3; $$->setName($ID);}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
funcargs:
|
||||||
|
/* empty string */
|
||||||
|
{$$ = new MathNode("", MathNode::Type::func);}
|
||||||
|
| expr
|
||||||
|
{$$ = new MathNode("", MathNode::Type::func, 1, $1);}
|
||||||
|
| funcargs ',' expr
|
||||||
|
{$$ = $1; $$->pushArg($3);}
|
||||||
|
;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user