Esempio n. 1
0
        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
                }
            }
        }
Esempio n. 2
0
 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;
 }
Esempio n. 3
0
 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;
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }