748 lines
19 KiB
C++
748 lines
19 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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 3 of the License, or
|
|
* (at your option) 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "bagel/spacebar/baglib/expression.h"
|
|
#include "bagel/spacebar/baglib/master_win.h"
|
|
#include "bagel/spacebar/baglib/storage_dev_win.h"
|
|
#include "bagel/spacebar/baglib/sound_object.h"
|
|
#include "bagel/boflib/sound.h"
|
|
#include "bagel/bagel.h"
|
|
|
|
namespace Bagel {
|
|
namespace SpaceBar {
|
|
|
|
CBagVar *CBagExpression::_tempVar; // Used as a default param
|
|
|
|
void CBagExpression::initialize() {
|
|
// used as a default param
|
|
_tempVar = new CBagVar("CBagExpr::TempVar", "", false);
|
|
}
|
|
|
|
void CBagExpression::shutdown() {
|
|
delete _tempVar;
|
|
}
|
|
|
|
CBagExpression::CBagExpression(CBagExpression *prevExpr, bool prevNegFl) {
|
|
_negativeFl = false;
|
|
_prevExpression = prevExpr;
|
|
_prevNegativeFl = prevNegFl;
|
|
}
|
|
|
|
CBagExpression::~CBagExpression() {
|
|
}
|
|
|
|
bool CBagExpression::evaluate(CBagVar *leftHandOper, CBagVar *rightHandOper, OPERATION oper, CBagVar &result) {
|
|
bool retVal = false;
|
|
|
|
// If the variable is named "RANDOM", generate a random number for its value
|
|
if (leftHandOper->getName() == "RANDOM")
|
|
leftHandOper->setValue(g_engine->getRandomNumber());
|
|
if (rightHandOper->getName() == "RANDOM")
|
|
rightHandOper->setValue(g_engine->getRandomNumber());
|
|
|
|
switch (oper) {
|
|
case OP_NONE:
|
|
break;
|
|
|
|
case OP_ASSIGN:
|
|
retVal = onAssign(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_EQUAL:
|
|
retVal = onEqual(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_NOT_EQUAL:
|
|
retVal = onNotEqual(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_LESS_THAN:
|
|
retVal = onLessThan(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_LESS_THAN_EQUAL:
|
|
retVal = onLessThanEqual(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_GREATER_THAN:
|
|
retVal = onGreaterThan(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_GREATER_THAN_EQUAL:
|
|
retVal = onGreaterThanEqual(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_PLUS_ASSIGN:
|
|
retVal = onPlusAssign(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_MINUS_ASSIGN:
|
|
retVal = onMinusAssign(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_PLUS:
|
|
retVal = onPlus(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_MINUS:
|
|
retVal = onMinus(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_MULTIPLY:
|
|
retVal = onMultiply(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_DIVIDE:
|
|
retVal = onDivide(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_MOD:
|
|
retVal = onMod(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_CONTAINS:
|
|
retVal = onContains(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_HAS:
|
|
retVal = onHas(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
case OP_STATUS:
|
|
retVal = onStatus(leftHandOper, rightHandOper, result);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
CBagVar *CBagExpression::getVariable(int itemPos) {
|
|
CBagVar *curVar = _varList.getNodeItem(itemPos);
|
|
|
|
// If the variable is a reference (OBJ.PROPERTY)
|
|
if (curVar->isReference()) {
|
|
char frontStr[256];
|
|
Common::strcpy_s(frontStr, curVar->getName());
|
|
|
|
char *p = strstr(frontStr, "~~");
|
|
if (p != nullptr) {
|
|
char backStr[256];
|
|
Common::strcpy_s(backStr, p + 2);
|
|
*p = '\0';
|
|
|
|
const CBofString stringObject(frontStr, 256);
|
|
const CBofString stringProperty(backStr, 256);
|
|
|
|
const int newVal = g_SDevManager->getObjectValue(stringObject, stringProperty);
|
|
curVar->setValue(newVal);
|
|
}
|
|
}
|
|
|
|
return curVar;
|
|
}
|
|
|
|
|
|
CBagExpression::OPERATION CBagExpression::getOperation(int itemPos) {
|
|
assert(false);
|
|
return _operList.getNodeItem(itemPos);
|
|
}
|
|
|
|
|
|
bool CBagExpression::evaluate(bool negFl, CBagVar &result) {
|
|
bool retVal = false;
|
|
|
|
// There must be an expression for every variable after the first
|
|
assert(_varList.getCount() - 1 == _operList.getCount());
|
|
|
|
int count = 0;
|
|
|
|
CBagVar *leftHandOper = getVariable(count++);
|
|
result = *leftHandOper;
|
|
|
|
bool parentCheckFl = true;
|
|
if (_prevExpression) {
|
|
parentCheckFl = _prevExpression->evaluate(_prevNegativeFl, result);
|
|
}
|
|
|
|
if (parentCheckFl) {
|
|
bool subValFl;
|
|
int nodeCount = 0;
|
|
|
|
while (count < _varList.getCount()) {
|
|
CBagVar *rightHandOper = getVariable(count++);
|
|
OPERATION oper = _operList.getNodeItem(nodeCount++);
|
|
CBagVar *rightHandOper2;
|
|
|
|
switch (oper) {
|
|
case OP_AND:
|
|
rightHandOper2 = getVariable(count++);
|
|
oper = _operList.getNodeItem(nodeCount++);
|
|
subValFl = evaluate(rightHandOper, rightHandOper2, oper, result);
|
|
|
|
retVal &= subValFl;
|
|
break;
|
|
|
|
case OP_OR:
|
|
rightHandOper2 = getVariable(count++);
|
|
oper = _operList.getNodeItem(nodeCount++);
|
|
subValFl = evaluate(rightHandOper, rightHandOper2, oper, result);
|
|
|
|
retVal |= subValFl;
|
|
break;
|
|
|
|
default:
|
|
retVal = evaluate(leftHandOper, rightHandOper, oper, result);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (negFl)
|
|
// Evaluate before and with parent
|
|
retVal = !retVal;
|
|
|
|
retVal &= parentCheckFl;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
bool CBagExpression::evalLeftToRight(bool negFl, CBagVar &result) {
|
|
bool retVal = false;
|
|
OPERATION oper = OP_NONE;
|
|
|
|
// There must be an expression for every variable after the first
|
|
assert(_varList.getCount() - 1 == _operList.getCount());
|
|
|
|
int varCount = 0;
|
|
|
|
CBagVar *leftHandOper = getVariable(varCount++);
|
|
result = *leftHandOper;
|
|
|
|
bool parentCheckFl = true;
|
|
if (_prevExpression) {
|
|
parentCheckFl = _prevExpression->evaluate(_prevNegativeFl, result);
|
|
}
|
|
|
|
if (parentCheckFl) {
|
|
bool bFirstTime = true;
|
|
int nodeCount = 0;
|
|
while (varCount < _varList.getCount()) {
|
|
CBagVar compLeftHandOper;
|
|
CBagVar *rightHandOper = getVariable(varCount++);
|
|
const OPERATION prevOper = oper; // save previous operator
|
|
oper = _operList.getNodeItem(nodeCount++);
|
|
|
|
if (bFirstTime) {
|
|
compLeftHandOper = *leftHandOper;
|
|
bFirstTime = false;
|
|
} else {
|
|
// Based on what we have for a previous operator, either use
|
|
// the left hand expression or the result of the previous expression.
|
|
switch (prevOper) {
|
|
case OP_MINUS:
|
|
case OP_MULTIPLY:
|
|
case OP_DIVIDE:
|
|
case OP_MOD:
|
|
case OP_PLUS:
|
|
compLeftHandOper = result;
|
|
break;
|
|
case OP_NONE:
|
|
case OP_ASSIGN:
|
|
case OP_EQUAL:
|
|
case OP_NOT_EQUAL:
|
|
case OP_LESS_THAN:
|
|
case OP_LESS_THAN_EQUAL:
|
|
case OP_GREATER_THAN:
|
|
case OP_GREATER_THAN_EQUAL:
|
|
case OP_PLUS_ASSIGN:
|
|
case OP_MINUS_ASSIGN:
|
|
case OP_CONTAINS:
|
|
case OP_HAS:
|
|
case OP_STATUS:
|
|
default:
|
|
compLeftHandOper = *leftHandOper;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool boolVal;
|
|
CBagVar *rightHandOper2;
|
|
switch (oper) {
|
|
|
|
case OP_AND:
|
|
rightHandOper2 = getVariable(varCount++);
|
|
oper = _operList.getNodeItem(nodeCount++);
|
|
boolVal = evaluate(rightHandOper, rightHandOper2, oper, result);
|
|
|
|
retVal &= boolVal;
|
|
break;
|
|
|
|
case OP_OR:
|
|
rightHandOper2 = getVariable(varCount++);
|
|
oper = _operList.getNodeItem(nodeCount++);
|
|
boolVal = evaluate(rightHandOper, rightHandOper2, oper, result);
|
|
|
|
// or this don't not it!!!
|
|
retVal |= boolVal;
|
|
break;
|
|
|
|
default:
|
|
retVal = evaluate(&compLeftHandOper, rightHandOper, oper, result);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (negFl)
|
|
// Evaluate before and with parent
|
|
retVal = !retVal;
|
|
|
|
retVal &= parentCheckFl;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::negEvaluate(CBagVar &result) {
|
|
return evaluate(false, result);
|
|
}
|
|
|
|
|
|
bool CBagExpression::onAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused*/) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
char buffer[256];
|
|
Common::strcpy_s(buffer, rightHandOper->getValue());
|
|
assert(strlen(buffer) < 256);
|
|
const CBofString newLeftHandValue(buffer, 256);
|
|
|
|
leftHandOper->setValue(newLeftHandValue);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
const bool retVal = leftHandOper->getValue() == rightHandOper->getValue();
|
|
resultOper.setBoolValue(retVal);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onNotEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
const bool retVal = leftHandOper->getValue() != rightHandOper->getValue();
|
|
resultOper.setBoolValue(retVal);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onLessThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
const bool retVal = leftHandOper->getNumValue() < rightHandOper->getNumValue();
|
|
resultOper.setBoolValue(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onGreaterThan(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
const bool retVal = leftHandOper->getNumValue() > rightHandOper->getNumValue();
|
|
resultOper.setBoolValue(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onLessThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
const bool retVal = leftHandOper->getNumValue() <= rightHandOper->getNumValue();
|
|
resultOper.setBoolValue(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onGreaterThanEqual(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
const bool retVal = leftHandOper->getNumValue() >= rightHandOper->getNumValue();
|
|
resultOper.setBoolValue(retVal);
|
|
return retVal;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onPlusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
leftHandOper->setValue(leftHandNum + rightHandNum);
|
|
resultOper.setValue(leftHandOper->getNumValue());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onMinusAssign(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
leftHandOper->setValue(leftHandNum - rightHandNum);
|
|
resultOper.setValue(leftHandOper->getNumValue());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onContains(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
CBagStorageDev *sDev = g_SDevManager->getStorageDevice(leftHandOper->getValue());
|
|
if (sDev == nullptr)
|
|
return false;
|
|
|
|
CBagObject *curObj = sDev->getObject(rightHandOper->getValue());
|
|
if ((curObj != nullptr) && curObj->isActive())
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CBagExpression::onHas(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
CBagStorageDev *sDev = g_SDevManager->getStorageDevice(leftHandOper->getValue());
|
|
if (sDev == nullptr)
|
|
return false;
|
|
|
|
CBagObject *curObj = sDev->getObjectByType(rightHandOper->getValue(), true);
|
|
if (curObj == nullptr)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CBagExpression::onStatus(CBagVar *pLHOper, CBagVar * /* rightHandOper, unused */, CBagVar & /* resultOper, unused */) {
|
|
assert(pLHOper != nullptr);
|
|
|
|
CBagStorageDev *sDev = g_SDevManager->getStorageDeviceContaining(pLHOper->getValue());
|
|
if (sDev == nullptr)
|
|
return false;
|
|
|
|
CBagObject *curObj = sDev->getObject(pLHOper->getValue());
|
|
if (curObj == nullptr)
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
bool CBagExpression::onCurrSDev(CBagVar * /* leftHandOper, unused*/, CBagVar * /* rightHandOper, unused */, CBagVar & /* resultOper, unused */) {
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onPlus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
resultOper.setValue(leftHandNum + rightHandNum);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onMinus(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
resultOper.setValue(leftHandNum - rightHandNum);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onMultiply(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
|
|
resultOper.setValue(leftHandNum * rightHandNum);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onDivide(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
|
|
// Divide by Zero error?
|
|
assert(rightHandNum != 0);
|
|
|
|
resultOper.setValue(leftHandNum / rightHandNum);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onMod(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar &resultOper) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
if (leftHandOper->isNumeric() && rightHandOper->isNumeric()) {
|
|
const int leftHandNum = leftHandOper->getNumValue();
|
|
const int rightHandNum = rightHandOper->getNumValue();
|
|
|
|
// Divide by Zero error?
|
|
assert(rightHandNum != 0);
|
|
|
|
resultOper.setValue(leftHandNum % rightHandNum);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CBagExpression::onAnd(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
return (!leftHandOper->getValue().find("true") && !rightHandOper->getValue().find("true"));
|
|
}
|
|
|
|
|
|
bool CBagExpression::onOr(CBagVar *leftHandOper, CBagVar *rightHandOper, CBagVar & /* resultOper, unused */) {
|
|
assert((leftHandOper != nullptr) && (rightHandOper != nullptr));
|
|
|
|
return (!leftHandOper->getValue().find("true") || !rightHandOper->getValue().find("true"));
|
|
}
|
|
|
|
|
|
ParseCodes CBagExpression::setInfo(CBagIfstream &istr) {
|
|
char buffer[256];
|
|
buffer[0] = 0;
|
|
CBofString tmpStr(buffer, 256);
|
|
|
|
ParseCodes parseCode = PARSING_DONE;
|
|
bool doneFl = false;
|
|
|
|
while (!doneFl && parseCode == PARSING_DONE) {
|
|
istr.eatWhite();
|
|
int ch = istr.peek();
|
|
switch (ch) {
|
|
case '(': {
|
|
istr.getCh();
|
|
istr.eatWhite();
|
|
|
|
getAlphaNumFromStream(istr, tmpStr);
|
|
CBagVar *curVar = g_VarManager->getVariable(tmpStr);
|
|
if (!curVar) {
|
|
// This must be a reference, make a new variable
|
|
if (tmpStr.find("~~") > 0) {
|
|
curVar = new CBagVar;
|
|
curVar->setName(tmpStr);
|
|
curVar->setReference();
|
|
} else {
|
|
// This is an error condition, constants can only be rhopers
|
|
curVar = new CBagVar;
|
|
curVar->setName(tmpStr);
|
|
curVar->setValue(tmpStr);
|
|
curVar->setConstant();
|
|
}
|
|
}
|
|
_varList.addToTail(curVar);
|
|
|
|
istr.eatWhite();
|
|
ch = istr.peek();
|
|
while ((ch != ')') && parseCode == PARSING_DONE) {
|
|
OPERATION curOper;
|
|
getOperatorFromStream(istr, curOper);
|
|
if (curOper == OP_NONE) {
|
|
parseCode = UNKNOWN_TOKEN;
|
|
break;
|
|
}
|
|
_operList.addToTail(curOper);
|
|
|
|
istr.eatWhite();
|
|
getAlphaNumFromStream(istr, tmpStr);
|
|
curVar = g_VarManager->getVariable(tmpStr);
|
|
if (!curVar) {
|
|
if (tmpStr.find("~~") > 0) {
|
|
// This must be a reference, make a new variable
|
|
curVar = new CBagVar;
|
|
curVar->setName(tmpStr);
|
|
curVar->setReference();
|
|
} else {
|
|
// This must be a constant, make a new variable
|
|
curVar = new CBagVar;
|
|
curVar->setName(tmpStr);
|
|
curVar->setValue(tmpStr);
|
|
curVar->setConstant();
|
|
}
|
|
}
|
|
_varList.addToTail(curVar);
|
|
|
|
istr.eatWhite();
|
|
ch = istr.peek();
|
|
} // while parsing inner circle
|
|
|
|
if (ch == ')') {
|
|
istr.getCh();
|
|
doneFl = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 'N':
|
|
getAlphaNumFromStream(istr, tmpStr);
|
|
if (!tmpStr.find("NOT")) {
|
|
_negativeFl = !_negativeFl;
|
|
istr.eatWhite();
|
|
break;
|
|
}
|
|
// FIXME: Is this intentional?
|
|
// fallthrough
|
|
default:
|
|
parseCode = UNKNOWN_TOKEN;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (parseCode != PARSING_DONE) {
|
|
parseAlertBox(istr, "Error in expression:", __FILE__, __LINE__);
|
|
}
|
|
|
|
istr.eatWhite();
|
|
|
|
return parseCode;
|
|
}
|
|
|
|
|
|
ErrorCode CBagExpression::getOperatorFromStream(CBagIfstream &istr, OPERATION &oper) {
|
|
ErrorCode errorCode = ERR_NONE;
|
|
|
|
char localBuff[256];
|
|
localBuff[0] = 0;
|
|
|
|
CBofString localStr(localBuff, 256);
|
|
|
|
oper = OP_NONE;
|
|
|
|
istr.eatWhite();
|
|
getOperStrFromStream(istr, localStr);
|
|
|
|
if (localStr.isEmpty()) {
|
|
getAlphaNumFromStream(istr, localStr);
|
|
istr.eatWhite();
|
|
}
|
|
|
|
if (!localStr.find("-=")) {
|
|
oper = OP_MINUS_ASSIGN;
|
|
|
|
} else if (!localStr.find("+=")) {
|
|
oper = OP_PLUS_ASSIGN;
|
|
|
|
} else if (!localStr.find(">=")) {
|
|
oper = OP_GREATER_THAN_EQUAL;
|
|
|
|
} else if (!localStr.find("<=")) {
|
|
oper = OP_LESS_THAN_EQUAL;
|
|
|
|
} else if (!localStr.find("!=")) {
|
|
oper = OP_NOT_EQUAL;
|
|
|
|
} else if (!localStr.find("==")) {
|
|
oper = OP_EQUAL;
|
|
|
|
} else if (!localStr.find(">")) {
|
|
oper = OP_GREATER_THAN;
|
|
|
|
} else if (!localStr.find("<")) {
|
|
oper = OP_LESS_THAN;
|
|
|
|
} else if (!localStr.find("=")) {
|
|
oper = OP_ASSIGN;
|
|
|
|
} else if (!localStr.find("+")) {
|
|
oper = OP_PLUS;
|
|
|
|
} else if (!localStr.find("-")) {
|
|
oper = OP_MINUS;
|
|
|
|
} else if (!localStr.find("*")) {
|
|
oper = OP_MULTIPLY;
|
|
|
|
} else if (!localStr.find("/")) {
|
|
oper = OP_DIVIDE;
|
|
|
|
} else if (!localStr.find("%")) {
|
|
oper = OP_MOD;
|
|
|
|
} else if (!localStr.find("CONTAINS")) {
|
|
// SDev contains object
|
|
oper = OP_CONTAINS;
|
|
|
|
} else if (!localStr.find("HAS")) {
|
|
// SDev has type of object
|
|
oper = OP_HAS;
|
|
|
|
} else if (!localStr.find("OR")) {
|
|
oper = OP_OR;
|
|
|
|
} else if (!localStr.find("STATUS")) {
|
|
oper = OP_STATUS;
|
|
|
|
} else if (!localStr.find("AND")) {
|
|
oper = OP_AND;
|
|
}
|
|
|
|
if (oper == OP_NONE)
|
|
errorCode = ERR_UNKNOWN;
|
|
|
|
return errorCode;
|
|
}
|
|
|
|
} // namespace SpaceBar
|
|
} // namespace Bagel
|