private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List <FunctionDefinition> allFunctionDefinitions = new List <FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); // HasFunction requires a reference to the SprakRunner FunctionDocumentation functionDoc_HasFunction = new FunctionDocumentation("Check if a function exists on the object", new string[] { "The name of the function" }); allFunctionDefinitions.Add(new FunctionDefinition("bool", "HasFunction", new string[] { "string" }, new string[] { "functionName" }, new ExternalFunctionCreator.OnFunctionCall(API_hasFunction), functionDoc_HasFunction)); FunctionDocumentation functionDoc_ListFunctions = new FunctionDocumentation("List all functions on the object", new string[] { }); allFunctionDefinitions.Add(new FunctionDefinition("array", "ListFunctions", new string[] { }, new string[] { }, new ExternalFunctionCreator.OnFunctionCall(API_listFunction), functionDoc_ListFunctions)); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return(externalFunctionCreator); }
static Dictionary <string, FunctionDocumentation> CreateDocumentation(MethodInfo[] methodInfos) { Dictionary <string, FunctionDocumentation> functionDocumentations = new Dictionary <string, FunctionDocumentation>(); foreach (MethodInfo methodInfo in methodInfos) { //Log("Found method " + methodInfo.Name); if (methodInfo.Name.StartsWith("API_")) { SprakAPI[] helpAttributes = (SprakAPI[])methodInfo.GetCustomAttributes(typeof(SprakAPI), true); if (helpAttributes.Length > 0) { //Console.WriteLine("found " + String.Join( ",", help[0].Values)); List <string> parameterHelp = new List <string> (); for (int i = 1; i < helpAttributes [0].Values.Length; i++) { parameterHelp.Add(helpAttributes [0].Values [i]); } string shortname = methodInfo.Name.Substring(4); FunctionDocumentation fd = new FunctionDocumentation(helpAttributes [0].Values [0], parameterHelp.ToArray()); functionDocumentations.Add(shortname, fd); } } } return(functionDocumentations); }
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 static List <FunctionDefinition> __CreateBuiltInFunctionDefinitions() { List <FunctionDefinition> result = new List <FunctionDefinition>(); FunctionDocumentation functionDoc_count = new FunctionDocumentation("Count the number of elements in an array", new string[] { "The array" }); result.Add(new FunctionDefinition("number", "count", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_count), functionDoc_count)); FunctionDocumentation functionDoc_allocate = new FunctionDocumentation("Create a new array with X number of elements", new string[] { "How many elements the array should hold" }); result.Add(new FunctionDefinition("number", "allocate", new string[] { "number" }, new string[] { "X" }, new ExternalFunctionCreator.OnFunctionCall(API_allocate), functionDoc_allocate)); FunctionDocumentation functionDoc_range = new FunctionDocumentation("Create a new array that contains a range of numbers", new string[] { "The start value of the range", "The end value of the range" }); result.Add(new FunctionDefinition("number", "range", new string[] { "number", "number" }, new string[] { "min", "max" }, new ExternalFunctionCreator.OnFunctionCall(API_range), functionDoc_range)); FunctionDocumentation functionDoc_toArray = new FunctionDocumentation("Convert something to an array", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("array", "toArray", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toArray), functionDoc_toArray)); FunctionDocumentation functionDoc_toNumber = new FunctionDocumentation("Convert something to a number", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("number", "toNumber", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toNumber), functionDoc_toNumber)); FunctionDocumentation functionDoc_toString = new FunctionDocumentation("Convert something to a string", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("string", "toString", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toString), functionDoc_toString)); FunctionDocumentation functionDoc_toBool = new FunctionDocumentation("Convert something to a bool", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("bool", "toBool", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toBool), functionDoc_toBool)); FunctionDocumentation functionDoc_getIndexes = new FunctionDocumentation("Create a new array that contains the indexes of another array", new string[] { "The array with indexes" }); result.Add(new FunctionDefinition("array", "getIndexes", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_createArrayOfArrayIndexes), functionDoc_getIndexes)); FunctionDocumentation functionDoc_removeElement = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The position in the array to remove (starts at 0)" }); result.Add(new FunctionDefinition("void", "removeElement", new string[] { "array", "number" }, new string[] { "array", "position" }, new ExternalFunctionCreator.OnFunctionCall(API_removeElement), functionDoc_removeElement)); FunctionDocumentation functionDoc_type = new FunctionDocumentation("Get the type of something (returns a string)", new string[] { "The value to get the type of" }); result.Add(new FunctionDefinition("string", "type", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_type), functionDoc_type)); return(result); }
public DefaultSprakRunner(TextReader stream) { FunctionDefinition[] functionDefinitions = new FunctionDefinition[] { new FunctionDefinition("void", "print", new string[] { "string" }, new string[] { "text" }, new ExternalFunctionCreator.OnFunctionCall(print), FunctionDocumentation.Default()), new FunctionDefinition("number", "sqrt", new string[] { "number" }, new string[] { "f" }, new ExternalFunctionCreator.OnFunctionCall(sqrt), FunctionDocumentation.Default()) }; m_sprakRunner = new SprakRunner(stream, functionDefinitions); }
private static List<FunctionDefinition> __CreateBuiltInFunctionDefinitions() { List<FunctionDefinition> result = new List<FunctionDefinition>(); FunctionDocumentation functionDoc_count = new FunctionDocumentation("Count the number of elements in an array", new string[] { "The array" }); result.Add(new FunctionDefinition("number", "count", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_count), functionDoc_count)); FunctionDocumentation functionDoc_allocate = new FunctionDocumentation("Create a new array with X number of elements", new string[] { "How many elements the array should hold" }); result.Add(new FunctionDefinition("number", "allocate", new string[] { "number" }, new string[] { "X" }, new ExternalFunctionCreator.OnFunctionCall(API_allocate), functionDoc_allocate)); FunctionDocumentation functionDoc_range = new FunctionDocumentation("Create a new array that contains a range of numbers", new string[] { "The start value of the range", "The end value of the range" }); result.Add(new FunctionDefinition("number", "range", new string[] { "number", "number" }, new string[] { "min", "max" }, new ExternalFunctionCreator.OnFunctionCall(API_range), functionDoc_range)); FunctionDocumentation functionDoc_toArray = new FunctionDocumentation("Convert something to an array", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("array", "toArray", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toArray), functionDoc_toArray)); FunctionDocumentation functionDoc_toNumber = new FunctionDocumentation("Convert something to a number", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("number", "toNumber", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toNumber), functionDoc_toNumber)); FunctionDocumentation functionDoc_toString = new FunctionDocumentation("Convert something to a string", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("string", "toString", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toString), functionDoc_toString)); FunctionDocumentation functionDoc_toBool = new FunctionDocumentation("Convert something to a bool", new string[] { "The value to convert" }); result.Add(new FunctionDefinition("bool", "toBool", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toBool), functionDoc_toBool)); FunctionDocumentation functionDoc_getIndexes = new FunctionDocumentation("Create a new array that contains the indexes of another array", new string[] { "The array with indexes" }); result.Add(new FunctionDefinition("array", "getIndexes", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_createArrayOfArrayIndexes), functionDoc_getIndexes)); FunctionDocumentation functionDoc_removeElement = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The position in the array to remove (starts at 0)" }); result.Add(new FunctionDefinition("void", "removeElement", new string[] { "array", "number" }, new string[] { "array", "position" }, new ExternalFunctionCreator.OnFunctionCall(API_removeElement), functionDoc_removeElement)); FunctionDocumentation functionDoc_type = new FunctionDocumentation("Get the type of something (returns a string)", new string[] { "The value to get the type of" }); result.Add(new FunctionDefinition("string", "type", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_type), functionDoc_type)); return result; }
private static List <FunctionDefinition> __CreateBuiltInFunctionDefinitions() { List <FunctionDefinition> result = new List <FunctionDefinition>(); FunctionDocumentation functionDoc_Count = new FunctionDocumentation("Count the number of elements in an array", new string[] { "The array" }); result.Add(new FunctionDefinition("number", "Count", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_count), functionDoc_Count)); // Need an add-function???! // FunctionDocumentation functionDoc_add = // new FunctionDocumentation("Add an element to the end of the array", new string[] { "The element" }); // result.Add(new FunctionDefinition("array", "add", new string[] { "var" }, new string[] { "element" }, new ExternalFunctionCreator.OnFunctionCall(API_add), functionDoc_add)); // FunctionDocumentation functionDoc_allocate = // new FunctionDocumentation("Create a new array with X number of elements", new string[] { "How many elements the array should hold" }); // result.Add(new FunctionDefinition("number", "allocate", new string[] { "number" }, new string[] { "X" }, new ExternalFunctionCreator.OnFunctionCall(API_allocate), functionDoc_allocate)); FunctionDocumentation functionDoc_Range = new FunctionDocumentation("Create a range of numbers from 'min' to (and including) 'max'", new string[] { "The start value of the range", "The end value of the range" }); result.Add(new FunctionDefinition("number", "Range", new string[] { "number", "number" }, new string[] { "min", "max" }, new ExternalFunctionCreator.OnFunctionCall(API_range), functionDoc_Range)); // FunctionDocumentation functionDoc_toArray = // new FunctionDocumentation("Convert something to an array", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("array", "toArray", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toArray), functionDoc_toArray)); // // FunctionDocumentation functionDoc_toNumber = // new FunctionDocumentation("Convert something to a number", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("number", "toNumber", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toNumber), functionDoc_toNumber)); // // FunctionDocumentation functionDoc_toString = // new FunctionDocumentation("Convert something to a string", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("string", "toString", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toString), functionDoc_toString)); // // FunctionDocumentation functionDoc_toBool = // new FunctionDocumentation("Convert something to a bool", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("bool", "toBool", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toBool), functionDoc_toBool)); FunctionDocumentation functionDoc_GetIndexes = new FunctionDocumentation("Create a new array that contains the indexes of another array", new string[] { "The array with indexes" }); result.Add(new FunctionDefinition("array", "GetIndexes", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_createArrayOrRangeOfIndexes), functionDoc_GetIndexes)); FunctionDocumentation functionDoc_RemoveElement = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The index in the array to remove" }); result.Add(new FunctionDefinition("void", "Remove", new string[] { "array", "number" }, new string[] { "array", "position" }, new ExternalFunctionCreator.OnFunctionCall(API_removeElement), functionDoc_RemoveElement)); FunctionDocumentation functionDoc_RemoveAllElements = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The index in the array to remove" }); result.Add(new FunctionDefinition("void", "RemoveAll", new string[] { "array" }, new string[] { "array" }, new ExternalFunctionCreator.OnFunctionCall(API_removeAllElements), functionDoc_RemoveAllElements)); FunctionDocumentation functionDoc_HasIndex = new FunctionDocumentation("Check if an index is in the array", new string[] { "The array to check in", "The index to check for in the array" }); result.Add(new FunctionDefinition("bool", "HasIndex", new string[] { "array", "var" }, new string[] { "array", "key" }, new ExternalFunctionCreator.OnFunctionCall(API_hasKey), functionDoc_HasIndex)); FunctionDocumentation functionDoc_Append = new FunctionDocumentation("Add an element to the end of an array", new string[] { "The array to add an element to", "The element to add" }); result.Add(new FunctionDefinition("void", "Append", new string[] { "array", "var" }, new string[] { "array", "elem" }, new ExternalFunctionCreator.OnFunctionCall(API_append), functionDoc_Append)); #if TYPE_FUNCTION FunctionDocumentation functionDoc_type = new FunctionDocumentation("Get the type of something (returns a string)", new string[] { "The value to get the type of" }); result.Add(new FunctionDefinition("string", "Type", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_type), functionDoc_type)); #endif FunctionDocumentation functionDoc_Round = new FunctionDocumentation("Round a number to the nearest integer", new string[] { "The number to round" }); result.Add(new FunctionDefinition("number", "Round", new string[] { "var" }, new string[] { "x" }, new ExternalFunctionCreator.OnFunctionCall(API_round), functionDoc_Round)); FunctionDocumentation functionDoc_Int = new FunctionDocumentation("Remove the decimals of a float", new string[] { "The number to convert to an integer" }); result.Add(new FunctionDefinition("number", "Int", new string[] { "var" }, new string[] { "x" }, new ExternalFunctionCreator.OnFunctionCall(API_int), functionDoc_Int)); FunctionDocumentation functionDoc_Mod = new FunctionDocumentation("Get the remainder of x / y", new string[] { "x", "y" }); result.Add(new FunctionDefinition("number", "Mod", new string[] { "var", "var" }, new string[] { "x", "y" }, new ExternalFunctionCreator.OnFunctionCall(API_mod), functionDoc_Mod)); return(result); }
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()); }
private static List<FunctionDefinition> __CreateBuiltInFunctionDefinitions() { List<FunctionDefinition> result = new List<FunctionDefinition>(); FunctionDocumentation functionDoc_Count = new FunctionDocumentation("Count the number of elements in an array", new string[] { "The array" }); result.Add(new FunctionDefinition("number", "Count", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_count), functionDoc_Count)); // Need an add-function???! // FunctionDocumentation functionDoc_add = // new FunctionDocumentation("Add an element to the end of the array", new string[] { "The element" }); // result.Add(new FunctionDefinition("array", "add", new string[] { "var" }, new string[] { "element" }, new ExternalFunctionCreator.OnFunctionCall(API_add), functionDoc_add)); // FunctionDocumentation functionDoc_allocate = // new FunctionDocumentation("Create a new array with X number of elements", new string[] { "How many elements the array should hold" }); // result.Add(new FunctionDefinition("number", "allocate", new string[] { "number" }, new string[] { "X" }, new ExternalFunctionCreator.OnFunctionCall(API_allocate), functionDoc_allocate)); FunctionDocumentation functionDoc_Range = new FunctionDocumentation("Create a range of numbers from 'min' to (and including) 'max'", new string[] { "The start value of the range", "The end value of the range" }); result.Add(new FunctionDefinition("number", "Range", new string[] { "number", "number" }, new string[] { "min", "max" }, new ExternalFunctionCreator.OnFunctionCall(API_range), functionDoc_Range)); // FunctionDocumentation functionDoc_toArray = // new FunctionDocumentation("Convert something to an array", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("array", "toArray", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toArray), functionDoc_toArray)); // // FunctionDocumentation functionDoc_toNumber = // new FunctionDocumentation("Convert something to a number", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("number", "toNumber", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toNumber), functionDoc_toNumber)); // // FunctionDocumentation functionDoc_toString = // new FunctionDocumentation("Convert something to a string", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("string", "toString", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toString), functionDoc_toString)); // // FunctionDocumentation functionDoc_toBool = // new FunctionDocumentation("Convert something to a bool", new string[] { "The value to convert" }); // result.Add(new FunctionDefinition("bool", "toBool", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_toBool), functionDoc_toBool)); FunctionDocumentation functionDoc_GetIndexes = new FunctionDocumentation("Create a new array that contains the indexes of another array", new string[] { "The array with indexes" }); result.Add(new FunctionDefinition("array", "GetIndexes", new string[] { "array" }, new string[] { "a" }, new ExternalFunctionCreator.OnFunctionCall(API_createArrayOrRangeOfIndexes), functionDoc_GetIndexes)); FunctionDocumentation functionDoc_RemoveElement = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The index in the array to remove" }); result.Add(new FunctionDefinition("void", "Remove", new string[] { "array", "number" }, new string[] { "array", "position" }, new ExternalFunctionCreator.OnFunctionCall(API_removeElement), functionDoc_RemoveElement)); FunctionDocumentation functionDoc_RemoveAllElements = new FunctionDocumentation("Remove an element from an array", new string[] { "The array to remove an element from", "The index in the array to remove" }); result.Add(new FunctionDefinition("void", "RemoveAll", new string[] { "array" }, new string[] { "array" }, new ExternalFunctionCreator.OnFunctionCall(API_removeAllElements), functionDoc_RemoveAllElements)); FunctionDocumentation functionDoc_HasIndex = new FunctionDocumentation("Check if an index is in the array", new string[] { "The array to check in", "The index to check for in the array" }); result.Add(new FunctionDefinition("bool", "HasIndex", new string[] { "array", "var" }, new string[] { "array", "key" }, new ExternalFunctionCreator.OnFunctionCall(API_hasKey), functionDoc_HasIndex)); FunctionDocumentation functionDoc_Append = new FunctionDocumentation("Add an element to the end of an array", new string[] { "The array to add an element to", "The element to add" }); result.Add(new FunctionDefinition("void", "Append", new string[] { "array", "var" }, new string[] { "array", "elem" }, new ExternalFunctionCreator.OnFunctionCall(API_append), functionDoc_Append)); #if TYPE_FUNCTION FunctionDocumentation functionDoc_type = new FunctionDocumentation("Get the type of something (returns a string)", new string[] { "The value to get the type of" }); result.Add(new FunctionDefinition("string", "type", new string[] { "var" }, new string[] { "value" }, new ExternalFunctionCreator.OnFunctionCall(API_type), functionDoc_type)); #endif FunctionDocumentation functionDoc_Round = new FunctionDocumentation("Round a number to the nearest integer", new string[] { "The number to round" }); result.Add(new FunctionDefinition("number", "Round", new string[] { "var" }, new string[] { "x" }, new ExternalFunctionCreator.OnFunctionCall(API_round), functionDoc_Round)); FunctionDocumentation functionDoc_Int = new FunctionDocumentation("Remove the decimals of a float", new string[] { "The number to convert to an integer" }); result.Add(new FunctionDefinition("number", "Int", new string[] { "var" }, new string[] { "x" }, new ExternalFunctionCreator.OnFunctionCall(API_int), functionDoc_Int)); FunctionDocumentation functionDoc_Mod = new FunctionDocumentation("Remove the decimals of a float", new string[] { "Get the remainder of x / y" }); result.Add(new FunctionDefinition("number", "Mod", new string[] { "var", "var" }, new string[] { "x", "y" }, new ExternalFunctionCreator.OnFunctionCall(API_mod), functionDoc_Mod)); return result; }
private ExternalFunctionCreator AddExternalFunctions(FunctionDefinition[] functionDefinitions, AST ast) { List<FunctionDefinition> allFunctionDefinitions = new List<FunctionDefinition>(); allFunctionDefinitions.AddRange(builtInFunctions); allFunctionDefinitions.AddRange(functionDefinitions); // HasFunction requires a reference to the SprakRunner FunctionDocumentation functionDoc_HasFunction = new FunctionDocumentation("Check if a function exists on the object", new string[] { "The name of the function" }); allFunctionDefinitions.Add(new FunctionDefinition("bool", "HasFunction", new string[] { "string" }, new string[] { "functionName" }, new ExternalFunctionCreator.OnFunctionCall(API_hasFunction), functionDoc_HasFunction)); ExternalFunctionCreator externalFunctionCreator = new ExternalFunctionCreator(allFunctionDefinitions.ToArray()); AST functionList = ast.getChild(1); foreach (AST externalFunction in externalFunctionCreator.FunctionASTs) { functionList.addChild(externalFunction); } return externalFunctionCreator; }
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); }