Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 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");
             }
         }
     }
 }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
 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");
             }
         }
     }
 }
Exemplo n.º 7
0
        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;
        }
Exemplo n.º 8
0
        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;
        }