private void JumpToFunction() { AST_FunctionDefinitionNode functionDefinitionNode = (CurrentNode as AST_FunctionCall).FunctionDefinitionRef; string functionName = functionDefinitionNode.getChild(1).getTokenString(); int nrOfParameters = functionDefinitionNode.getChild(2).getChildren().Count; ReturnValue[] parameters = new ReturnValue[nrOfParameters]; for (int i = nrOfParameters - 1; i >= 0; i--) { parameters[i] = PopValue(); } if (m_externalFunctionCreator.externalFunctions.ContainsKey(functionName)) { //Console.WriteLine("Calling external function " + functionName); ExternalFunctionCreator.OnFunctionCall fc = m_externalFunctionCreator.externalFunctions[functionName]; ReturnValue rv = fc(parameters); if (rv.getReturnValueType() != ReturnValueType.VOID) { PushValue(rv); } } else { PushNewScope(functionDefinitionNode.getScope(), functionName + "_memorySpace" + functionCounter++, functionDefinitionNode); for (int i = nrOfParameters - 1; i >= 0; i--) { PushValue(parameters[i]); // reverse order } } }
public FunctionDefinition(string pReturnType, string pFunctionName, string[] pParameterTypes, string[] pParameterNames, ExternalFunctionCreator.OnFunctionCall pCallback, FunctionDocumentation pFunctionDocumentation) { returnType = pReturnType; functionName = pFunctionName; parameterTypes = pParameterTypes; parameterNames = pParameterNames; callback = pCallback; functionDocumentation = pFunctionDocumentation; }
public FunctionDefinition(string pReturnType, string pFunctionName, string[] pParameterTypes, string[] pParameterNames, ExternalFunctionCreator.OnFunctionCall pCallback, FunctionDocumentation pFunctionDocumentation) { returnType = pReturnType; functionName = pFunctionName; parameterTypes = pParameterTypes; parameterNames = pParameterNames; callback = pCallback; functionDocumentation = pFunctionDocumentation; }
private ReturnValue functionCall(AST tree) { ReturnValue returnValue = null; if (m_externalFunctionCreator.externalFunctions.ContainsKey(tree.getTokenString())) { ExternalFunctionCreator.OnFunctionCall functionCall = m_externalFunctionCreator.externalFunctions[tree.getTokenString()]; if (functionCall != null) { ReturnValue[] parameters = new ReturnValue[tree.getChildren().Count]; int i = 0; foreach (AST parameter in tree.getChildren()) { parameters[i] = execute(parameter); i++; } returnValue = functionCall(parameters); } else { throw new Error("Can't find external function " + tree.getTokenString(), Error.ErrorType.UNDEFINED, tree.getToken().LineNr, tree.getToken().LinePosition); } } else { // Call user defined function string functionName = tree.getTokenString(); AST functionTree = getFunctionTreeNode(functionName); Assert.IsNotNull(functionTree); // Create list of parameter values List <ReturnValue> parameterValues = new List <ReturnValue>(); List <AST> functionCallChildNodes = tree.getChildren(); if (functionCallChildNodes != null) { foreach (AST parameter in tree.getChildren()) { ReturnValue val = execute(parameter); parameterValues.Add(val); } } returnValue = function(functionTree, parameterValues); } return(returnValue); }
void CallExternalFunction(string pFunctionName, object[] pParameters) { // Console.WriteLine("Calling external function " + pFunctionName + " with parameters:"); // foreach (var p in pParameters) { // if (p == null) { // Console.WriteLine ("null"); // } else { // Console.WriteLine ("" + p); // } // } ExternalFunctionCreator.OnFunctionCall fc = m_externalFunctionCreator.externalFunctions[pFunctionName]; object rv = fc(pParameters); if (!(rv is VoidType)) { PushValue(rv); } }
public static FunctionDefinition[] CreateDefinitions(object o, Type t) { List <FunctionDefinition> methods = new List <FunctionDefinition>(); Dictionary <string, FunctionDocumentation> HelpInfo = new Dictionary <string, FunctionDocumentation>(); MethodInfo[] methodInfos = t.GetMethods(); foreach (MethodInfo methodI in methodInfos) { if (methodI.Name.StartsWith("API_")) { SprakAPI[] help = (SprakAPI[])methodI.GetCustomAttributes(typeof(SprakAPI), true); if (help.Length > 0) { //Console.WriteLine("found " + String.Join( ",", help[0].Values)); List <string> parameterHelp = new List <string>(); for (int i = 1; i < help[0].Values.Length; i++) { parameterHelp.Add(help[0].Values[i]); } string shortname = methodI.Name.Substring(4); FunctionDocumentation fd = new FunctionDocumentation(help[0].Values[0], parameterHelp.ToArray()); HelpInfo.Add(shortname, fd); } } } foreach (MethodInfo mi in methodInfos) { if (mi.Name.StartsWith("API_")) { //Console.WriteLine("parsing " + mi.Name + " return Type " + mi.ReturnType.Name); string shortname = mi.Name.Substring(4); if (mi.ReturnType.IsArray) { throw new Exception("FunctionDefinitionCreator can't handle array return value!"); } List <ReturnValueType> parameterTypes = new List <ReturnValueType>(); List <string> parameterNames = new List <string>(); List <string> parameterTypeNames = new List <string>(); foreach (ParameterInfo pi in mi.GetParameters()) { if (pi.ParameterType.IsArray) { throw new Exception("FunctionDefinitionCreator can't handle array parameters!"); } parameterNames.Add(pi.Name); parameterTypes.Add(ReturnValue.SystemTypeToReturnValueType(pi.ParameterType)); parameterTypeNames.Add(ReturnValue.SystemTypeToReturnValueType(pi.ParameterType).ToString().ToLower()); } MethodInfo lamdaMethodInfo = mi; ExternalFunctionCreator.OnFunctionCall function = (retvals) => { int i = 0; ParameterInfo[] realParamInfo = lamdaMethodInfo.GetParameters(); List <object> parameters = new List <object>(); foreach (ReturnValue r in retvals) { if (realParamInfo[i++].ParameterType == typeof(int)) { parameters.Add(Convert.ToInt32(r.Unpack())); } else { parameters.Add(r.Unpack()); } } //Console.WriteLine("supplied parameter count" + parameters.Count + " neededParamter count " + lamdaMethodInfo.GetParameters().Length); object result = lamdaMethodInfo.Invoke(o, parameters.ToArray()); if (lamdaMethodInfo.ReturnType == typeof(void)) { return(new ReturnValue(ReturnValueType.VOID)); } else { return(new ReturnValue(ReturnValue.SystemTypeToReturnValueType(lamdaMethodInfo.ReturnType), result)); } }; ReturnValueType returnValueType = ReturnValue.SystemTypeToReturnValueType(mi.ReturnType); FunctionDocumentation doc; if (HelpInfo.TryGetValue(shortname, out doc)) { methods.Add(new FunctionDefinition(returnValueType.ToString(), shortname, parameterTypeNames.ToArray(), parameterNames.ToArray(), function, doc)); } else { methods.Add(new FunctionDefinition(returnValueType.ToString(), shortname, parameterTypeNames.ToArray(), parameterNames.ToArray(), function, FunctionDocumentation.Default())); } } } return(methods.ToArray()); }
static List <FunctionDefinition> CreateFunctionDefinitions(object pProgramTarget, Dictionary <string, FunctionDocumentation> functionDocumentations, MethodInfo[] methodInfos) { List <FunctionDefinition> functionDefinitions = new List <FunctionDefinition>(); foreach (MethodInfo methodInfo in methodInfos) { if (!methodInfo.Name.StartsWith("API_")) { continue; } MethodInfo lambdaMethodInfo = methodInfo; // "hard copy" because of c# lambda rules string shortname = lambdaMethodInfo.Name.Substring(4); List <ReturnValueType> parameterTypes = new List <ReturnValueType> (); List <string> parameterNames = new List <string> (); List <string> parameterTypeNames = new List <string> (); foreach (ParameterInfo parameterInfo in lambdaMethodInfo.GetParameters()) { var t = ReturnValueConversions.SystemTypeToReturnValueType(parameterInfo.ParameterType); //Console.WriteLine("Registering parameter '" + parameterInfo.Name + "' (" + parameterInfo.ParameterType + ") with ReturnValueType " + t + " for function " + shortname); parameterNames.Add(parameterInfo.Name); parameterTypes.Add(t); parameterTypeNames.Add(t.ToString().ToLower()); } ExternalFunctionCreator.OnFunctionCall function = (sprakArguments => { ParameterInfo[] realParamInfo = lambdaMethodInfo.GetParameters(); if (sprakArguments.Count() != realParamInfo.Length) { throw new Error("Should call '" + shortname + "' with " + realParamInfo.Length + " argument" + (realParamInfo.Length == 1 ? "" : "s")); } int i = 0; foreach (object sprakArg in sprakArguments) { //Console.WriteLine(string.Format("Parameter {0} in function {1} is of type {2}", i, shortname, realParamInfo[i].ParameterType)); var realParamType = realParamInfo [i].ParameterType; if (sprakArg.GetType() == typeof(SortedDictionary <KeyWrapper, object>)) { sprakArguments[i] = (sprakArg as SortedDictionary <KeyWrapper, object>).Values.ToArray(); } if (sprakArg.GetType() == typeof(int)) { // YES, this is kind of a HACK (allowing definitions with int arguments, making them work like the were floats. Remove later! sprakArguments[i] = (float)sprakArg; realParamType = typeof(int); } if (acceptableTypes.Contains(realParamType)) { // OK } else { throw new Error("Can't deal with parameter " + i.ToString() + " of type " + realParamType + " in function " + shortname); } i++; } //Console.WriteLine("supplied parameter count" + parameters.Count + " neededParamter count " + lamdaMethodInfo.GetParameters().Length); object result = null; try { /* * Console.WriteLine("Will call " + shortname + " with sprak arguments:"); * int j = 0; * foreach(var a in sprakArguments) { * Console.WriteLine(" Argument " + (j++) + ": " + ReturnValueConversions.PrettyStringRepresenation(a) + " (" + a.GetType() + ")"); * } */ result = lambdaMethodInfo.Invoke(pProgramTarget, sprakArguments.ToArray()); } catch (System.Reflection.TargetInvocationException e) { //Console.WriteLine("Got an exception when calling the lambda: " + e.ToString()); //Console.WriteLine("The base exception: " + e.GetBaseException().ToString()); throw e.GetBaseException(); } // HACK if (lambdaMethodInfo.ReturnType == typeof(int)) { return((float)(int)result); } if (lambdaMethodInfo.ReturnType.IsSubclassOf(typeof(Array))) { var dictArray = new SortedDictionary <KeyWrapper, object>(); int j = 0; foreach (var o in (Array)result) { //Console.WriteLine(" - " + o.ToString()); dictArray.Add(new KeyWrapper((float)j++), o); } //Console.WriteLine("Converted object[] to SortedDictionary when returning from " + shortname + ": " + ReturnValueConversions.PrettyStringRepresenation(dictArray)); return(dictArray); } if (!acceptableTypes.Contains(lambdaMethodInfo.ReturnType)) { throw new Error("Function '" + shortname + "' can't return value of type " + lambdaMethodInfo.ReturnType.ToString()); } if (lambdaMethodInfo.ReturnType == typeof(void)) { //Console.WriteLine("Returning void from " + shortname); return(VoidType.voidType); } else { //Console.WriteLine("Returning from " + shortname + ": " + ReturnValueConversions.PrettyStringRepresenation(result)); return(result); } }); ReturnValueType returnValueType = ReturnValueConversions.SystemTypeToReturnValueType(lambdaMethodInfo.ReturnType); FunctionDocumentation doc; if (functionDocumentations.ContainsKey(shortname)) { doc = functionDocumentations [shortname]; } else { doc = FunctionDocumentation.Default(); } functionDefinitions.Add(new FunctionDefinition( returnValueType.ToString(), shortname, parameterTypeNames.ToArray(), parameterNames.ToArray(), function, // The lambda doc)); } return(functionDefinitions); }