Example #1
0
        object ExecuteFunction(Command cmd, object instance, bool useDefaultVar)
        {
            object result   = null;
            string origName = ((Literal)cmd.Args[0]).Value;

            string assemblyName = null;
            string className    = null;
            string methodName   = null;

            string[] splitName = origName.ToLowerInvariant().Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
            if (splitName.Length == 1)
            {
                methodName = splitName[0];
            }
            else if (splitName.Length == 2)
            {
                className  = splitName[0];
                methodName = splitName[1];
            }
            else if (splitName.Length == 3)
            {
                assemblyName = splitName[0];
                className    = splitName[1];
                methodName   = splitName[2];
            }
            else
            {
                throw new Exception("Invalid function name: " + origName + "()");
            }

            if (methodName == LoadPluginName)
            {
                string path;
                if (useDefaultVar)
                {
                    path = (string)defaultVar;
                }
                else
                {
                    path = (string)ExecuteExpr(cmd.Args[1]);
                }
                PluginManager.LoadPlugin(path);
            }
            else if (methodName == ImportName)
            {
                string path;
                if (useDefaultVar)
                {
                    path = (string)defaultVar;
                }
                else
                {
                    path = (string)ExecuteExpr(cmd.Args[1]);
                }
                ScriptParser parser  = new ScriptParser(path);
                string       prevCWD = Environment.CurrentDirectory;
                Environment.CurrentDirectory = parser.CWD;
                ExecuteExpr(parser.CommandRoot);
                Environment.CurrentDirectory = prevCWD;
            }
            else
            {
                List <FunctionBase> plugins;
                if (!PluginManager.Functions.TryGetValue(methodName, out plugins) || (plugins.Count <= 0))
                {
                    throw new Exception("Couldn't find plugin for " + origName + "()");
                }

                if (assemblyName != null)
                {
                    for (int i = 0; i < plugins.Count;)
                    {
                        string pluginAssemblyName = Path.GetFileNameWithoutExtension(plugins[i].Type.Assembly.CodeBase).ToLowerInvariant();
                        if (assemblyName == pluginAssemblyName)
                        {
                            i++;
                        }
                        else
                        {
                            plugins.RemoveAt(i);
                        }
                    }
                }
                if (className != null)
                {
                    for (int i = 0; i < plugins.Count;)
                    {
                        string pluginClassName = plugins[i].Type.Name.ToLowerInvariant();
                        if (className == pluginClassName)
                        {
                            i++;
                        }
                        else
                        {
                            plugins.RemoveAt(i);
                        }
                    }
                }
                if (plugins.Count <= 0)
                {
                    throw new Exception("Couldn't find plugin for " + origName + "()");
                }

                ScriptArg[] scriptArgs;
                int         argIdx = 0;
                if (useDefaultVar)
                {
                    scriptArgs = new ScriptArg[cmd.Args.Count];

                    ScriptArg scriptArg = new ScriptArg();
                    scriptArg.Value    = defaultVar;
                    scriptArgs[argIdx] = scriptArg;
                    argIdx++;
                }
                else
                {
                    scriptArgs = new ScriptArg[cmd.Args.Count - 1];
                }
                for (int cmdIdx = 1; cmdIdx < cmd.Args.Count; cmdIdx++)
                {
                    ScriptArg scriptArg = new ScriptArg();
                    Expr      cmdArg    = cmd.Args[cmdIdx];
                    if (cmdArg.Type == ExprType.Assign)
                    {
                        Command assign = (Command)cmdArg;
                        scriptArg.Name = ((Literal)assign.Args[0]).Value;
                        cmdArg         = assign.Args[1];
                    }
                    if (cmdArg.Type == ExprType.Name)
                    {
                        scriptArg.Variable = ((Literal)cmdArg).Value;
                    }
                    scriptArg.Value    = ExecuteExpr(cmdArg);
                    scriptArgs[argIdx] = scriptArg;
                    argIdx++;
                }

                bool          instanceExactMatch = false;
                int           minConversions     = Int32.MaxValue;
                FunctionArg[] pluginArgs         = null;
                FunctionBase  plugin             = null;
                for (int i = 0; i < plugins.Count; i++)
                {
                    int           numConversions;
                    FunctionArg[] matchArgs = plugins[i].Match(scriptArgs, useDefaultVar, out numConversions);
                    if ((matchArgs != null) && (numConversions < minConversions))
                    {
                        if (instance == null)
                        {
                            pluginArgs     = matchArgs;
                            plugin         = plugins[i];
                            minConversions = numConversions;
                        }
                        else
                        {
                            Type instanceType = instance.GetType();
                            if (plugins[i].Type.Equals(instanceType))
                            {
                                pluginArgs         = matchArgs;
                                plugin             = plugins[i];
                                minConversions     = numConversions;
                                instanceExactMatch = true;
                            }
                            else if (!instanceExactMatch && plugins[i].Type.IsAssignableFrom(instanceType))
                            {
                                pluginArgs     = matchArgs;
                                plugin         = plugins[i];
                                minConversions = numConversions;
                            }
                        }
                    }
                }
                if (pluginArgs == null)
                {
                    throw new Exception("Couldn't match args for " + origName + "()");
                }

                List <FunctionArg> changedVars;
                result = plugin.RunPlugin(instance, pluginArgs, out changedVars);
                for (int i = 0; i < changedVars.Count; i++)
                {
                    FunctionArg pluginArg = changedVars[i];
                    if (pluginArg.DefaultVar)
                    {
                        defaultVar = pluginArg.Value;
                    }
                    else
                    {
                        Variables[pluginArg.Variable] = pluginArg.Value;
                    }
                }
            }
            return(result);
        }