//========================================================================================= bool BinaryOperationEvaluator::EvaluateOperands( Number*& leftNumber, Number*& rightNumber, Environment& environment ) { bool success = false; leftNumber = 0; rightNumber = 0; do { if( !leftOperand ) { environment.AddError( "Binary operator has no left operand." ); break; } if( !rightOperand ) { environment.AddError( "Binary operator has no right operand." ); break; } // Call upon the environment to create the types of numbers we'll be working with. leftNumber = environment.CreateNumber( this ); rightNumber = environment.CreateNumber( this ); if( !( leftNumber && rightNumber ) ) { environment.AddError( "Failed to create numbers from environment for binary operation." ); break; } // Evaluate our left and right operands. if( !leftOperand->EvaluateResult( *leftNumber, environment ) ) { environment.AddError( "Failed to evaluate left operand of binary operator." ); break; } if( !rightOperand->EvaluateResult( *rightNumber, environment ) ) { environment.AddError( "Failed to evaluate right operand of binary operator." ); break; } success = true; } while( false ); if( !success ) { delete leftNumber; delete rightNumber; leftNumber = 0; rightNumber = 0; } return success; }
//========================================================================================= void TaylorSeriesFunctionEvaluator::Center( const Number* number, Environment& environment ) { if( center ) delete center; center = environment.CreateNumber(0); center->AssignFrom( number, environment ); }
//========================================================================================= /*virtual*/ bool InverseFunctionEvaluator::EvaluateResult( Number& result, Environment& environment ) { bool success = false; Number* argumentResult = 0; do { FunctionArgumentEvaluator* argument = GetArgument(0); if( !argument ) { environment.AddError( "The inverse function expects an argument." ); break; } argumentResult = environment.CreateNumber( argument ); if( !argument->EvaluateResult( *argumentResult, environment ) ) break; if( !result.IsTypeOf( MultivectorNumber::ClassName() ) ) break; if( !result.AssignMultilicativeInverse( argumentResult, environment ) ) { environment.AddError( "Failed to take the inverse!" ); break; } success = true; } while( false ); delete argumentResult; return success; }
//========================================================================================= // It is very important that we evaluate the arguments from left to right, because // this is the expected behavior of the language. bool FunctionEvaluator::EvaluateArguments( Number**& numberArray, int& numberArraySize, Environment& environment ) { bool success = false; do { // Some functions don't take any arguments. // If this one does, then go evaluate those arguments. numberArray = 0; numberArraySize = listOfArguments.Count(); if( numberArraySize > 0 ) { numberArray = new Number*[ numberArraySize ]; memset( numberArray, 0, numberArraySize * sizeof( Number* ) ); // Go populate the number array with the argument list evaluation results. FunctionArgumentEvaluator* evaluator = ( FunctionArgumentEvaluator* )listOfArguments.LeftMost(); int index; for( index = 0; index < numberArraySize; index++ ) { if( !evaluator ) break; Number* number = environment.CreateNumber( this ); numberArray[ index ] = number; if( !evaluator->EvaluateResult( *number, environment ) ) break; evaluator = ( FunctionArgumentEvaluator* )evaluator->Right(); } if( index < numberArraySize ) break; } success = true; } while( false ); // It's all or nothing. If we failed, don't return anything. if( !success ) DeleteArguments( numberArray, numberArraySize ); return success; }
//========================================================================================= bool UnaryOperationEvaluator::EvaluateOperand( Number*& number, Environment& environment ) { bool success = false; do { if( !operand ) { environment.AddError( "Unary operator has no argument." ); break; } // Call upon the environment to create the type of number we'll be working with. number = environment.CreateNumber( operand ); if( !number ) { environment.AddError( "Failed to create number from environment for unary operator." ); break; } // Evaluate our operand. if( !operand->EvaluateResult( *number, environment ) ) { environment.AddError( "Unary operand operand evaluation failed." ); break; } success = true; } while( false ); if( !success ) { delete number; number = 0; } return success; }