protected override Evaluator CreateEvaluator(Dictionary<Expression,Evaluator> Cache, int BufferSize, int Resolution)
{
Evaluator lefteval = this.Left.GetEvaluator(Cache, BufferSize, Resolution);
Evaluator righteval = this.Right.GetEvaluator(Cache, BufferSize, Resolution);
bool constleft = false;
Value leftval = 0;
bool constright = false;
Value rightval = 0;
ConstantEvaluator consteval = lefteval as ConstantEvaluator;
if (consteval != null)
{
constleft = true;
leftval = consteval.Value;
}
consteval = righteval as ConstantEvaluator;
if (consteval != null)
{
constright = true;
rightval = consteval.Value;
}
switch (this.Operation)
{
case BinaryOperation.Add:
if (constleft && constright)
return new ConstantEvaluator(leftval + rightval);
if (constleft)
return new AddConstantEvaluator(righteval, leftval);
if (constright)
return new AddConstantEvaluator(lefteval, rightval);
return new AddEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Subtract:
if (constleft && constright)
return new ConstantEvaluator(leftval - rightval);
if (constleft)
return new AddConstantEvaluator(new NegateEvaluator(righteval), leftval);
if (constright)
return new AddConstantEvaluator(lefteval, -rightval);
return new SubtractEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Multiply:
if (constleft && constright)
return new ConstantEvaluator(leftval * rightval);
if (constleft)
return new MultiplyConstantEvaluator(righteval, leftval);
if (constright)
return new MultiplyConstantEvaluator(lefteval, rightval);
return new MultiplyEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Divide:
if (constleft && constright)
{
if (rightval == 0)
return new ConstantEvaluator(0);
else
return new ConstantEvaluator(leftval / rightval);
}
if (constleft)
return new DivideEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new DivideConstantEvaluator(lefteval, rightval);
return new DivideEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Modulus:
if (constleft && constright)
{
if (rightval == 0)
return new ConstantEvaluator(0);
else
return new ConstantEvaluator(leftval % rightval);
}
if (constleft)
return new ModulusEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new ModulusConstantEvaluator(lefteval, rightval);
return new ModulusEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Or:
if (constleft && constright)
return new ConstantEvaluator(leftval | rightval);
if (constleft)
return new OrEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new OrEvaluator(lefteval, righteval.GetBuffered(BufferSize));
return new OrEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.And:
if (constleft && constright)
return new ConstantEvaluator(leftval & rightval);
if (constleft)
return new AndEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new AndEvaluator(lefteval, righteval.GetBuffered(BufferSize));
return new AndEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.Xor:
if (constleft && constright)
return new ConstantEvaluator(leftval ^ rightval);
if (constleft)
return new XorEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new XorEvaluator(lefteval, righteval.GetBuffered(BufferSize));
return new XorEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.LeftShift:
if (constleft && constright)
return new ConstantEvaluator(leftval << (int)rightval);
if (constleft)
return new LeftShiftEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new LeftShiftConstantEvaluator(lefteval, (int)rightval);
return new LeftShiftEvaluator(lefteval, righteval.GetBuffered(BufferSize));
case BinaryOperation.RightShift:
if (constleft && constright)
return new ConstantEvaluator(leftval >> (int)rightval);
if (constleft)
return new RightShiftEvaluator(lefteval, righteval.GetBuffered(BufferSize));
if (constright)
return new RightShiftConstantEvaluator(lefteval, (int)rightval);
return new RightShiftEvaluator(lefteval, righteval.GetBuffered(BufferSize));
default:
throw new NotImplementedException();
}
}