private NumberKinds DowngradedKind(NumberKinds oldKind, NumberKinds newKind)
        {
            NumberKinds Result;

            if (oldKind == NumberKinds.Integer && (newKind == NumberKinds.Real || newKind == NumberKinds.Unknown))
            {
                if (newKind == NumberKinds.Real)
                {
                    Result = NumberKinds.Real;
                }
                else
                {
                    Result = newKind;
                }
            }
            else if (oldKind == NumberKinds.Real && newKind == NumberKinds.Unknown)
            {
                Result = newKind;
            }
            else if (oldKind == NumberKinds.NotApplicable && newKind == NumberKinds.Unknown)
            {
                Result = newKind;
            }
            else
            {
                Result = oldKind;
            }

            return(Result);
        }
예제 #2
0
        /// <summary>
        /// Tentatively updates the number kind if <paramref name="numberKind"/> is more accurate.
        /// </summary>
        /// <param name="numberKind">The new kind.</param>
        /// <param name="isChanged">True if the number kind was changed.</param>
        public void UpdateNumberKind(NumberKinds numberKind, ref bool isChanged)
        {
            Debug.Assert(numberKind != NumberKinds.NotChecked);

            if (NumberKind == NumberKinds.NotChecked)
            {
                NumberKind = numberKind;
                isChanged  = true;
            }
            else
            {
                Debug.Assert(NumberKind != NumberKinds.NotApplicable || numberKind == NumberKinds.NotApplicable);

                if (NumberKind == NumberKinds.Unknown)
                {
                    if (numberKind == NumberKinds.Integer)
                    {
                        NumberKind = NumberKinds.Integer;
                        isChanged  = true;
                    }

                    if (numberKind == NumberKinds.Real)
                    {
                        NumberKind = NumberKinds.Real;
                        isChanged  = true;
                    }
                }
            }
        }
        /// <summary>
        /// Gets the default number kind for this type.
        /// </summary>
        public NumberKinds GetDefaultNumberKind()
        {
            NumberKinds Result = NumberKinds.NotApplicable;

            foreach (IConstraint Constraint in FormalGeneric.ConstraintList)
            {
                //TODO Check this
                //Debug.Assert(Constraint.ResolvedParentType.IsAssigned);

                if (Constraint.ResolvedParentType.IsAssigned && Constraint.ResolvedParentType.Item is IClassType AsClassType)
                {
                    NumberKinds ClassKind = AsClassType.GetDefaultNumberKind();
                    Result = DowngradedKind(NumberKind, ClassKind);
                }
            }

            if (Result == NumberKinds.NotApplicable)
            {
                foreach (IConstraint Constraint in FormalGeneric.ConstraintList)
                {
                    //TODO Check this
                    //Debug.Assert(Constraint.ResolvedParentType.IsAssigned);

                    if (Constraint.ResolvedParentType.IsAssigned && Constraint.ResolvedParentType.Item is ICompiledNumberType AsNumberType)
                    {
                        Result = DowngradedKind(NumberKind, AsNumberType.NumberKind);
                    }
                }
            }

            return(Result);
        }
예제 #4
0
        /// <summary>
        /// Tentatively updates the number kind of the result.
        /// </summary>
        /// <param name="numberKind">The new number kind.</param>
        /// <param name="isChanged">True if the number kind was changed.</param>
        public void UpdateNumberKind(NumberKinds numberKind, ref bool isChanged)
        {
            IExpressionType PreferredResultType = Preferred;

            if (PreferredResultType != null)
            {
                PreferredResultType.UpdateNumberKind(numberKind, ref isChanged);
            }
        }
        /// <summary>
        /// Check number types.
        /// </summary>
        /// <param name="isChanged">True upon return if a number type was changed.</param>
        public void CheckNumberType(ref bool isChanged)
        {
            FormattedNumber n          = FormattedNumber.Parse(ValidText.Item);
            bool            IsInteger  = n.Value.IsInteger;
            NumberKinds     NumberKind = IsInteger ? NumberKinds.Integer : NumberKinds.Real;

            Debug.Assert(ResolvedResult.IsAssigned);

            ResolvedResult.Item.UpdateNumberKind(NumberKind, ref isChanged);
        }
예제 #6
0
        public static void Number_ContructGet(string description, object expected, NumberKinds kind, bool isZero)
        {
            // InlineData does not like decimal literals (eg 10.0m)
            if (description == nameof(Decimal))
            {
                expected = (decimal)(double)expected;
            }

            var actual = Number.CreateFromObject(expected);

            Assert.Equal(expected, actual.Value);
        }
 /// <summary>
 /// Tentatively updates the number kind if <paramref name="numberKind"/> is more accurate.
 /// </summary>
 /// <param name="numberKind">The new kind.</param>
 /// <param name="isChanged">True if the number kind was changed.</param>
 public void UpdateNumberKind(NumberKinds numberKind, ref bool isChanged)
 {
     if (NumberKind == NumberKinds.NotApplicable && numberKind != NumberKinds.NotApplicable)
     {
         NumberKind = numberKind;
         isChanged  = true;
     }
     else if (NumberKind == NumberKinds.Unknown && numberKind == NumberKinds.Integer)
     {
         NumberKind = numberKind;
         isChanged  = true;
     }
 }
예제 #8
0
        /// <summary>
        /// Restarts a check of number types.
        /// </summary>
        public void RestartNumberType(ref bool isChanged)
        {
            foreach (IEntityDeclaration EntityDeclaration in ParameterList)
            {
                EntityDeclaration.RestartNumberType(ref isChanged);
            }

            foreach (IEntityDeclaration EntityDeclaration in ResultList)
            {
                EntityDeclaration.RestartNumberType(ref isChanged);
            }

            if (Variant.IsAssigned)
            {
                ((IExpression)Variant).RestartNumberType(ref isChanged);
            }

            ((IBody)QueryBody).RestartNumberType(ref isChanged);

            if (ParameterTable.Count > 0)
            {
                if (NumberArgumentTable.Count == 0)
                {
                    for (int i = 0; i < ParameterTable.Count; i++)
                    {
                        IParameter Parameter = ParameterTable[i];
                        NumberArgumentTable.Add(Parameter, new List <NumberKinds>());
                    }
                }
                else
                {
                    // Result of the previous pass.
                    for (int i = 0; i < ParameterTable.Count; i++)
                    {
                        IParameter Parameter = ParameterTable[i];
                        Debug.Assert(NumberArgumentTable.ContainsKey(Parameter));

                        Debug.Assert(Parameter.ResolvedParameter.ResolvedEffectiveType.IsAssigned);

                        if (Parameter.ResolvedParameter.ResolvedEffectiveType.Item is ICompiledNumberType AsNumberType)
                        {
                            NumberKinds BestGuess = AsNumberType.GetDefaultNumberKind();
                            UpdateParameterKind(NumberArgumentTable[Parameter], ref BestGuess);
                            AsNumberType.UpdateNumberKind(BestGuess, ref isChanged);
                        }

                        NumberArgumentTable[Parameter].Clear();
                    }
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Tentatively updates the number kind from a list of other types, if they are all more accurate.
        /// </summary>
        /// <param name="typeList">The list of types.</param>
        /// <param name="isChanged">True if the number kind was changed.</param>
        public void UpdateNumberKind(IList <ICompiledNumberType> typeList, ref bool isChanged)
        {
            if (NumberKind == NumberKinds.NotChecked)
            {
                NumberKind = GetDefaultNumberKind();
                isChanged  = true;
            }

            if (NumberKind != NumberKinds.NotApplicable || typeList.Count == 0)
            {
                return;
            }

            NumberKinds ComposedNumberKind = typeList[0].NumberKind;

            for (int i = 1; i < typeList.Count; i++)
            {
                NumberKinds ItemNumberKind = typeList[i].NumberKind;

                if (ItemNumberKind == NumberKinds.NotApplicable)
                {
                    ComposedNumberKind = NumberKinds.NotApplicable;
                }
                else if (ComposedNumberKind == NumberKinds.Integer && (ItemNumberKind == NumberKinds.Unknown || ItemNumberKind == NumberKinds.Real))
                {
                    if (ItemNumberKind == NumberKinds.Unknown)
                    {
                        ComposedNumberKind = ItemNumberKind;
                    }
                    else
                    {
                        ComposedNumberKind = ItemNumberKind;
                    }
                }
                else if (ComposedNumberKind == NumberKinds.Real && ItemNumberKind == NumberKinds.Unknown)
                {
                    ComposedNumberKind = NumberKinds.Unknown;
                }
            }

            if (ComposedNumberKind != NumberKinds.NotApplicable)
            {
                NumberKind = ComposedNumberKind;
                isChanged  = true;
            }
        }
예제 #10
0
        /// <summary>
        /// Gets the best guess for the kind of a number parameter.
        /// </summary>
        public static void UpdateParameterKind(IList <NumberKinds> usageList, ref NumberKinds bestGuess)
        {
            foreach (NumberKinds Item in usageList)
            {
                switch (Item)
                {
                case NumberKinds.NotApplicable:
                    bestGuess = NumberKinds.NotApplicable;
                    return;

                case NumberKinds.Unknown:
                    bestGuess = NumberKinds.Unknown;
                    break;

                case NumberKinds.Real:
                    if (bestGuess == NumberKinds.Integer)
                    {
                        bestGuess = NumberKinds.Real;
                    }
                    break;
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Check number types.
        /// </summary>
        /// <param name="isChanged">True upon return if a number type was changed.</param>
        public void CheckNumberType(ref bool isChanged)
        {
            if (ValidEntity.Item.ResolvedEffectiveType.Item is ICompiledNumberType AsNumberTypeEntity)
            {
                if (AsNumberTypeEntity.NumberKind == NumberKinds.NotChecked)
                {
                    NumberKinds NumberKind = AsNumberTypeEntity.GetDefaultNumberKind();

                    if (DefaultValue.IsAssigned)
                    {
                        IExpression SourceExpression = (IExpression)DefaultValue.Item;
                        SourceExpression.CheckNumberType(ref isChanged);

                        IExpressionType PreferredSource = SourceExpression.ResolvedResult.Item.Preferred;
                        if (PreferredSource.ValueType is ICompiledNumberType AsNumberTypeSource)
                        {
                            NumberKind = AsNumberTypeSource.NumberKind;
                        }
                    }

                    AsNumberTypeEntity.UpdateNumberKind(NumberKind, ref isChanged);
                }
            }
        }