示例#1
0
bool ExpConditional::Constant()
{
	if (a->Constant()) CollapseConstantTree(a);
	if (b->Constant()) CollapseConstantTree(b);
	if (c->Constant()) CollapseConstantTree(c);

	return (a->Constant() && b->Constant() && c->Constant());
}
示例#2
0
// Do a standard binary constant collapse for a binary operator.
bool DoBinaryCollapse(ExpPart*& l, ExpPart*& r)
{
	bool leftConst = l->Constant();
	bool rightConst = r->Constant();

	// If the L part is constant, collapse it.
	if (leftConst) CollapseConstantTree(l);

	// If the R part is constant, collapse it.
	if (rightConst) CollapseConstantTree(r);

	// This part is constant if the left and right parts are both constant.
	return (leftConst && rightConst);
}
示例#3
0
bool ExpArray::Constant()
{
	// Const collapse all items
	ExpParamIterator i = expElements.begin();
	ExpParamConstIterator elements_end = expElements.end();

	isConstant = true;

	for ( ; i != elements_end; i++) {
		if ((*i)->Constant())
			CollapseConstantTree(*i);
		else
			isConstant = false;
	}

	// If it is constant, get me to evaluate
	if (isConstant) {
		ExpReturn unused;

		// Evaluate checks for the isConstant flag so temporarily turn it off
		isConstant = false;
		this->Evaluate(&unused);
		isConstant = true;
	}

	return isConstant!=0;
}
示例#4
0
bool ExpIdent::Constant()
{
	// Const collapse all parameters
	ExpPart** curParam = parameters;

	bool allParamsConstant = true;

	for ( ; curParam != paramsEnd; curParam++) {

		// This parameter is constant
		if ((*curParam)->Constant())
			CollapseConstantTree(*curParam);	// Collapse it
		else
			allParamsConstant = false;
	}

	// All parameters are constant: evaluate the parameters
	if (allParamsConstant) {

		ExpReturn* expPtr = expParamList;
		ExpPart** curParam = parameters;

		// Evaluate every parameter
		for ( ; curParam != paramsEnd; curParam++)

			// Send to address of corresponding expParamList array entry
			(*curParam)->Evaluate(expPtr++);

		// Switch off parameter evaluation since all parameters are constant and we've evaluated them already.
		hasParameters = false;
	}

	// Return false; no way of telling if the plugin will return a constant value
	// or not.

	// UNLESS it is a system expression, in which we can mark constant all expressions which return
	// a constant output for a constant input.
	// Note i havent bothered for expressions like max and min.  Nobody types max(3,4,5,6).
	if (oid == -1 && allParamsConstant) {
		switch (expID) {
		case 10:					// newline
		case 21:					// numtokens
		case 22:					// gettoken
		case SYSTEM_VARINDEX:		// _varindex
			return true;
		default:
			return false;
		}

	}

	return false;
}
示例#5
0
bool ExpDot::Constant()
{
	// Const collapse all parameters
	vector<ExpPart*>::iterator i;

	for (i = parameters.begin(); i != parameters.end(); i++) {

		// This parameter is constant
		if ((*i)->Constant())
			CollapseConstantTree((*i));	// Collapse it
	}

	// Return false; no way of telling if the plugin will return a constant value
	// or not.
	return false;
}
示例#6
0
void CExpression::ParseTokenStream()
{
	// Make the tree
	int step = 0;
	pExpressionOwner = NULL;
	ExpTree = DoTree(step);
	ExpTree = PostSortTree(ExpTree);

	// Determine if the overall expression is constant, collapsing constant parts along
	// the way.
	isConstant = ExpTree->Constant();

	// If constant, get the constant value.
	if (isConstant) {
		CollapseConstantTree(ExpTree);
		ExpTree->Evaluate(&constantValue);
	}
}
示例#7
0
bool ExpDot::Constant()
{
	// Const collapse all parameters
	ExpPart** curParam = parameters;

	if(hasParameters)
	{
		bool allParamsConstant = true;


		for ( ; curParam != paramsEnd; curParam++) {

			// This parameter is constant
			if ((*curParam)->Constant())
				CollapseConstantTree(*curParam);	// Collapse it
			else
				allParamsConstant = false;
		}
	

		// All parameters are constant: evaluate the parameters
		if (allParamsConstant) {

			ExpReturn* expPtr = expParamList;
			ExpPart** curParam = parameters;

			// Evaluate every parameter
			for ( ; curParam != paramsEnd; curParam++)

				// Send to address of corresponding expParamList array entry
				(*curParam)->Evaluate(expPtr++);

			// Switch off parameter evaluation since all parameters are constant and we've evaluated them already.
			hasParameters = false;
		}
	}
	// Return false; no way of telling if the plugin will return a constant value
	// or not.
	return false;
}
示例#8
0
// Tokenise a user's typed expression string
void CExpression::ParseUserString(const char* exp, int* pchpos, bool editorMode)
{
	toks.clear();

	whitespaceCount = 0;

	// Loop every char
	for (int i = 0; exp[i] != NULL; i++) {

		if (pchpos) *pchpos = i;

		char NextCh = exp[i+1];
		char CurCh = exp[i];
		char PrevCh = exp[(i == 0 ? 0 : i-1)];
		char strbuf[128];

		// Check this char
		switch (exp[i]) {

		case '+':
			AppendToken(T_ADD, "+");
			break;
		case '-':

			// If previous token is not operand, use as negative sign
			// Fix 25/4/07: random(4) - random(5) interprets '-' as integer: explicit check for right bracket
			if (toks.size() == 0 || ((!TokenFitsRule(toks.back().t, T_ANY_VALUE) || toks.back().t == T_LEFTBRACKET) && toks.back().t != T_RIGHTBRACKET)) {

				i += ConsumeDigits(strbuf, &(exp[i]));

				// Contains a dot: float
				if (StrContains(strbuf, '.'))
					AppendToken(T_FLOAT, strbuf);
				else	// Else integer
					AppendToken(T_INTEGER, strbuf);
			}
			else
				AppendToken(T_SUBTRACT, "-");

			break;
		case '*':
			AppendToken(T_MULTIPLY, "*");
			break;
		case '/':
			AppendToken(T_DIVIDE, "/");
			break;
		case '^':
			AppendToken(T_POWER, "^");
			break;
		case '%':
			AppendToken(T_MOD, "%");
			break;
		case '(':
			AppendToken(T_LEFTBRACKET, "(");
			break;
		case ')':
			AppendToken(T_RIGHTBRACKET, ")");
			break;
		case '{':
			AppendToken(T_LEFTCURLY, "{");
			break;
		case '}':
			AppendToken(T_RIGHTCURLY, "}");
			break;
		case '@':
			AppendToken(T_AT, "@");
			break;
		case ',':
			AppendToken(T_COMMA, ",");
			break;
		case '.':
			AppendToken(T_DOT, ".");
			break;
		case '"':
			i += AppendString(&(exp[i]), editorMode);
			break;
		case '\'':
			i += AppendString(&(exp[i]), editorMode, true);
			break;
		case '=':
			AppendToken(T_EQUAL, "=");
			break;
		case '<':
			if (NextCh == '=') {
				AppendToken(T_LESSEQUAL, "<=");
				i++;
			}
			else if (NextCh == '>') {
				AppendToken(T_NOTEQUAL, "<>");
				i++;
			}
			else
				AppendToken(T_LESS, "<");
			break;
		// Alternative not equal operator != <>
		case '!':
			if (NextCh == '=') {
				AppendToken(T_NOTEQUAL, "!=");
				i++;
			}
			else
				NotifyError("Syntax error: '!'");
			break;
		case '&':
			AppendToken(T_AND, "&");
			break;
		case '|':
			AppendToken(T_OR, "|");
			break;
		case '>':
			if (NextCh == '=') {
				AppendToken(T_GREATEREQUAL, ">=");
				i++;
			}
			else
				AppendToken(T_GREATER, ">");
			break;
		case '?':
			AppendToken(T_CONDITIONAL, "?");
			break;
		case ':':
			AppendToken(T_COLON, ":");
			break;
		default:

			// Parse numbers and idents
			if (IsChAlphaNumeric(CurCh))
				i += ConsumeAppendIdentifier(strbuf, &(exp[i]));

			// Skip over whitespace
			else if (IsWhitespace(CurCh)) {

				// In editor mode add a T_WHITESPACE token
				if (editorMode) {
					Token t;
					t.length = 0;
					t.t = T_WHITESPACE;

					while (IsWhitespace(exp[i])) {
						t.str += exp[i];
						i++;
					}

					// We want the next for loop iteration to see the next char
					i--;

					toks.push_back(t);
				}

				// Add to last token length
				if (toks.size() > 0)
					toks[toks.size() - 1].length++;
			}
			// Else unknown character
			else {
				string error = "Unknown character '";
				error += CurCh;
				error += "'";
				throw runtime_error(error.c_str());
			}
		}//switch

	}//for

	// Only perform preprocessing when not in edittime mode
	if (!editorMode)
		PreProcessTokStream();


	///////////////////////////
	// Final step:  parse to tree

	// Determine if the overall expression is constant, collapsing constant parts along
	// the way.
	// Runtime only
#ifdef RUNTIME
	// Make the tree
	int step = 0;
	ExpTree = DoTree(step);

	isConstant = ExpTree->Constant();

	// If constant, get the constant value.
	if (isConstant) {
		CollapseConstantTree(ExpTree);
		ExpTree->Evaluate(&constantValue);
	}
#endif

}