public AType Execute(AType function, AType n, AType right, AType left, Aplus environment = null) { if (!(function.Data is AFunc)) { throw new Error.NonFunction("Rank"); } AFunc func = (AFunc)function.Data; if (!func.IsBuiltin) { if (func.Valence - 1 != 2) { throw new Error.Valence("Rank"); } } int[] rankSpecifier = GetRankSpecifier(n, left, right, environment); RankJobInfo rankInfo = new RankJobInfo(rankSpecifier, func); AType result = Walker(left, right, environment, rankInfo); if (rankInfo.FloatConvert && result.IsArray) { result.ConvertToFloat(); } return(result); }
public AType Execute(AType function, AType n, AType right, AType left, Aplus environment = null) { if (!(function.Data is AFunc)) { throw new Error.NonFunction("Rank"); } AFunc func = (AFunc)function.Data; if (!func.IsBuiltin) { if (func.Valence - 1 != 2) { throw new Error.Valence("Rank"); } } int[] rankSpecifier = GetRankSpecifier(n, left, right, environment); RankJobInfo rankInfo = new RankJobInfo(rankSpecifier, func); AType result = Walker(left, right, environment, rankInfo); if (rankInfo.FloatConvert && result.IsArray) { result.ConvertToFloat(); } return result; }
private AType LeftSideWalk(AType left, AType right, Aplus environment, RankJobInfo rankInfo) { AType result = AArray.Create(ATypes.ANull); AType temp; foreach (AType item in left) { temp = Walker(item, right, environment, rankInfo); TypeCheck(temp.Type, rankInfo); result.AddWithNoUpdate(temp); } return(result); }
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"); } } } }
private AType Walker(AType left, AType right, Aplus environment, RankJobInfo rankInfo) { int tx = Math.Min(rankInfo.RankSpecifier[2], right.Rank - rankInfo.RankSpecifier[1]); int ty = Math.Min(rankInfo.RankSpecifier[2], left.Rank - rankInfo.RankSpecifier[0]); int lx = Math.Max(0, right.Rank - (rankInfo.RankSpecifier[1] + tx)); int ly = Math.Max(0, left.Rank - (rankInfo.RankSpecifier[0] + ty)); AType result; if (ly > 0) { result = LeftSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else if (lx > 0) { result = RightSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else if (ty != tx) { result = (ty > tx) ? LeftSideWalk(left, right, environment, rankInfo) : RightSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else { if (ty > 0) { List <int> tyShape = left.Shape.GetRange(0, ty); List <int> txShape = right.Shape.GetRange(0, tx); if (!tyShape.SequenceEqual(txShape)) { throw new Error.Mismatch("Rank"); } } if (ty != 0) { result = AArray.Create(ATypes.ANull); AType temp; for (int i = 0; i < left.Length; i++) { temp = Walker(left[i], right[i], environment, rankInfo); TypeCheck(temp.Type, rankInfo); result.AddWithNoUpdate(temp); } result.UpdateInfo(); } else { result = rankInfo.Method(environment, right, left); } } return(result); }
private AType LeftSideWalk(AType left, AType right, Aplus environment, RankJobInfo rankInfo) { AType result = AArray.Create(ATypes.ANull); AType temp; foreach (AType item in left) { temp = Walker(item, right, environment, rankInfo); TypeCheck(temp.Type, rankInfo); result.AddWithNoUpdate(temp); } return result; }
private AType Walker(AType left, AType right, Aplus environment, RankJobInfo rankInfo) { int tx = Math.Min(rankInfo.RankSpecifier[2], right.Rank - rankInfo.RankSpecifier[1]); int ty = Math.Min(rankInfo.RankSpecifier[2], left.Rank - rankInfo.RankSpecifier[0]); int lx = Math.Max(0, right.Rank - (rankInfo.RankSpecifier[1] + tx)); int ly = Math.Max(0, left.Rank - (rankInfo.RankSpecifier[0] + ty)); AType result; if (ly > 0) { result = LeftSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else if (lx > 0) { result = RightSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else if (ty != tx) { result = (ty > tx) ? LeftSideWalk(left, right, environment, rankInfo) : RightSideWalk(left, right, environment, rankInfo); result.UpdateInfo(); } else { if (ty > 0) { List<int> tyShape = left.Shape.GetRange(0, ty); List<int> txShape = right.Shape.GetRange(0, tx); if (!tyShape.SequenceEqual(txShape)) { throw new Error.Mismatch("Rank"); } } if (ty != 0) { result = AArray.Create(ATypes.ANull); AType temp; for (int i = 0; i < left.Length; i++) { temp = Walker(left[i], right[i], environment, rankInfo); TypeCheck(temp.Type, rankInfo); result.AddWithNoUpdate(temp); } result.UpdateInfo(); } else { result = rankInfo.Method(environment, right, left); } } return result; }