mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 16:57:31 +01:00
[poincare] Enable functions with more than one argument
Change-Id: I543594072c37716fffcc54d5d6ba9b6b3499bcd1
This commit is contained in:
@@ -10,14 +10,15 @@ class Function : public Expression {
|
||||
public:
|
||||
Function(const char * name);
|
||||
~Function();
|
||||
void setArgument(Expression * arg, bool clone = true);
|
||||
void setArgument(Expression ** args, int numberOfArguments, bool clone = true);
|
||||
ExpressionLayout * createLayout() const override;
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * clone() const override;
|
||||
Expression * evaluate(Context& context) const override;
|
||||
protected:
|
||||
const Expression * m_arg;
|
||||
Expression ** m_args;
|
||||
int m_numberOfArguments;
|
||||
private:
|
||||
const char * m_name;
|
||||
};
|
||||
|
||||
@@ -18,11 +18,11 @@ Expression * AbsoluteValue::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
AbsoluteValue * c = new AbsoluteValue();
|
||||
c->setArgument(*newOperands, cloneOperands);
|
||||
return c;
|
||||
AbsoluteValue * a = new AbsoluteValue();
|
||||
a->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return a;
|
||||
}
|
||||
|
||||
float AbsoluteValue::approximate(Context& context) const {
|
||||
return fabsf(m_arg->approximate(context));
|
||||
return fabsf(m_args[0]->approximate(context));
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ Expression * Cosine::cloneWithDifferentOperands(Expression** newOperands,
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
Cosine * c = new Cosine();
|
||||
c->setArgument(*newOperands, cloneOperands);
|
||||
c->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return c;
|
||||
}
|
||||
|
||||
float Cosine::approximate(Context& context) const {
|
||||
return cosf(m_arg->approximate(context));
|
||||
return cosf(m_args[0]->approximate(context));
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ exp:
|
||||
| exp POW exp { Expression * terms[2] = {$1,$3}; $$ = new Power(terms, false); }
|
||||
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Parenthesis($2, false); }
|
||||
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Matrix($2); }
|
||||
| FUNCTION LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = $1; $1->setArgument($3, false); }
|
||||
| FUNCTION LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = $1; Expression * terms[1] = {$3}; $1->setArgument(terms, 1, false); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
@@ -8,48 +8,65 @@ extern "C" {
|
||||
#include "layout/string_layout.h"
|
||||
|
||||
Function::Function(const char * name) :
|
||||
m_arg(nullptr),
|
||||
m_args(nullptr),
|
||||
m_numberOfArguments(0),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void Function::setArgument(Expression * arg, bool clone) {
|
||||
if (m_arg != nullptr) {
|
||||
delete m_arg;
|
||||
void Function::setArgument(Expression ** args, int numberOfArguments, bool clone) {
|
||||
if (m_args != nullptr) {
|
||||
for (int i = 0; i < m_numberOfArguments; i++) {
|
||||
delete m_args[i];
|
||||
}
|
||||
free(m_args);
|
||||
}
|
||||
if (clone) {
|
||||
m_arg = arg->clone();
|
||||
} else {
|
||||
m_arg = arg;
|
||||
m_numberOfArguments = numberOfArguments;
|
||||
m_args = (Expression **)malloc(numberOfArguments*sizeof(Expression *));
|
||||
for (int i = 0; i < numberOfArguments; i++) {
|
||||
assert(args[i] != nullptr);
|
||||
if (clone) {
|
||||
m_args[i] = args[i]->clone();
|
||||
} else {
|
||||
m_args[i] = args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function::~Function() {
|
||||
if (m_arg != nullptr) {
|
||||
delete m_arg;
|
||||
if (m_args != nullptr) {
|
||||
for (int i = 0; i < m_numberOfArguments; i++) {
|
||||
delete m_args[i];
|
||||
}
|
||||
free(m_args);
|
||||
}
|
||||
}
|
||||
|
||||
Expression * Function::clone() const {
|
||||
return this->cloneWithDifferentOperands((Expression**)&m_arg, 1, true);
|
||||
return this->cloneWithDifferentOperands(m_args, m_numberOfArguments, true);
|
||||
}
|
||||
|
||||
ExpressionLayout * Function::createLayout() const {
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc(4*sizeof(ExpressionLayout *));
|
||||
ExpressionLayout ** childrenLayouts = (ExpressionLayout **)malloc((2*m_numberOfArguments+2)*sizeof(ExpressionLayout *));
|
||||
childrenLayouts[0] = new StringLayout(m_name, strlen(m_name));
|
||||
childrenLayouts[1] = new StringLayout("(", 1);
|
||||
childrenLayouts[2] = m_arg->createLayout();
|
||||
childrenLayouts[3] = new StringLayout(")", 1);
|
||||
return new HorizontalLayout(childrenLayouts, 4);
|
||||
int layoutIndex = 2;
|
||||
childrenLayouts[layoutIndex++] = m_args[0]->createLayout();
|
||||
for (int i = 1; i < m_numberOfArguments; i++) {
|
||||
childrenLayouts[layoutIndex++] = new StringLayout(",", 1);
|
||||
childrenLayouts[layoutIndex++] = m_args[i]->createLayout();
|
||||
}
|
||||
childrenLayouts[layoutIndex] = new StringLayout(")", 1);
|
||||
return new HorizontalLayout(childrenLayouts, 2*m_numberOfArguments+2);
|
||||
}
|
||||
|
||||
const Expression * Function::operand(int i) const {
|
||||
assert(i==0);
|
||||
return m_arg;
|
||||
assert(i >= 0 && i < m_numberOfArguments);
|
||||
return m_args[i];
|
||||
}
|
||||
|
||||
int Function::numberOfOperands() const {
|
||||
return 1;
|
||||
return m_numberOfArguments;
|
||||
}
|
||||
|
||||
Expression * Function::evaluate(Context& context) const {
|
||||
|
||||
@@ -17,11 +17,11 @@ Expression * Logarithm::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(numberOfOperands == 1);
|
||||
assert(newOperands != nullptr);
|
||||
Logarithm * c = new Logarithm();
|
||||
c->setArgument(*newOperands, cloneOperands);
|
||||
return c;
|
||||
Logarithm * l = new Logarithm();
|
||||
l->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return l;
|
||||
}
|
||||
|
||||
float Logarithm::approximate(Context& context) const {
|
||||
return log10f(m_arg->approximate(context));
|
||||
return log10f(m_args[0]->approximate(context));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Expression * Sine::cloneWithDifferentOperands(Expression** newOperands,
|
||||
assert(newOperands != nullptr);
|
||||
assert(numberOfOperands == 1);
|
||||
Sine * s = new Sine();
|
||||
s->setArgument(*newOperands, cloneOperands);
|
||||
s->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ Expression::Type Sine::type() const {
|
||||
}
|
||||
|
||||
float Sine::approximate(Context& context) const {
|
||||
return sinf(m_arg->approximate(context));
|
||||
return sinf(m_args[0]->approximate(context));
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Expression * Tangent::cloneWithDifferentOperands(Expression** newOperands,
|
||||
assert(newOperands != nullptr);
|
||||
assert(numberOfOperands == 1);
|
||||
Tangent * t = new Tangent();
|
||||
t->setArgument(*newOperands, cloneOperands);
|
||||
t->setArgument(newOperands, numberOfOperands, cloneOperands);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -24,5 +24,5 @@ Expression::Type Tangent::type() const {
|
||||
}
|
||||
|
||||
float Tangent::approximate(Context& context) const {
|
||||
return tanf(m_arg->approximate(context));
|
||||
return tanf(m_args[0]->approximate(context));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user