コード例 #1
0
 public static void PrintTree(Command cmd, string space)
 {
     Console.WriteLine(space + cmd.Type);
     foreach (var arg in cmd.Args)
     {
         if (arg is Literal)
         {
             Literal literal = (Literal)arg;
             Console.WriteLine(space + "  " + literal.Value + " [" + literal.Type + "]");
         }
         else
         {
             Command child = (Command)arg;
             PrintTree(child, space + "  ");
         }
     }
 }
コード例 #2
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;
        }
コード例 #3
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetNegative(List<Token> tokens, ref int tokenIdx)
 {
     Expr result = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Minus))
     {
         Token token = tokens[tokenIdx];
         tokenIdx++;
         Command cmd = new Command(ExprType.Negative);
         result = cmd;
         Expr expr = GetNegVar(tokens, ref tokenIdx);
         if (expr == null)
         {
             throw new Exception("Expected a numeric expression" + token.Error());
         }
         cmd.Args.Add(expr);
     }
     return result;
 }
コード例 #4
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 void Parse(StreamReaderCursor reader, string scriptName)
 {
     var tokenList = Scanner(reader, scriptName);
     this.CommandRoot = new Command(ExprType.Root);
     foreach (var tokens in tokenList)
     {
         int tokenIdx = 0;
         while (tokenIdx < tokens.Count)
         {
             Expr expr = ParseStmt(tokens, ref tokenIdx);
             if (expr != null)
             {
                 this.CommandRoot.Args.Add(expr);
             }
         }
     }
 }
コード例 #5
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
        Expr GetFunction(List<Token> tokens, ref int tokenIdx)
        {
            Expr result = null;
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name) &&
                ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.LP))
            {
                Token token = tokens[tokenIdx];
                tokenIdx += 2;
                Command cmd = new Command(ExprType.Function);
                result = cmd;
                cmd.Args.Add(new Literal(ExprType.Name, token.Value));
                GetExprList(cmd, token, TokenType.RP, ')', tokens, ref tokenIdx);

                if ((token.Value.ToLowerInvariant() == ScriptExecutor.LoadPluginName) && (cmd.Args.Count != 2))
                {
                    throw new Exception("Invalid path for LoadPlugin()" + token.Error());
                }
                else if ((token.Value.ToLowerInvariant() == ScriptExecutor.ImportName) && (cmd.Args.Count != 2))
                {
                    throw new Exception("Invalid path for Import()" + token.Error());
                }

                result = GetIndexed(result, tokens, ref tokenIdx);
                result = GetChain(result, tokens, ref tokenIdx);
            }
            return result;
        }
コード例 #6
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
        Expr GetIndexed(Expr result, List<Token> tokens, ref int tokenIdx)
        {
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.HexOrIndex || tokens[tokenIdx].Type == TokenType.Name))
            {
                Command cmd = new Command(ExprType.Indexed);
                cmd.Args.Add(result);
                cmd.Args.Add(new Literal(tokens[tokenIdx].Type == TokenType.HexOrIndex ? ExprType.Number : ExprType.Name, tokens[tokenIdx].Value));
                tokenIdx++;

                result = cmd;
            }
            return result;
        }
コード例 #7
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
        Expr GetDotPropertyChain(Expr result, List<Token> tokens, ref int tokenIdx)
        {
            Expr chain = null;
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Dot) &&
                ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Name))
            {
                Token property = tokens[tokenIdx + 1];
                tokenIdx += 2;

                Command cmd = new Command(ExprType.DotPropertyChain);
                cmd.Args.Add(result);
                cmd.Args.Add(new Literal(ExprType.Name, property.Value));
                chain = cmd;

                chain = GetIndexed(chain, tokens, ref tokenIdx);
                chain = GetChain(chain, tokens, ref tokenIdx);
            }
            return chain;
        }
コード例 #8
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 void GetExprList(Command cmd, Token startToken, TokenType endToken, char endTokenChar, List<Token> tokens, ref int tokenIdx)
 {
     Token token = startToken;
     while ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type != endToken))
     {
         token = tokens[tokenIdx];
         Expr expr;
         if ((expr = GetAssign(tokens, ref tokenIdx)) != null) { }
         else if ((expr = GetExpr(tokens, ref tokenIdx)) != null) { }
         else
         {
             throw new Exception("Expected an expression" + token.Error());
         }
         cmd.Args.Add(expr);
         if (tokenIdx < tokens.Count)
         {
             token = tokens[tokenIdx];
             if (token.Type != endToken)
             {
                 if (token.Type == TokenType.Comma)
                 {
                     tokenIdx++;
                 }
                 else
                 {
                     throw new Exception("Expected a comma" + token.Error());
                 }
             }
         }
     }
     if ((tokenIdx >= tokens.Count) || ((token = tokens[tokenIdx]).Type != endToken))
     {
         throw new Exception("Missing '" + endTokenChar + "'" + token.Error());
     }
     tokenIdx++;
 }
コード例 #9
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetDotInstanceDefaultChain(Expr result, List<Token> tokens, ref int tokenIdx)
 {
     Expr chain = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Dot) &&
         ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Dot))
     {
         Token token = tokens[tokenIdx];
         tokenIdx += 2;
         Command cmd = new Command(ExprType.DotInstanceDefaultChain);
         chain = cmd;
         cmd.Args.Add(result);
         Expr expr = GetFunction(tokens, ref tokenIdx);
         if (expr == null)
         {
             throw new Exception("Expected a function" + token.Error(2));
         }
         cmd.Args.Add(expr);
     }
     return chain;
 }
コード例 #10
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
        Expr GetDotProperty(List<Token> tokens, ref int tokenIdx)
        {
            Expr result = null;
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name) &&
                ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Dot) &&
                ((tokenIdx + 2) < tokens.Count) && (tokens[tokenIdx + 2].Type == TokenType.Name))
            {
                Token token = tokens[tokenIdx];
                Token property = tokens[tokenIdx + 2];
                tokenIdx += 3;

                Command cmd = new Command(ExprType.DotProperty);
                cmd.Args.Add(new Literal(ExprType.Name, token.Value));
                cmd.Args.Add(new Literal(ExprType.Name, property.Value));
                result = cmd;

                result = GetIndexed(result, tokens, ref tokenIdx);
                result = GetChain(result, tokens, ref tokenIdx);
            }
            return result;
        }
コード例 #11
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetDotInstanceDefault(List<Token> tokens, ref int tokenIdx)
 {
     Expr result = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name) &&
         ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Dot) &&
         ((tokenIdx + 2) < tokens.Count) && (tokens[tokenIdx + 2].Type == TokenType.Dot))
     {
         Token token = tokens[tokenIdx];
         tokenIdx += 3;
         Command cmd = new Command(ExprType.DotInstanceDefault);
         result = cmd;
         cmd.Args.Add(new Literal(ExprType.Name, token.Value));
         Expr expr = GetFunction(tokens, ref tokenIdx);
         if (expr == null)
         {
             throw new Exception("Expected a function" + token.Error(2));
         }
         cmd.Args.Add(expr);
     }
     return result;
 }
コード例 #12
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetDotDefault(List<Token> tokens, ref int tokenIdx)
 {
     Expr result = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Dot))
     {
         Token token = tokens[tokenIdx];
         tokenIdx++;
         Command cmd = new Command(ExprType.DotDefault);
         result = cmd;
         Expr expr = GetFunction(tokens, ref tokenIdx);
         if (expr == null)
         {
             throw new Exception("Expected a function" + token.Error(1));
         }
         cmd.Args.Add(expr);
     }
     return result;
 }
コード例 #13
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
        Expr GetAssign(List<Token> tokens, ref int tokenIdx)
        {
            Expr result = null;
            if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.Name) &&
                ((tokenIdx + 1) < tokens.Count) && (tokens[tokenIdx + 1].Type == TokenType.Equals))
            {
                Token token = tokens[tokenIdx];
                tokenIdx += 2;
                Command cmd = new Command(ExprType.Assign);
                result = cmd;
                cmd.Args.Add(new Literal(ExprType.Name, token.Value));

                Expr expr = GetExpr(tokens, ref tokenIdx);
                if (expr == null)
                {
                    throw new Exception("Expected an expression" + token.Error());
                }
                cmd.Args.Add(expr);
            }
            return result;
        }
コード例 #14
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetArray(List<Token> tokens, ref int tokenIdx)
 {
     Expr result = null;
     if ((tokenIdx < tokens.Count) && (tokens[tokenIdx].Type == TokenType.LCB))
     {
         Token token = tokens[tokenIdx];
         tokenIdx++;
         Command cmd = new Command(ExprType.Array);
         result = cmd;
         GetExprList(cmd, token, TokenType.RCB, '}', tokens, ref tokenIdx);
     }
     return result;
 }
コード例 #15
0
ファイル: ScriptParser.cs プロジェクト: hejob/SB3Utility
 Expr GetArithHelper(Expr result, ExprType exprType, List<Token> tokens, ref int tokenIdx)
 {
     Token token = tokens[tokenIdx];
     tokenIdx++;
     Command cmd = new Command(exprType);
     cmd.Args.Add(result);
     Expr expr = GetArith(tokens, ref tokenIdx);
     if (expr == null)
     {
         throw new Exception("Expected a numeric expression" + token.Error());
     }
     cmd.Args.Add(expr);
     return cmd;
 }