mirror of https://gitlab.com/rnger/amath
1212 lines
27 KiB
C++
Executable File
1212 lines
27 KiB
C++
Executable File
/*
|
|
* Copyright (c) 2015 Carsten Larsen
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "def/libc.h"
|
|
#include "def/text.h"
|
|
#include "lib/numb.h"
|
|
#include "prog/program.h"
|
|
#include "main/values.h"
|
|
#include "main/functions.h"
|
|
#include "main/functiondefs.h"
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------ FunctionNode ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
FunctionNode::FunctionNode(ExpressionNode* expression) :
|
|
ExpressionNode(), expression(expression) { }
|
|
|
|
FunctionNode::~FunctionNode()
|
|
{
|
|
if (expression != NOMEM) {
|
|
delete expression;
|
|
}
|
|
}
|
|
|
|
int FunctionNode::GetPrecedence()
|
|
{
|
|
return 5;
|
|
}
|
|
|
|
char* FunctionNode::GetText()
|
|
{
|
|
const char *functionText = GetNodeText();
|
|
const char *expText = expression->GetText();
|
|
|
|
output->EnsureSize(StrLen(functionText) + StrLen(expText) + 2 + 1);
|
|
output->Empty();
|
|
output->Append(functionText);
|
|
output->Append("(");
|
|
output->Append(expText);
|
|
output->Append(")");
|
|
|
|
return output->GetString();
|
|
}
|
|
|
|
SyntaxNode* FunctionNode::GetNext()
|
|
{
|
|
if (iterator == NOMEM) {
|
|
iterator = expression;
|
|
return expression;
|
|
}
|
|
|
|
return NOMEM;
|
|
}
|
|
|
|
void FunctionNode::Attach(SyntaxNode* node)
|
|
{
|
|
if (expression == NOMEM) {
|
|
expression = (ExpressionNode*)node;
|
|
node->SetParent(this);
|
|
}
|
|
}
|
|
|
|
void FunctionNode::Detach(SyntaxNode* node)
|
|
{
|
|
if (expression == node) {
|
|
expression = NOMEM;
|
|
}
|
|
}
|
|
|
|
void FunctionNode::Replace(SyntaxNode* n, SyntaxNode* x)
|
|
{
|
|
if (expression == n) {
|
|
delete expression;
|
|
expression = (ExpressionNode*)x;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------ UserFunction ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
UserFunction::UserFunction(const char *name, const char *variable, ExpressionNode *expression)
|
|
{
|
|
AllocAndCopy(&this->name, name);
|
|
this->variable = new Variable(variable);
|
|
this->expression = expression;
|
|
this->Next = NOMEM;
|
|
|
|
defname = new CharBuffer();
|
|
defition = new CharBuffer();
|
|
InitializeTexts();
|
|
|
|
chainDelete = true;
|
|
}
|
|
|
|
UserFunction::UserFunction(const char *name)
|
|
{
|
|
AllocAndCopy(&this->name, name);
|
|
this->variable = NOMEM;
|
|
this->expression = NOMEM;
|
|
this->Next = NOMEM;
|
|
|
|
defname = new CharBuffer();
|
|
defition = new CharBuffer();
|
|
|
|
chainDelete = true;
|
|
}
|
|
|
|
UserFunction::~UserFunction()
|
|
{
|
|
delete [] name;
|
|
delete defname;
|
|
delete defition;
|
|
|
|
if (variable != NOMEM) {
|
|
delete variable;
|
|
}
|
|
|
|
if (expression != NOMEM) {
|
|
delete expression;
|
|
}
|
|
|
|
if (chainDelete && Next != NOMEM) {
|
|
delete Next;
|
|
}
|
|
}
|
|
|
|
void UserFunction::InitializeTexts()
|
|
{
|
|
defname->Empty();
|
|
defname->Append(name);
|
|
defname->Append('(');
|
|
defname->Append(variable != NOMEM ? variable->GetName() : EMPTYSTRING);
|
|
defname->Append(')');
|
|
|
|
defition->Empty();
|
|
defition->Append(defname->GetString());
|
|
defition->Append('=');
|
|
defition->Append(expression != NOMEM ? expression->GetText() : EMPTYSTRING);
|
|
}
|
|
|
|
char* UserFunction::GetName()
|
|
{
|
|
return name;
|
|
}
|
|
|
|
char* UserFunction::GetDefitionName()
|
|
{
|
|
return defname->GetString();
|
|
}
|
|
|
|
char* UserFunction::GetDefitionText()
|
|
{
|
|
return defition->GetString();
|
|
}
|
|
|
|
Variable* UserFunction::GetVariable()
|
|
{
|
|
return variable;
|
|
}
|
|
|
|
Variable* UserFunction::CreateVariable(const char *name)
|
|
{
|
|
if(variable != NOMEM) {
|
|
delete variable;
|
|
}
|
|
|
|
variable = new Variable(name);
|
|
InitializeTexts();
|
|
|
|
return variable;
|
|
}
|
|
|
|
ExpressionNode* UserFunction::GetExpression()
|
|
{
|
|
return expression;
|
|
}
|
|
|
|
void UserFunction::SetExpression(ExpressionNode* expression)
|
|
{
|
|
delete this->expression;
|
|
this->expression = expression;
|
|
InitializeTexts();
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ---------------- UserFunctionNode -------------------
|
|
// -----------------------------------------------------
|
|
|
|
UserFunctionNode::UserFunctionNode(UserFunction* function, ExpressionNode* parameter) :
|
|
FunctionNode(parameter), function(function) { }
|
|
|
|
char* UserFunctionNode::GetNodeText()
|
|
{
|
|
return function->GetName();
|
|
}
|
|
|
|
Number* UserFunctionNode::Evaluate()
|
|
{
|
|
// Set value of function parameter and then evaluate function.
|
|
function->GetVariable()->AssignValue(expression->Evaluate());
|
|
return function->GetExpression()->Evaluate();
|
|
}
|
|
|
|
SyntaxNode* UserFunctionNode::GetNext()
|
|
{
|
|
if (iterator == NOMEM) {
|
|
iterator = function->GetExpression();
|
|
return iterator;
|
|
}
|
|
|
|
return NOMEM;
|
|
}
|
|
|
|
void UserFunctionNode::Attach(SyntaxNode* node)
|
|
{
|
|
// TODO: Implement
|
|
}
|
|
|
|
void UserFunctionNode::Detach(SyntaxNode* node)
|
|
{
|
|
// TODO: Implement
|
|
}
|
|
|
|
void UserFunctionNode::Replace(SyntaxNode* n, SyntaxNode* x)
|
|
{
|
|
// TODO: Implement
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// -------------- FunctionDefinitionNode ---------------
|
|
// -----------------------------------------------------
|
|
|
|
FunctionDefinitionNode::FunctionDefinitionNode() :
|
|
StatementNode() {
|
|
output->EnsureMinimumSize();
|
|
output->Empty();
|
|
}
|
|
|
|
char* FunctionDefinitionNode::Execute()
|
|
{
|
|
// TODO: Move function definition logic from parser to here.
|
|
return output->GetString();
|
|
}
|
|
|
|
char* FunctionDefinitionNode::GetText()
|
|
{
|
|
return output->GetString();
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------ FunctionList ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
FunctionList::FunctionList()
|
|
{
|
|
first = NOMEM;
|
|
buf = new CharBuffer();
|
|
}
|
|
|
|
FunctionList::~FunctionList()
|
|
{
|
|
if (first != NOMEM) {
|
|
delete first;
|
|
}
|
|
|
|
delete buf;
|
|
}
|
|
|
|
void FunctionList::Clear()
|
|
{
|
|
if (first != NOMEM) {
|
|
delete first;
|
|
first = NOMEM;
|
|
}
|
|
|
|
buf->ClearBuffer();
|
|
}
|
|
|
|
bool FunctionList::Delete(const char *name, const char *argument)
|
|
{
|
|
if (first == NOMEM)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (first != NOMEM && StrIsEqual(first->GetName(), name) && StrIsEqual(first->GetVariable()->GetName(), argument)) {
|
|
UserFunction *func = first;
|
|
first = first->Next;
|
|
func->chainDelete = false;
|
|
delete func;
|
|
return true;
|
|
}
|
|
|
|
UserFunction *current = first->Next;
|
|
UserFunction *last = first;
|
|
|
|
while (current != NOMEM && !StrIsEqual(current->GetName(), name)) {
|
|
current = current->Next;
|
|
last = last->Next;
|
|
}
|
|
|
|
if (current == NOMEM) {
|
|
return false;
|
|
} else if (!StrIsEqual(current->GetVariable()->GetName(), argument)) {
|
|
return false;
|
|
}
|
|
|
|
last->Next = current->Next;
|
|
|
|
// Only delete this variable. Not the whole chain.
|
|
current->chainDelete = false;
|
|
delete current;
|
|
|
|
return true;
|
|
}
|
|
|
|
UserFunction* FunctionList::GetFirstFunction()
|
|
{
|
|
return first;
|
|
}
|
|
|
|
UserFunction* FunctionList::GetFunctionDef(const char *name)
|
|
{
|
|
// Search the list for function definition. If function not found then create a new definition.
|
|
if (first == NOMEM) {
|
|
first = new UserFunction(name);
|
|
return first;
|
|
}
|
|
|
|
UserFunction *current = first;
|
|
UserFunction *last = NOMEM;
|
|
|
|
while (current != NOMEM) {
|
|
if (StrIsEqual(current->GetName(), name)) {
|
|
return current;
|
|
}
|
|
|
|
last = current;
|
|
current = current->Next;
|
|
}
|
|
|
|
current = new UserFunction(name);
|
|
last->Next = current;
|
|
|
|
return current;
|
|
}
|
|
|
|
UserFunction* FunctionList::GetFunctionDef(const char *name, const char *argument)
|
|
{
|
|
UserFunction *current = first;
|
|
|
|
while (current != NOMEM) {
|
|
if (StrIsEqual(current->GetName(), name) && StrIsEqual(current->GetVariable()->GetName(), argument)) {
|
|
return current;
|
|
}
|
|
|
|
current = current->Next;
|
|
}
|
|
|
|
return NOMEM;
|
|
}
|
|
|
|
FunctionNode* FunctionList::GetFunctionCall(const char *function, ExpressionNode *parameter)
|
|
{
|
|
const functiondef *systemFunction = GetSystemFunction(function);
|
|
if (systemFunction != NOMEM) {
|
|
return (systemFunction->create)(parameter);
|
|
}
|
|
|
|
UserFunction *current = first;
|
|
while (current != NOMEM && !StrIsEqual(current->GetName(), function)) {
|
|
current = current->Next;
|
|
}
|
|
|
|
if (current != NOMEM) {
|
|
return new UserFunctionNode(current, parameter);
|
|
}
|
|
|
|
return NOMEM;
|
|
}
|
|
|
|
char* FunctionList::List()
|
|
{
|
|
return ListContent(false);
|
|
}
|
|
|
|
char* FunctionList::ListDefinitions()
|
|
{
|
|
return ListContent(true);
|
|
}
|
|
|
|
char* FunctionList::ListContent(bool cmdFormat)
|
|
{
|
|
if (first == NOMEM) {
|
|
return (char*)(cmdFormat ? NOMEM : HELPFUNCNDEF);
|
|
}
|
|
|
|
int len = 0;
|
|
UserFunction *current = first;
|
|
|
|
while (current != NOMEM) {
|
|
len += StrLen(current->GetName());
|
|
len += 1;
|
|
len += StrLen(current->GetVariable()->GetName());
|
|
len += 2;
|
|
len += StrLen(current->GetExpression()->GetText());
|
|
len += cmdFormat ? 2 : 1;
|
|
current = current->Next;
|
|
}
|
|
|
|
buf->Empty();
|
|
buf->EnsureSize(len + StrLen(NEWLINE) + 1);
|
|
|
|
current = first;
|
|
while (current != NOMEM) {
|
|
buf->Append(current->GetName());
|
|
buf->Append("(");
|
|
buf->Append(current->GetVariable()->GetName());
|
|
buf->Append(")=");
|
|
buf->Append(current->GetExpression()->GetText());
|
|
|
|
if (cmdFormat) {
|
|
buf->Append(';');
|
|
}
|
|
|
|
buf->Append(NEWLINE);
|
|
current = current->Next;
|
|
}
|
|
|
|
return buf->GetString();
|
|
}
|
|
|
|
bool FunctionList::IsSystemFunction(const char *name)
|
|
{
|
|
return (GetSystemFunction(name) != NOMEM);
|
|
}
|
|
|
|
functiondef* FunctionList::GetSystemFunction(const char *ident)
|
|
{
|
|
static const unsigned int count = sizeof(functiondefs) / sizeof(functiondef);
|
|
for (unsigned int i = 0; i < count; i++) {
|
|
if (StrIsEqual(functiondefs[i].name, ident)) {
|
|
return (functiondef*)&functiondefs[i];
|
|
}
|
|
}
|
|
|
|
return NOMEM;
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// -------------- ListFunctionsStatement ---------------
|
|
// -----------------------------------------------------
|
|
|
|
ListFunctionsStatement::ListFunctionsStatement() :
|
|
StatementNode() { }
|
|
|
|
char* ListFunctionsStatement::Execute()
|
|
{
|
|
return Program->Functions->List();
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------- AbsoluteFunctionNode ----------------
|
|
// -----------------------------------------------------
|
|
|
|
AbsoluteFunctionNode::AbsoluteFunctionNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* AbsoluteFunctionNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new AbsoluteFunctionNode(expression);
|
|
}
|
|
|
|
Number* AbsoluteFunctionNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Absolute();
|
|
return result;
|
|
}
|
|
|
|
char* AbsoluteFunctionNode::GetNodeText()
|
|
{
|
|
return (char*)"abs";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------------- SignumNode --------------------
|
|
// -----------------------------------------------------
|
|
|
|
SignumNode::SignumNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* SignumNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new SignumNode(expression);
|
|
}
|
|
|
|
Number* SignumNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Signum();
|
|
return result;
|
|
}
|
|
|
|
char* SignumNode::GetNodeText()
|
|
{
|
|
return (char*)"sgn";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------------- RoundNode ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
RoundNode::RoundNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* RoundNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new RoundNode(expression);
|
|
}
|
|
|
|
Number* RoundNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Round();
|
|
return result;
|
|
}
|
|
|
|
char* RoundNode::GetNodeText()
|
|
{
|
|
return (char*)"round";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------------- TruncNode ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
TruncNode::TruncNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* TruncNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new TruncNode(expression);
|
|
}
|
|
|
|
Number* TruncNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Trunc();
|
|
return result;
|
|
}
|
|
|
|
char* TruncNode::GetNodeText()
|
|
{
|
|
return (char*)"trunc";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------------- FloorNode ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
FloorNode::FloorNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* FloorNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new FloorNode(expression);
|
|
}
|
|
|
|
Number* FloorNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Floor();
|
|
return result;
|
|
}
|
|
|
|
char* FloorNode::GetNodeText()
|
|
{
|
|
return (char*)"floor";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// -------------------- CeilingNode ---------------------
|
|
// -----------------------------------------------------
|
|
|
|
CeilingNode::CeilingNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* CeilingNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new CeilingNode(expression);
|
|
}
|
|
|
|
Number* CeilingNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Ceiling();
|
|
return result;
|
|
}
|
|
|
|
char* CeilingNode::GetNodeText()
|
|
{
|
|
return (char*)"ceil";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------ SquareRootNode -------------------
|
|
// -----------------------------------------------------
|
|
|
|
SquareRootNode::SquareRootNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* SquareRootNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new SquareRootNode(expression);
|
|
}
|
|
|
|
Number* SquareRootNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->SquareRoot();
|
|
return result;
|
|
}
|
|
|
|
char* SquareRootNode::GetNodeText()
|
|
{
|
|
return (char*)"sqrt";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------- CubeRootNode --------------------
|
|
// -----------------------------------------------------
|
|
|
|
CubeRootNode::CubeRootNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* CubeRootNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new CubeRootNode(expression);
|
|
}
|
|
|
|
Number* CubeRootNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->CubeRoot();
|
|
return result;
|
|
}
|
|
|
|
char* CubeRootNode::GetNodeText()
|
|
{
|
|
return (char*)"cbrt";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// ------------------ BinaryLogFunction ----------------
|
|
// -----------------------------------------------------
|
|
|
|
BinaryLogNode::BinaryLogNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* BinaryLogNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new BinaryLogNode(expression);
|
|
}
|
|
|
|
Number* BinaryLogNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Log2();
|
|
return result;
|
|
}
|
|
|
|
char* BinaryLogNode::GetNodeText()
|
|
{
|
|
return (char*)"lb";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// --------------------- LnRootNode --------------------
|
|
// -----------------------------------------------------
|
|
|
|
LnRootNode::LnRootNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* LnRootNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new LnRootNode(expression);
|
|
}
|
|
|
|
Number* LnRootNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Log();
|
|
return result;
|
|
}
|
|
|
|
char* LnRootNode::GetNodeText()
|
|
{
|
|
return (char*)"ln";
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// -------------------- LogRootNode --------------------
|
|
// -----------------------------------------------------
|
|
|
|
LogNode::LogNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* LogNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new LogNode(expression);
|
|
}
|
|
|
|
Number* LogNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Log10();
|
|
return result;
|
|
}
|
|
|
|
char* LogNode::GetNodeText()
|
|
{
|
|
return (char*)"lg";
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// ----------------------- Trigonometric Functions -------------------------
|
|
// -------------------------------------------------------------------------
|
|
|
|
SineNode::SineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* SineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new SineNode(expression);
|
|
}
|
|
|
|
Number* SineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Sine();
|
|
return result;
|
|
}
|
|
|
|
char* SineNode::GetNodeText()
|
|
{
|
|
return (char*)"sin";
|
|
}
|
|
|
|
CosineNode::CosineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* CosineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new CosineNode(expression);
|
|
}
|
|
|
|
Number* CosineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Cosine();
|
|
return result;
|
|
}
|
|
|
|
char* CosineNode::GetNodeText()
|
|
{
|
|
return (char*)"cos";
|
|
}
|
|
|
|
TangentNode::TangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* TangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new TangentNode(expression);
|
|
}
|
|
|
|
Number* TangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Tangent();
|
|
return result;
|
|
}
|
|
|
|
char* TangentNode::GetNodeText()
|
|
{
|
|
return (char*)"tan";
|
|
}
|
|
|
|
CosecantNode::CosecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* CosecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new CosecantNode(expression);
|
|
}
|
|
|
|
Number* CosecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Cosecant();
|
|
return result;
|
|
}
|
|
|
|
char* CosecantNode::GetNodeText()
|
|
{
|
|
return (char*)"csc";
|
|
}
|
|
|
|
SecantNode::SecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* SecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new SecantNode(expression);
|
|
}
|
|
|
|
Number* SecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Secant();
|
|
return result;
|
|
}
|
|
|
|
char* SecantNode::GetNodeText()
|
|
{
|
|
return (char*)"sec";
|
|
}
|
|
|
|
CotangentNode::CotangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* CotangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new CotangentNode(expression);
|
|
}
|
|
|
|
Number* CotangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->Cotangent();
|
|
return result;
|
|
}
|
|
|
|
char* CotangentNode::GetNodeText()
|
|
{
|
|
return (char*)"cot";
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// -------------------- Inverse Trigonometric Functions --------------------
|
|
// -------------------------------------------------------------------------
|
|
|
|
ArcSineNode::ArcSineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* ArcSineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcSineNode(expression);
|
|
}
|
|
|
|
Number* ArcSineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcSine();
|
|
return result;
|
|
}
|
|
|
|
char* ArcSineNode::GetNodeText()
|
|
{
|
|
return (char*)"asin";
|
|
}
|
|
|
|
ArcCosineNode::ArcCosineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* ArcCosineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcCosineNode(expression);
|
|
}
|
|
|
|
Number* ArcCosineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcCosine();
|
|
return result;
|
|
}
|
|
|
|
char* ArcCosineNode::GetNodeText()
|
|
{
|
|
return (char*)"acos";
|
|
}
|
|
|
|
ArcTangentNode::ArcTangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* ArcTangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcTangentNode(expression);
|
|
}
|
|
|
|
Number* ArcTangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcTangent();
|
|
return result;
|
|
}
|
|
|
|
char* ArcTangentNode::GetNodeText()
|
|
{
|
|
return (char*)"atan";
|
|
}
|
|
|
|
ArcCosecantNode::ArcCosecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* ArcCosecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcCosecantNode(expression);
|
|
}
|
|
|
|
Number* ArcCosecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcCosecant();
|
|
return result;
|
|
}
|
|
|
|
char* ArcCosecantNode::GetNodeText()
|
|
{
|
|
return (char*)"acsc";
|
|
}
|
|
|
|
ArcSecantNode::ArcSecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* ArcSecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcSecantNode(expression);
|
|
}
|
|
|
|
Number* ArcSecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcSecant();
|
|
return result;
|
|
}
|
|
|
|
char* ArcSecantNode::GetNodeText()
|
|
{
|
|
return (char*)"asec";
|
|
}
|
|
|
|
ArcCotangentNode::ArcCotangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
|
|
FunctionNode* ArcCotangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new ArcCotangentNode(expression);
|
|
}
|
|
|
|
Number* ArcCotangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->ArcCotangent();
|
|
return result;
|
|
}
|
|
|
|
char* ArcCotangentNode::GetNodeText()
|
|
{
|
|
return (char*)"acot";
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
// ------------------------- Hyperbolic Functions -------------------------
|
|
// ------------------------------------------------------------------------
|
|
|
|
HyperbolicSineNode::HyperbolicSineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicSineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicSineNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicSineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypSine();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicSineNode::GetNodeText()
|
|
{
|
|
return (char*)"sinh";
|
|
}
|
|
|
|
HyperbolicCosineNode::HyperbolicCosineNode(ExpressionNode* expression)
|
|
: FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicCosineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicCosineNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicCosineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypCosine();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicCosineNode::GetNodeText()
|
|
{
|
|
return (char*)"cosh";
|
|
}
|
|
|
|
HyperbolicTangentNode::HyperbolicTangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicTangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicTangentNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicTangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypTangent();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicTangentNode::GetNodeText()
|
|
{
|
|
return (char*)"tanh";
|
|
}
|
|
|
|
HyperbolicCotangentNode::HyperbolicCotangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicCotangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicCotangentNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicCotangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypCotangent();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicCotangentNode::GetNodeText()
|
|
{
|
|
return (char*)"coth";
|
|
}
|
|
|
|
HyperbolicSecantNode::HyperbolicSecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicSecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicSecantNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicSecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypSecant();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicSecantNode::GetNodeText()
|
|
{
|
|
return (char*)"sech";
|
|
}
|
|
|
|
HyperbolicCosecantNode::HyperbolicCosecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicCosecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicCosecantNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicCosecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypCosecant();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicCosecantNode::GetNodeText()
|
|
{
|
|
return (char*)"csch";
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// --------------------- Inverse Hyperbolic Functions ----------------------
|
|
// -------------------------------------------------------------------------
|
|
|
|
HyperbolicArcsineNode::HyperbolicArcsineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArcsineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArcsineNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArcsineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcSine();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArcsineNode::GetNodeText()
|
|
{
|
|
return (char*)"asinh";
|
|
}
|
|
|
|
HyperbolicArccosineNode::HyperbolicArccosineNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArccosineNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArccosineNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArccosineNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcCosine();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArccosineNode::GetNodeText()
|
|
{
|
|
return (char*)"acosh";
|
|
}
|
|
|
|
HyperbolicArctangentNode::HyperbolicArctangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArctangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArctangentNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArctangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcTangent();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArctangentNode::GetNodeText()
|
|
{
|
|
return (char*)"atanh";
|
|
}
|
|
|
|
HyperbolicArcCotangentNode::HyperbolicArcCotangentNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArcCotangentNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArcCotangentNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArcCotangentNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcCotangent();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArcCotangentNode::GetNodeText()
|
|
{
|
|
return (char*)"acoth";
|
|
}
|
|
|
|
HyperbolicArcSecantNode::HyperbolicArcSecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArcSecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArcSecantNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArcSecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcSecant();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArcSecantNode::GetNodeText()
|
|
{
|
|
return (char*)"asech";
|
|
}
|
|
|
|
HyperbolicArcCosecantNode::HyperbolicArcCosecantNode(ExpressionNode* expression) :
|
|
FunctionNode(expression) { }
|
|
|
|
FunctionNode* HyperbolicArcCosecantNode::Create(ExpressionNode* expression)
|
|
{
|
|
return new HyperbolicArcCosecantNode(expression);
|
|
}
|
|
|
|
Number* HyperbolicArcCosecantNode::Evaluate()
|
|
{
|
|
result = expression->Evaluate()->HypArcCosecant();
|
|
return result;
|
|
}
|
|
|
|
char* HyperbolicArcCosecantNode::GetNodeText()
|
|
{
|
|
return (char*)"acsch";
|
|
}
|