protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
{
IValue retVal = null;
ExplanationPart binaryExpressionExplanation = ExplanationPart.CreateSubExplanation(explain, this);
IValue leftValue = Left.GetValue(context, binaryExpressionExplanation);
if (leftValue != null)
{
IValue rightValue;
switch (Operation)
{
case Operator.Exp:
case Operator.Mult:
case Operator.Add:
case Operator.Sub:
case Operator.Div:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = Left.GetExpressionType().PerformArithmericOperation(context, leftValue, Operation,
rightValue);
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.And:
{
if (leftValue.Type == EfsSystem.Instance.BoolType)
{
BoolValue lb = leftValue as BoolValue;
if (lb != null)
{
if (lb.Val)
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
if (rightValue.Type == EfsSystem.Instance.BoolType)
{
retVal = rightValue as BoolValue;
}
else
{
AddError("Cannot apply an operator " + Operation +
" on a variable of type " + rightValue.GetType(), RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
else
{
ExplanationPart.CreateSubExplanation(binaryExpressionExplanation,
"Right part not evaluated");
retVal = lb;
}
}
else
{
AddError("Cannot evaluate " + Left + " as a boolean", RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("Cannot apply an operator " + Operation + " on a variable of type " +
leftValue.GetType(), RuleChecksEnum.SemanticAnalysisError);
}
}
break;
case Operator.Or:
{
if (leftValue.Type == EfsSystem.Instance.BoolType)
{
BoolValue lb = leftValue as BoolValue;
if (lb != null)
{
if (!lb.Val)
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
if (rightValue.Type == EfsSystem.Instance.BoolType)
{
retVal = rightValue as BoolValue;
}
else
{
AddError("Cannot apply an operator " + Operation +
" on a variable of type " + rightValue.GetType(), RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
else
{
ExplanationPart.CreateSubExplanation(binaryExpressionExplanation,
"Right part not evaluated");
retVal = lb;
}
}
else
{
AddError("Cannot evaluate " + Left + " as a boolean", RuleChecksEnum.ExecutionFailed);
}
}
else
{
AddError("Cannot apply an operator " + Operation + " on a variable of type " +
leftValue.GetType(), RuleChecksEnum.SemanticAnalysisError);
}
}
break;
case Operator.Less:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(Left.GetExpressionType().Less(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.LessOrEqual:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal =
EfsSystem.Instance.GetBoolean(Left.GetExpressionType().CompareForEquality(leftValue, rightValue) ||
leftValue.Type.Less(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.Greater:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(Left.GetExpressionType().Greater(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.GreaterOrEqual:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal =
EfsSystem.Instance.GetBoolean(Left.GetExpressionType().CompareForEquality(leftValue, rightValue) ||
leftValue.Type.Greater(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.Equal:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(Left.GetExpressionType().CompareForEquality(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.NotEqual:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(!Left.GetExpressionType().CompareForEquality(leftValue, rightValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.In:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(Right.GetExpressionType().Contains(rightValue, leftValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.NotIn:
{
rightValue = Right.GetValue(context, binaryExpressionExplanation);
if (rightValue != null)
{
retVal = EfsSystem.Instance.GetBoolean(!Right.GetExpressionType().Contains(rightValue, leftValue));
}
else
{
AddError("Error while computing value for " + Right, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.Is:
{
leftValue = Left.GetValue(context, binaryExpressionExplanation);
retVal = EfsSystem.Instance.GetBoolean(false);
if (leftValue != null)
{
Structure rightStructure = Right.Ref as Structure;
if (rightStructure != null)
{
if (leftValue.Type is Structure)
{
Structure leftStructure = leftValue.Type as Structure;
if (rightStructure.ImplementedStructures.Contains(leftStructure))
{
retVal = EfsSystem.Instance.GetBoolean(true);
}
else
{
AddError("Incompatible types for operator is", RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("The operator is can only be applied on structures", RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("The right part of is operator should be a structure", RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("Error while computing value for " + Left, RuleChecksEnum.ExecutionFailed);
}
}
break;
case Operator.As:
{
leftValue = Left.GetValue(context, binaryExpressionExplanation);
if (leftValue != null)
{
if (leftValue.Type == Right.GetExpressionType())
{
retVal = leftValue;
}
else
{
AddError("Incompatible types for operator as", RuleChecksEnum.SemanticAnalysisError);
}
}
else
{
AddError("Error while computing value for " + Left, RuleChecksEnum.ExecutionFailed);
}
}
break;
}
}
else
{
AddError("Error while computing value for " + Left, RuleChecksEnum.ExecutionFailed);
}
return retVal;
}