Example #1
0
        public override HeronValue As(HeronType t)
        {
            if (type.name == t.name)
            {
                return(obj);
            }

            if (type is ClassDefn)
            {
                ClassInstance inst = obj as ClassInstance;
                if (inst == null)
                {
                    throw new Exception("Expected an instance of a class");
                }
                return(inst.As(t));
            }
            else if (type is InterfaceDefn)
            {
                InterfaceInstance ii = obj as InterfaceInstance;
                if (ii == null)
                {
                    throw new Exception("Expected an instance of an interface");
                }
                return(ii.As(t));
            }
            else if (type is DotNetClass)
            {
                if (!(t is DotNetClass))
                {
                    throw new Exception("External objects can only be cast to the type 'DotNetClass'");
                }

                if (t.Equals(type))
                {
                    return(obj);
                }
            }
            else if (t.name == "Any")
            {
                return(this);
            }
            else
            {
                Type from = type.GetSystemType();
                Type to   = t.GetSystemType();

                if (from != null && to != null && to.IsAssignableFrom(from))
                {
                    return(obj);
                }
            }

            return(null);
        }
Example #2
0
        public override HeronValue As(HeronType t)
        {
            if (type.name == t.name)
                return obj;

            if (type is ClassDefn)
            {
                ClassInstance inst = obj as ClassInstance;
                if (inst == null)
                    throw new Exception("Expected an instance of a class");
                return inst.As(t);
            }
            else if (type is InterfaceDefn)
            {
                InterfaceInstance ii = obj as InterfaceInstance;
                if (ii == null)
                    throw new Exception("Expected an instance of an interface");
                return ii.As(t);
            }
            else if (type is DotNetClass)
            {
                if (!(t is DotNetClass))
                    throw new Exception("External objects can only be cast to the type 'DotNetClass'");

                if (t.Equals(type))
                    return obj;
            }
            else if (t.name == "Any")
            {
                return this;
            }
            else 
            {
                Type from = type.GetSystemType();
                Type to = t.GetSystemType();

                if (from != null && to != null && to.IsAssignableFrom(from))
                    return obj;
            }

            return null;
        }
        /// <summary>
        /// Given a list of arguments, it looks at the types and tries to find out which function
        /// in this list is the best match.
        /// </summary>
        /// <param name="list"></param>
        /// <param name="funcs"></param>
        /// <returns></returns>
        public FunctionValue FindBestMatch(List <FunctionValue> list, HeronValue[] args)
        {
            // Each iteration removes candidates. This list holds all of the matches
            // Necessary, because removing items from a list while we iterate it is hard.
            List <FunctionValue> tmp = new List <FunctionValue>(list);

            for (int pos = 0; pos < args.Length; ++pos)
            {
                // On each iteration, update the main list, to only contain the remaining items
                list = new List <FunctionValue>(tmp);
                HeronValue arg = args[pos];
                HeronType  argType;
                if (arg is AnyValue)
                {
                    argType = (arg as AnyValue).GetHeldType();
                }
                else
                {
                    argType = arg.Type;
                }
                for (int i = 0; i < list.Count; ++i)
                {
                    FunctionValue fo         = list[i];
                    HeronType     formalType = fo.GetFormalType(pos);
                    if (!formalType.Equals(argType))
                    {
                        tmp.Remove(fo);
                    }
                }
                if (tmp.Count == 0)
                {
                    throw new Exception("Could not resolve function " + name + " no function matches perfectly");
                }

                // We found a single best match
                if (tmp.Count == 1)
                {
                    return(tmp[0]);
                }
            }

            Debug.Assert(tmp.Count > 1);

            // There are multiple functions
            // Choose the function which is the most derived type.
            // This is a pretty awful hack to make up for a bad design.
            int           n    = 0;
            FunctionValue best = null;

            foreach (FunctionValue fv in list)
            {
                int depth = fv.GetDefn().parent.GetHierarchyDepth();
                if (depth > n)
                {
                    n    = depth;
                    best = fv;
                }
                else if (depth == n)
                {
                    // Ambiguous match at this depth.
                    best = null;
                }
            }

            if (best == null)
            {
                throw new Exception("Ambiguous function match");
            }

            return(best);
        }