/// <summary> /// Generates a series of BoxedValue[] handlers for overloaded functions. /// </summary> /// <param name="sorted">The sorted function list.</param> private void GenerateBoxedValueFunctions(FunctionListSorted sorted) { foreach (string n in sorted.NonUniqueNames) { List<FunctionInfo> variants = sorted.NonUniqueFunctions.Where(f => (f.Name == n)).ToList(); AutoBoxedDelegate handler = (parameters) => { foreach (FunctionInfo v in variants) { // Check to see if the parameter count is the same. if (v.ParameterTypes.Length != parameters.Length) continue; // Check to see if the types match. int i; for (i = 0; i < parameters.Length; i += 1) { try { object o = typeof(BoxedValue) .GetMethod("Unbox") .MakeGenericMethod(v.ParameterTypes[i]) .Invoke(parameters[i], null); } catch (InvalidCastException) { // We couldn't cast it. break; } catch (TargetInvocationException) { // We couldn't cast it. break; } } if (i != parameters.Length) // We didn't validate all parameters. continue; // At this point we pass all the requirements, so invoke // the function. return v.Function.Call(this, parameters); } // There was no function to handle this. throw new NullReferenceException(); }; this.Put(n, Utils.createHostFunction<AutoBoxedDelegate>(this.Env, handler)); } }
/// <summary> /// Go through a list of functions and sort them into unique functions (for which /// there is a single definitions) and non-unique functions (for which there are /// multiple definitions with varying arguments or return types). /// </summary> /// <param name="functions">The list of functions to sort.</param> /// <returns>The sorted function lists.</returns> private FunctionListSorted SortFunctions(List<FunctionInfo> functions) { FunctionListSorted result = new FunctionListSorted(); foreach (FunctionInfo fi in functions) { if (result.UniqueNames.Contains(fi.Name)) { // There was previously one instance of this function, but // we found a second one, so we need to move the old one into // nonUniqueFunctions and the name into nonUniqueNames. result.UniqueNames.Remove(fi.Name); result.NonUniqueNames.Add(fi.Name); FunctionInfo fii = result.UniqueFunctions.Where(f => (f.Name == fi.Name)).First(); result.UniqueFunctions.Remove(fii); result.NonUniqueFunctions.Add(fii); result.NonUniqueFunctions.Add(fi); } else if (result.NonUniqueNames.Contains(fi.Name)) { // We already know this is a non-unique function. result.NonUniqueFunctions.Add(fi); } else { // Assume it's a unique function. result.UniqueNames.Add(fi.Name); result.UniqueFunctions.Add(fi); } } return result; }