private void TypeCheck(ATypes type, RankJobInfo rankInfo) { if (!rankInfo.FloatConvert) { if (rankInfo.Check == ATypes.AType) { rankInfo.Check = type; } else if (rankInfo.Check != type) { if (rankInfo.Check == ATypes.AFloat && type == ATypes.AInteger || type == ATypes.AFloat && rankInfo.Check == ATypes.AInteger) { rankInfo.FloatConvert = true; } else if (!type.MixedType()) { throw new Error.Type("Rank"); } } } }
/// <summary> /// Argument is a nested vector than we: >(0#x), >(1#x),..., >(-1+#x)#x /// </summary> /// <param name="argument"></param> /// <returns></returns> private AType NestedVector(AType argument) { AType result = AArray.Create(ATypes.AArray); // disclose the first item of the argument, get type, rank and shape AType disclosedItem = MonadicFunctionInstance.Disclose.Execute(argument[0]); AType disclosedArray = disclosedItem.IsArray ? disclosedItem : AArray.Create(disclosedItem.Type, disclosedItem); ATypes type = disclosedArray.Type; int rank = disclosedArray.Rank; List <int> shape = disclosedArray.Shape; bool convertToFloat = false; // first Float null item bool FloatNull = (disclosedArray.Length == 0 && type == ATypes.AFloat); // add first item to the result int length = Catenate(disclosedArray, result); for (int i = 1; i < argument.Length; i++) { //Disclose ith item. disclosedItem = MonadicFunctionInstance.Disclose.Execute(argument[i]); // TODO: do we need these checks? disclosedArray = disclosedItem.IsArray ? disclosedItem : AArray.Create(disclosedItem.Type, disclosedItem); if (disclosedArray.Length == 0) { // skip empty items continue; } if (type != disclosedArray.Type) { // if one item of the argument is Float then all item will be Float // if and only if other items is Integers or Floats. if (type == ATypes.AFloat && disclosedArray.Type == ATypes.AInteger) { if (FloatNull) { type = ATypes.AInteger; } else { convertToFloat = true; } } else if (type == ATypes.AInteger && disclosedArray.Type == ATypes.AFloat) { convertToFloat = true; } else if (type == ATypes.ANull) { type = disclosedArray.Type; } else if (!type.MixedType() || !disclosedArray.MixedType()) { // type is differnce so we throw Type error throw new Error.Type(TypeErrorText); } } FloatNull = false; if (rank != disclosedArray.Rank) { throw new Error.Rank(RankErrorText); } // mismatch error arise if actual item has bigger rank than 1 and has a different shape if (!shape.SequenceEqual(disclosedArray.Shape)) { if (shape.Count > 1 || disclosedArray.Shape.Count > 1) { throw new Error.Mismatch(MismatchErrorText); } } length += Catenate(disclosedArray, result); } // set result properties result.Length = length; result.Rank = rank; result.Shape = new List <int>() { length }; if (rank > 1) { result.Shape.AddRange(shape.GetRange(1, shape.Count - 1)); } // convert items to Float, if this flag is true. if (convertToFloat) { result.ConvertToFloat(); } else { result.Type = type; } return(result); }
private AType DiscloseNestedVector(AType argument, out List <int> shape) { //TODO: Is Clone method correct here? AType item = argument[0].NestedItem.Clone(); ATypes type = item.Type; shape = item.Shape; int rank = item.Rank; if (CheckFloat(argument)) { //Convert the first item to AFloat. if (item.Type == ATypes.AInteger) { item = Utils.ConvertToFloat(item); type = ATypes.AFloat; } if (item.Type != ATypes.AFloat) { throw new Error.Type(TypeErrorText); } } AType result = AArray.Create(type, item); for (int i = 1; i < argument.Length; i++) { //TODO: Is Clone method correct here? item = argument[i].NestedItem.Clone(); // Uniform rules! if (item.Type != type) { if (type == ATypes.AFloat && item.Type == ATypes.AInteger) { item = Utils.ConvertToFloat(item); } else { if (!type.MixedType() || !item.MixedType()) { throw new Error.Type(TypeErrorText); } } } if (item.Rank != rank) { throw new Error.Rank(RankErrorText); } if (!item.Shape.SequenceEqual(shape)) { throw new Error.Mismatch(MismatchErrorText); } result.AddWithNoUpdate(item); } result.Length = argument.Length; result.Shape = new List <int>() { result.Length }; result.Shape.AddRange(shape); result.Rank = 1 + rank; return(result); }