static int?InvokeFunction(string name, System.Collections.IList arguments, NodeResolver document) { var finalArgs = new List <int?>(); var func = GetFunction(name); if (func == null) { return(null); } int paramCount = func.Parameters.Count; if (func.IsVariadic) { paramCount--; } if (arguments.Count < paramCount) { TrackerErrorLog.LogError("Function " + func.Name + " called with only " + arguments.Count + "arguments."); } if (arguments.Count > paramCount && !func.IsVariadic) { TrackerErrorLog.LogError("Function " + func.Name + " called with too many arguments."); } for (int i = 0; i < arguments.Count; i++) { finalArgs.Add(EvaluateArg(arguments[i], document)); } while (finalArgs.Count < paramCount) { finalArgs.Add(null); } return(func.Executor(finalArgs)); }
private static int?EvaluateArg(object arg, NodeResolver document) { if (arg == null) { return(null); } if (arg is int?) { return((int?)arg); } if (arg is int) { return((int)arg); } if (arg is JToken) { if (arg is JObject) { var jArg = (JObject)arg; if (jArg.Count != 1) { TrackerErrorLog.LogError("Invalid object. Only one child allowed."); return(null); } string funcName = null; JToken argList = null; // It's kind of dumb that you can't just numerically index the properties foreach (var p in jArg.Properties()) { funcName = p.Name; argList = p.Value; if (!(argList is JArray)) { TrackerErrorLog.LogError("Function parameters must be passed into an array."); return(null); } if (funcName.Length == 0 || funcName[0] != '@') { TrackerErrorLog.LogError("Unexpected object. If this is supposed to be a function, prefix \"" + funcName + "\" with \"@\"."); return(null); } funcName = funcName.Substring(1); } return(InvokeFunction(funcName, (JArray)argList, document)); } else { var jArg = (JToken)arg; if (jArg.Type == JTokenType.String) { // Document property reference return((int)document((string)jArg)); } else if (jArg.Type == JTokenType.Integer) { return((int)jArg); } } } TrackerErrorLog.LogError("Invalid argument type: " + arg.GetType().ToString()); if (arg is int) { return((int)arg); } return(null); }