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