Example #1
0
        public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments)
        {
            Contract.Requires(context != null);
            Contract.Requires(method != null);
            Contract.Requires(arguments != null);
            Contract.Requires(arguments.Count() == method.Parameters.Length);

            if (method.MethodKind != MethodKind.BuiltinOperator ||
                method.Parameters.Length == 0 ||
                !this.IsTypeSupported(method.ReturnType))
            {
                // This might be the case of static methods etc.
                context.SetUnsupported();
                return;
            }

            BoolHandle boolResult = GetOperationResult(method, arguments);

            if (boolResult.Expression != null)
            {
                Contract.Assert(this.IsTypeSupported(method.ReturnType));
                var resultModel = new BooleanModel(this, method.ReturnType, boolResult);

                context.SetResultValue(resultModel);
            }
            else
            {
                context.SetUnsupported();
            }
        }
        // TODO: Somehow handle the different sizes and signed/unsigned variants using modulo etc.
        public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments)
        {
            Contract.Requires(context != null);
            Contract.Requires(method != null);
            Contract.Requires(arguments != null);
            Contract.Requires(arguments.Count() == method.Parameters.Length);

            if (method.MethodKind != MethodKind.BuiltinOperator ||
                method.Parameters.Length == 0 ||
                (!BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType) &&
                 !this.IsTypeSupported(method.ReturnType)))
            {
                // This might be the case of conversions to other types, static methods etc.
                context.SetUnsupported();
                return;
            }

            IntHandle  intResult;
            BoolHandle boolResult;

            this.GetOperationResult(context, method, arguments, out intResult, out boolResult);

            ITypeModel resultModel = null;

            if (intResult.Expression != null)
            {
                Contract.Assert(this.IsTypeSupported(method.ReturnType));
                resultModel = new IntegerModel(this, method.ReturnType, intResult);
            }
            else if (boolResult.Expression != null)
            {
                Contract.Assert(BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType));

                // TODO: Properly manage the references to the other factories instead of using singletons for all types
                resultModel = BooleanModelFactory.Instance.GetExpressionModel(
                    method.ReturnType,
                    boolResult.Expression.ToSingular());
            }

            if (resultModel != null)
            {
                context.SetResultValue(resultModel);
            }
            else
            {
                context.SetUnsupported();
            }
        }
Example #3
0
 private BoolHandle GetOperationResult(
     IModellingContext context,
     IMethodSymbol method,
     IEnumerable <ITypeModel> arguments)
 {
     if (method.Name == "op_Equality")
     {
         return((BoolHandle)ExpressionFactory.Equal(
                    arguments.First().AssignmentRight[0],
                    arguments.ElementAt(1).AssignmentRight[0]));
     }
     else if (method.Name == "op_Inequality")
     {
         return((BoolHandle)ExpressionFactory.Distinct(
                    arguments.First().AssignmentRight[0],
                    arguments.ElementAt(1).AssignmentRight[0]));
     }
     else
     {
         return(default(BoolHandle));
     }
 }
Example #4
0
        public void ModelOperation(IModellingContext context, IMethodSymbol method, IEnumerable <ITypeModel> arguments)
        {
            if (method.MethodKind != MethodKind.BuiltinOperator ||
                method.Parameters.Length != 2)
            {
                context.SetUnsupported();
                return;
            }

            var boolResult = this.GetOperationResult(context, method, arguments);

            if (boolResult.Expression != null)
            {
                var resultModel = BooleanModelFactory.Instance.GetExpressionModel(
                    method.ReturnType,
                    boolResult.Expression.ToSingular());
                context.SetResultValue(resultModel);
            }
            else
            {
                context.SetUnsupported();
            }
        }
        private void GetOperationResult(
            IModellingContext context,
            IMethodSymbol method,
            IEnumerable <ITypeModel> arguments,
            out IntHandle intResult,
            out BoolHandle boolResult)
        {
            var first = ((IntegerModel)arguments.First()).Value;

            if (method.Parameters.Length == 1)
            {
                if (method.Name == "op_UnaryNegation")
                {
                    intResult = -first;
                }
                else if (method.Name == "op_UnaryPlus")
                {
                    intResult = first;
                }
            }
            else
            {
                Contract.Assert(method.Parameters.Length == 2);
                var second = ((IntegerModel)arguments.ElementAt(1)).Value;

                if (BooleanModelFactory.Instance.IsTypeSupported(method.ReturnType))
                {
                    switch (method.Name)
                    {
                    case "op_Equality":
                        boolResult = (first == second);
                        break;

                    case "op_Inequality":
                        boolResult = (first != second);
                        break;

                    case "op_GreaterThan":
                        boolResult = (first > second);
                        break;

                    case "op_LessThan":
                        boolResult = (first < second);
                        break;

                    case "op_GreaterThanOrEqual":
                        boolResult = (first >= second);
                        break;

                    case "op_LessThanOrEqual":
                        boolResult = (first <= second);
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    Contract.Assert(this.IsTypeSupported(method.ReturnType));

                    switch (method.Name)
                    {
                    case "op_Addition":
                        intResult = first + second;
                        break;

                    case "op_Subtraction":
                        intResult = first - second;
                        break;

                    case "op_Division":
                        // TODO: Set the exception if the right is zero
                        intResult = first / second;
                        break;

                    case "op_Modulus":
                        intResult = first % second;
                        break;

                    case "op_Multiply":
                        intResult = first * second;
                        break;

                    default:
                        break;
                    }
                }
            }
        }