You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
777 lines
24 KiB
777 lines
24 KiB
//=============================================================================
|
|
//
|
|
// File : kvi_kvs_treenode_expression.cpp
|
|
// Creation date : Mon 06 Oct 2003 01.35 CEST by Szymon Stefanek
|
|
//
|
|
// This file is part of the KVirc irc client distribution
|
|
// Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)
|
|
//
|
|
// This program is FREE software. You can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your opinion) any later version.
|
|
//
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
//
|
|
//=============================================================================
|
|
|
|
#define __KVIRC__
|
|
|
|
#include "kvi_kvs_treenode_expression.h"
|
|
#include "kvi_locale.h"
|
|
|
|
#include <math.h>
|
|
|
|
KviKvsTreeNodeExpression::KviKvsTreeNodeExpression(const TQChar * pLocation)
|
|
: KviKvsTreeNodeData(pLocation)
|
|
{
|
|
m_pParentExpression = 0;
|
|
}
|
|
|
|
KviKvsTreeNodeExpression::~KviKvsTreeNodeExpression()
|
|
{
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpression::contextDescription(TQString &szBuffer)
|
|
{
|
|
szBuffer = "Expression Evaluation";
|
|
}
|
|
|
|
void KviKvsTreeNodeExpression::dump(const char * prefix)
|
|
{
|
|
tqDebug("%s Expression",prefix);
|
|
}
|
|
|
|
int KviKvsTreeNodeExpression::precedence()
|
|
{
|
|
return PREC_MAXIMUM;
|
|
}
|
|
|
|
KviKvsTreeNodeExpression * KviKvsTreeNodeExpression::left()
|
|
{
|
|
tqDebug("KviKvsTreeNodeExpression::left() : should never end up here!");
|
|
return 0;
|
|
}
|
|
|
|
KviKvsTreeNodeExpression * KviKvsTreeNodeExpression::right()
|
|
{
|
|
tqDebug("KviKvsTreeNodeExpression::right() : should never end up here!");
|
|
return 0;
|
|
}
|
|
|
|
void KviKvsTreeNodeExpression::setLeft(KviKvsTreeNodeExpression *)
|
|
{
|
|
tqDebug("KviKvsTreeNodeExpression::setLeft() : should never end up here!");
|
|
}
|
|
|
|
void KviKvsTreeNodeExpression::setRight(KviKvsTreeNodeExpression *)
|
|
{
|
|
tqDebug("KviKvsTreeNodeExpression::setRight() : should never end up here!");
|
|
}
|
|
|
|
KviKvsTreeNodeExpression * KviKvsTreeNodeExpression::parentWithPrecedenceLowerThan(int iPrec)
|
|
{
|
|
if(precedence() > iPrec)return this;
|
|
if(!parentExpression())return 0;
|
|
return parentExpression()->parentWithPrecedenceLowerThan(iPrec);
|
|
}
|
|
|
|
int KviKvsTreeNodeExpression::firstBinaryOperator()
|
|
{
|
|
if(!left())return precedence();
|
|
return left()->firstBinaryOperator();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionVariableOperand::KviKvsTreeNodeExpressionVariableOperand(const TQChar * pLocation,KviKvsTreeNodeData * pData)
|
|
: KviKvsTreeNodeExpression(pLocation)
|
|
{
|
|
m_pData = pData;
|
|
m_pData->setParent(this);
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionVariableOperand::~KviKvsTreeNodeExpressionVariableOperand()
|
|
{
|
|
delete m_pData;
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionVariableOperand::contextDescription(TQString &szBuffer)
|
|
{
|
|
szBuffer = "Expression Variable Operand Evaluation";
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionVariableOperand::dump(const char * prefix)
|
|
{
|
|
tqDebug("%s ExpressionVariableOperand",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pData->dump(tmp.utf8().data());
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionVariableOperand::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
return m_pData->evaluateReadOnly(c,pBuffer);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
KviKvsTreeNodeExpressionConstantOperand::KviKvsTreeNodeExpressionConstantOperand(const TQChar * pLocation,KviKvsVariant * pConstant)
|
|
: KviKvsTreeNodeExpression(pLocation)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
m_pConstant = pConstant;
|
|
#endif
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionConstantOperand::~KviKvsTreeNodeExpressionConstantOperand()
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
delete m_pConstant;
|
|
#endif
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionConstantOperand::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Constant Operand Evaluation";
|
|
#endif
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpressionConstantOperand::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionConstantOperand",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pConstant->dump(tmp.utf8().data());
|
|
#endif
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionConstantOperand::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
pBuffer->copyFrom(m_pConstant);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionOperator::KviKvsTreeNodeExpressionOperator(const TQChar * pLocation)
|
|
: KviKvsTreeNodeExpression(pLocation)
|
|
{
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionOperator::~KviKvsTreeNodeExpressionOperator()
|
|
{
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionOperator::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Operator Evaluation";
|
|
#endif
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpressionOperator::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionOperator",prefix);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperator::KviKvsTreeNodeExpressionUnaryOperator(const TQChar * pLocation,KviKvsTreeNodeExpression * pData)
|
|
: KviKvsTreeNodeExpressionOperator(pLocation)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
m_pData = pData;
|
|
m_pData->setParent(this);
|
|
m_pData->setParentExpression(this);
|
|
#endif
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperator::~KviKvsTreeNodeExpressionUnaryOperator()
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
delete m_pData;
|
|
#endif
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperator::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Unary Operator Evaluation";
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperator::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionUnaryOperator",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pData->dump(tmp.utf8().data());
|
|
#endif
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionUnaryOperator::evaluateOperand(KviKvsRunTimeContext * c)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
KviKvsVariant v;
|
|
if(!m_pData->evaluateReadOnly(c,&v))return false;
|
|
|
|
if(!v.asNumber(m_nData))
|
|
{
|
|
c->error(this,__tr2qs("Operand of unary operator didn't evaluate to a number"));
|
|
return false;
|
|
}
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorNegate::KviKvsTreeNodeExpressionUnaryOperatorNegate(const TQChar * pLocation,KviKvsTreeNodeExpression * pData)
|
|
: KviKvsTreeNodeExpressionUnaryOperator(pLocation,pData)
|
|
{
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorNegate::~KviKvsTreeNodeExpressionUnaryOperatorNegate()
|
|
{
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorNegate::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Unary Operator Negate";
|
|
#endif
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorNegate::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionUnaryOperatorNegate",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pData->dump(tmp.utf8().data());
|
|
#endif
|
|
}
|
|
|
|
int KviKvsTreeNodeExpressionUnaryOperatorNegate::precedence()
|
|
{
|
|
return PREC_OP_NEGATE;
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionUnaryOperatorNegate::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
if(!evaluateOperand(c))return false;
|
|
if(m_nData.isReal())pBuffer->setReal(-m_nData.real());
|
|
else pBuffer->setInteger(-m_nData.integer());
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot(const TQChar * pLocation,KviKvsTreeNodeExpression * pData)
|
|
: KviKvsTreeNodeExpressionUnaryOperator(pLocation,pData)
|
|
{
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::~KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot()
|
|
{
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Unary Operator Bitwise Not";
|
|
#endif
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionUnaryOperatorBitwiseNot",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pData->dump(tmp.utf8().data());
|
|
#endif
|
|
}
|
|
|
|
int KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::precedence()
|
|
{
|
|
return PREC_OP_BITWISENOT;
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionUnaryOperatorBitwiseNot::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
if(!evaluateOperand(c))return false;
|
|
if(m_nData.isReal())pBuffer->setInteger(~(int)(m_nData.real()));
|
|
else pBuffer->setInteger(~m_nData.integer());
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::KviKvsTreeNodeExpressionUnaryOperatorLogicalNot(const TQChar * pLocation,KviKvsTreeNodeExpression * pData)
|
|
: KviKvsTreeNodeExpressionUnaryOperator(pLocation,pData)
|
|
{
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::~KviKvsTreeNodeExpressionUnaryOperatorLogicalNot()
|
|
{
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::contextDescription(TQString &szBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
szBuffer = "Expression Unary Operator Logical Not";
|
|
#endif
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::dump(const char * prefix)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
tqDebug("%s ExpressionUnaryOperatorLogicalNot",prefix);
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
m_pData->dump(tmp.utf8().data());
|
|
#endif
|
|
}
|
|
|
|
int KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::precedence()
|
|
{
|
|
return PREC_OP_LOGICALNOT;
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionUnaryOperatorLogicalNot::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
#ifdef COMPILE_NEW_KVS
|
|
KviKvsVariant v;
|
|
if(!m_pData->evaluateReadOnly(c,&v))return false;
|
|
//#warning "FIXME: We could use setNothing() for false and setInteger(1) for true: this would save memory allocations for false conditions"
|
|
pBuffer->setBoolean(!v.asBoolean());
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
KviKvsTreeNodeExpressionBinaryOperator::KviKvsTreeNodeExpressionBinaryOperator(const TQChar * pLocation)
|
|
: KviKvsTreeNodeExpressionOperator(pLocation)
|
|
{
|
|
m_pLeft = 0;
|
|
m_pRight = 0;
|
|
}
|
|
|
|
KviKvsTreeNodeExpressionBinaryOperator::~KviKvsTreeNodeExpressionBinaryOperator()
|
|
{
|
|
if(m_pLeft)delete m_pLeft;
|
|
if(m_pRight)delete m_pRight;
|
|
}
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperator::evaluateOperands(KviKvsRunTimeContext * c)
|
|
{
|
|
KviKvsVariant v1;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!v1.asNumber(m_nLeft))
|
|
{
|
|
c->error(this,__tr2qs("Left operand didn't evaluate to a number"));
|
|
return false;
|
|
}
|
|
KviKvsVariant v2;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
if(!v2.asNumber(m_nRight))
|
|
{
|
|
c->error(this,__tr2qs("Right operand didn't evaluate to a number"));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
KviKvsTreeNodeExpression * KviKvsTreeNodeExpressionBinaryOperator::left()
|
|
{
|
|
return m_pLeft;
|
|
}
|
|
|
|
KviKvsTreeNodeExpression * KviKvsTreeNodeExpressionBinaryOperator::right()
|
|
{
|
|
return m_pRight;
|
|
}
|
|
|
|
int KviKvsTreeNodeExpressionBinaryOperator::firstBinaryOperator()
|
|
{
|
|
return precedence();
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionBinaryOperator::setLeft(KviKvsTreeNodeExpression * pLeft)
|
|
{
|
|
m_pLeft = pLeft;
|
|
m_pLeft->setParent(this);
|
|
m_pLeft->setParentExpression(this);
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionBinaryOperator::setRight(KviKvsTreeNodeExpression * pRight)
|
|
{
|
|
m_pRight = pRight;
|
|
m_pRight->setParent(this);
|
|
m_pRight->setParentExpression(this);
|
|
}
|
|
|
|
|
|
void KviKvsTreeNodeExpressionBinaryOperator::dumpOperands(const char * prefix)
|
|
{
|
|
TQString tmp = prefix;
|
|
tmp.append(" ");
|
|
if(m_pLeft)m_pLeft->dump(tmp.utf8().data());
|
|
if(m_pRight)m_pRight->dump(tmp.utf8().data());
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionBinaryOperator::contextDescription(TQString &szBuffer)
|
|
{
|
|
szBuffer = "Expression Binary Operator";
|
|
}
|
|
|
|
void KviKvsTreeNodeExpressionBinaryOperator::dump(const char * prefix)
|
|
{
|
|
tqDebug("%s ExpressionBinaryOperator",prefix);
|
|
dumpOperands(prefix);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#define PREIMPLEMENT_BINARY_OPERATOR(__name,__stringname,__contextdescription,__precedence) \
|
|
__name::__name(const TQChar * pLocation) \
|
|
: KviKvsTreeNodeExpressionBinaryOperator(pLocation){} \
|
|
__name::~__name(){} \
|
|
void __name::dump(const char * prefix){ tqDebug("%s " __stringname,prefix); dumpOperands(prefix); } \
|
|
void __name::contextDescription(TQString &szBuffer){ szBuffer = __contextdescription; } \
|
|
int __name::precedence(){ return __precedence; };
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorSum,"ExpressionBinaryOperatorSum","Expression Binary Operator \"+\"",PREC_OP_SUM)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorSum::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
if(m_nLeft.isInteger())
|
|
{
|
|
if(m_nRight.isInteger())pBuffer->setInteger(m_nLeft.integer() + m_nRight.integer());
|
|
else pBuffer->setReal(m_nLeft.integer() + m_nRight.real());
|
|
} else {
|
|
if(m_nRight.isInteger())pBuffer->setReal(m_nLeft.real() + m_nRight.integer());
|
|
else pBuffer->setReal(m_nLeft.real() + m_nRight.real());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorSubtraction,"ExpressionBinaryOperatorSubtraction","Expression Binary Operator \"-\"",PREC_OP_SUBTRACTION)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorSubtraction::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
if(m_nLeft.isInteger())
|
|
{
|
|
if(m_nRight.isInteger())pBuffer->setInteger(m_nLeft.integer() - m_nRight.integer());
|
|
else pBuffer->setReal(((kvs_real_t)(m_nLeft.integer())) - m_nRight.real());
|
|
} else {
|
|
if(m_nRight.isInteger())pBuffer->setReal(m_nLeft.real() - ((kvs_real_t)(m_nRight.integer())));
|
|
else pBuffer->setReal(m_nLeft.real() - m_nRight.real());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorMultiplication,"ExpressionBinaryOperatorMultiplication","Expression Binary Operator \"*\"",PREC_OP_MULTIPLICATION)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorMultiplication::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
if(m_nLeft.isInteger())
|
|
{
|
|
if(m_nRight.isInteger())pBuffer->setInteger(m_nLeft.integer() * m_nRight.integer());
|
|
else pBuffer->setReal(((kvs_real_t)(m_nLeft.integer())) * m_nRight.real());
|
|
} else {
|
|
if(m_nRight.isInteger())pBuffer->setReal(m_nLeft.real() * ((kvs_real_t)(m_nRight.integer())));
|
|
else pBuffer->setReal(m_nLeft.real() * m_nRight.real());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorDivision,"ExpressionBinaryOperatorDivision","Expression Binary Operator \"/\"",PREC_OP_DIVISION)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorDivision::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
|
|
if(m_nRight.isInteger())
|
|
{
|
|
if(m_nRight.integer() == 0)
|
|
{
|
|
c->error(this,__tr2qs("Division by zero"));
|
|
return false;
|
|
}
|
|
if(m_nLeft.isInteger())pBuffer->setInteger(m_nLeft.integer() / m_nRight.integer());
|
|
else pBuffer->setReal(m_nLeft.real() / ((kvs_real_t)(m_nRight.integer())));
|
|
} else {
|
|
if(m_nRight.real() == 0.0)
|
|
{
|
|
c->error(this,__tr2qs("Division by zero"));
|
|
return false;
|
|
}
|
|
if(m_nLeft.isInteger())pBuffer->setReal(((kvs_real_t)(m_nLeft.integer())) / m_nRight.real());
|
|
else pBuffer->setReal(m_nLeft.real() / m_nRight.real());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorModulus,"ExpressionBinaryOperatorModulus","Expression Binary Operator \"modulus\"",PREC_OP_MODULUS)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorModulus::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
|
|
if(m_nRight.isInteger())
|
|
{
|
|
if(m_nRight.integer() == 0)
|
|
{
|
|
c->error(this,__tr2qs("Division by zero"));
|
|
return false;
|
|
}
|
|
if(m_nLeft.isInteger())pBuffer->setInteger(m_nLeft.integer() % m_nRight.integer());
|
|
else pBuffer->setReal(fmod(m_nLeft.real(),((kvs_real_t)(m_nRight.integer()))));
|
|
} else {
|
|
if(m_nRight.real() == 0.0)
|
|
{
|
|
c->error(this,__tr2qs("Division by zero"));
|
|
return false;
|
|
}
|
|
if(m_nLeft.isInteger())pBuffer->setReal(fmod(((kvs_real_t)(m_nLeft.integer())),m_nRight.real()));
|
|
else pBuffer->setReal(fmod(m_nLeft.real(),m_nRight.real()));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorBitwiseAnd,"ExpressionBinaryOperatorBitwiseAnd","Expression Binary Operator \"&\"",PREC_OP_BITWISEAND)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorBitwiseAnd::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
int iLeft = m_nLeft.isInteger() ? m_nLeft.integer() : (kvs_int_t)m_nLeft.real();
|
|
int iRight = m_nRight.isInteger() ? m_nRight.integer() : (kvs_int_t)m_nRight.real();
|
|
pBuffer->setInteger(iLeft & iRight);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorBitwiseOr,"ExpressionBinaryOperatorBitwiseOr","Expression Binary Operator \"|\"",PREC_OP_BITWISEOR)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorBitwiseOr::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
int iLeft = m_nLeft.isInteger() ? m_nLeft.integer() : (kvs_int_t)m_nLeft.real();
|
|
int iRight = m_nRight.isInteger() ? m_nRight.integer() : (kvs_int_t)m_nRight.real();
|
|
pBuffer->setInteger(iLeft | iRight);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorBitwiseXor,"ExpressionBinaryOperatorBitwiseXor","Expression Binary Operator \"^\"",PREC_OP_BITWISEXOR)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorBitwiseXor::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
int iLeft = m_nLeft.isInteger() ? m_nLeft.integer() : (kvs_int_t)m_nLeft.real();
|
|
int iRight = m_nRight.isInteger() ? m_nRight.integer() : (kvs_int_t)m_nRight.real();
|
|
pBuffer->setInteger(iLeft ^ iRight);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorShiftLeft,"ExpressionBinaryOperatorShiftLeft","Expression Binary Operator \"<<\"",PREC_OP_SHIFTLEFT)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorShiftLeft::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
int iLeft = m_nLeft.isInteger() ? m_nLeft.integer() : (kvs_int_t)(m_nLeft.real());
|
|
int iRight = m_nRight.isInteger() ? m_nRight.integer() : (kvs_int_t)(m_nRight.real());
|
|
pBuffer->setInteger(iLeft << iRight);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorShiftRight,"ExpressionBinaryOperatorShiftRight","Expression Binary Operator \">>\"",PREC_OP_SHIFTRIGHT)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorShiftRight::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
if(!evaluateOperands(c))return false;
|
|
int iLeft = m_nLeft.isInteger() ? m_nLeft.integer() : (kvs_int_t)(m_nLeft.real());
|
|
int iRight = m_nRight.isInteger() ? m_nRight.integer() : (kvs_int_t)(m_nRight.real());
|
|
pBuffer->setInteger(iLeft >> iRight);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorAnd,"ExpressionBinaryOperatorAnd","Expression Binary Operator \"&&\"",PREC_OP_AND)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorAnd::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
//#warning "FIXME: We could use setNothing() as false: this would save memory allocations (and thus time)"
|
|
if(!v1.asBoolean())
|
|
{
|
|
pBuffer->setBoolean(false);
|
|
return true;
|
|
}
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v2.asBoolean());
|
|
return true;
|
|
}
|
|
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorOr,"ExpressionBinaryOperatorOr","Expression Binary Operator \"||\"",PREC_OP_OR)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorOr::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
//#warning "FIXME: We could use setNothing() as false: this would save memory allocations (and thus time)"
|
|
if(v1.asBoolean())
|
|
{
|
|
pBuffer->setBoolean(true);
|
|
return true;
|
|
}
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v2.asBoolean());
|
|
return true;
|
|
}
|
|
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorXor,"ExpressionBinaryOperatorXor","Expression Binary Operator \"^^\"",PREC_OP_XOR)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorXor::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
//#warning "FIXME: We could use setNothing() as false: this would save memory allocations (and thus time)"
|
|
if(v1.asBoolean())
|
|
pBuffer->setBoolean(!v2.asBoolean());
|
|
else {
|
|
if(v2.asBoolean())
|
|
pBuffer->setBoolean(!v1.asBoolean());
|
|
else
|
|
pBuffer->setBoolean(false);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorLowerThan,"ExpressionBinaryOperatorLowerThan","Expression Binary Operator \"<\"",PREC_OP_LOWERTHAN)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorLowerThan::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) > 0);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorGreaterThan,"ExpressionBinaryOperatorGreaterThan","Expression Binary Operator \">\"",PREC_OP_GREATERTHAN)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorGreaterThan::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) < 0);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorLowerOrEqualTo,"ExpressionBinaryOperatorLowerOrEqualTo","Expression Binary Operator \"<=\"",PREC_OP_LOWEROREQUALTO)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorLowerOrEqualTo::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) >= 0);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorGreaterOrEqualTo,"ExpressionBinaryOperatorGreaterOrEqualTo","Expression Binary Operator \">=\"",PREC_OP_GREATEROREQUALTO)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorGreaterOrEqualTo::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) <= 0);
|
|
return true;
|
|
}
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorEqualTo,"ExpressionBinaryOperatorEqualTo","Expression Binary Operator \"==\"",PREC_OP_EQUALTO)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorEqualTo::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) == 0);
|
|
return true;
|
|
}
|
|
|
|
|
|
PREIMPLEMENT_BINARY_OPERATOR(KviKvsTreeNodeExpressionBinaryOperatorNotEqualTo,"ExpressionBinaryOperatorNotEqualTo","Expression Binary Operator \"!=\"",PREC_OP_NOTEQUALTO)
|
|
|
|
bool KviKvsTreeNodeExpressionBinaryOperatorNotEqualTo::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer)
|
|
{
|
|
KviKvsVariant v1;
|
|
KviKvsVariant v2;
|
|
if(!m_pLeft->evaluateReadOnly(c,&v1))return false;
|
|
if(!m_pRight->evaluateReadOnly(c,&v2))return false;
|
|
pBuffer->setBoolean(v1.compare(&v2,true) != 0);
|
|
return true;
|
|
}
|