Esempio n. 1
0
    static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createSimplified(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
    {
        CalculationCategory leftCategory = leftSide->category();
        CalculationCategory rightCategory = rightSide->category();
        ASSERT(leftCategory != CalcOther && rightCategory != CalcOther);

        bool isInteger = isIntegerResult(leftSide.get(), rightSide.get(), op);

        // Simplify numbers.
        if (leftCategory == CalcNumber && rightCategory == CalcNumber) {
            return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), CSSPrimitiveValue::UnitType::Number, isInteger);
        }

        // Simplify addition and subtraction between same types.
        if (op == CalcAdd || op == CalcSubtract) {
            if (leftCategory == rightSide->category()) {
                CSSPrimitiveValue::UnitType leftType = leftSide->typeWithCalcResolved();
                if (hasDoubleValue(leftType)) {
                    CSSPrimitiveValue::UnitType rightType = rightSide->typeWithCalcResolved();
                    if (leftType == rightType)
                        return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), leftType, isInteger);
                    CSSPrimitiveValue::UnitCategory leftUnitCategory = CSSPrimitiveValue::unitCategory(leftType);
                    if (leftUnitCategory != CSSPrimitiveValue::UOther && leftUnitCategory == CSSPrimitiveValue::unitCategory(rightType)) {
                        CSSPrimitiveValue::UnitType canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
                        if (canonicalType != CSSPrimitiveValue::UnitType::Unknown) {
                            double leftValue = leftSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(leftType);
                            double rightValue = rightSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(rightType);
                            return CSSCalcPrimitiveValue::create(evaluateOperator(leftValue, rightValue, op), canonicalType, isInteger);
                        }
                    }
                }
            }
        } else {
            // Simplify multiplying or dividing by a number for simplifiable types.
            ASSERT(op == CalcMultiply || op == CalcDivide);
            CSSCalcExpressionNode* numberSide = getNumberSide(leftSide.get(), rightSide.get());
            if (!numberSide)
                return create(leftSide, rightSide, op);
            if (numberSide == leftSide && op == CalcDivide)
                return nullptr;
            CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get();

            double number = numberSide->doubleValue();
            if (std::isnan(number) || std::isinf(number))
                return nullptr;
            if (op == CalcDivide && !number)
                return nullptr;

            CSSPrimitiveValue::UnitType otherType = otherSide->typeWithCalcResolved();
            if (hasDoubleValue(otherType))
                return CSSCalcPrimitiveValue::create(evaluateOperator(otherSide->doubleValue(), number, op), otherType, isInteger);
        }

        return create(leftSide, rightSide, op);
    }
Esempio n. 2
0
void tryEvaluateOperatorOnStackThenPush(OperatorToken *newToken,Stack *dataStack,Stack *operatorStack)
{
	OperatorToken *previousToken;
	previousToken=(OperatorToken*)pop(operatorStack);
	if(previousToken==NULL)
	{
		push(newToken,operatorStack);
	}
	else{
		while(previousToken!=NULL)
		{
			if(newToken->precedence > previousToken->precedence)
			{
				break;
			}
			else
			{
				evaluateOperator(dataStack,previousToken);
			}
			previousToken=(OperatorToken*)pop(operatorStack);
		}
		if(previousToken!=NULL)
		{
			push(previousToken,operatorStack);
		}
		push(newToken,operatorStack);
	}
}
Esempio n. 3
0
bool EXParser::priorityOperatorLoop(std::string &_expression)

{

	for(EXOperatorSet::iterator oiter = operators.begin(); oiter!=operators.end(); ++oiter){

		for(size_t index = 0; index<_expression.length(); index++){

			if(oiter->first == _expression[index] && !isScientificNotation(_expression, index)){

				if(oiter->first != '-' || !isNegitiveSign(_expression, index)){

					std::string prevExpression = _expression;

					if(!evaluateOperator(_expression, index, oiter))
					  return false;

					steps.push_back(EXSolveStep(prevExpression.append(" -> ").append(_expression), std::string(&oiter->first, 1)));

					oiter = operators.begin(); //reset operator loop to beginning

				}

			}

		}

	}
	return true;
}
Esempio n. 4
0
void evaluateAllOperatorOnStack(Stack *dataStack,Stack *operatorStack){
	
	OperatorToken *opeToken;
	while((opeToken=pop(operatorStack))!=NULL)
	{
		evaluateOperator(dataStack,opeToken);
	}
}
Esempio n. 5
0
 double evaluate(double leftSide, double rightSide) const
 {
     return evaluateOperator(leftSide, rightSide, m_operator);
 }