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); }
/// <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); }
/// <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); }
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; } }
/// <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(); } } } }
/// <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; } }
/// <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; } } }
/// <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); } } }