Ejemplo n.º 1
0
        public EnvFile ProcessFile(String name, String contents)
        {
            if (this.PathFiles.ContainsKey(name))
            {
                return(this.PathFiles[name]);
            }

            var file      = new EnvFile(name, contents);
            var tokenizer = new GLuaLexer(contents);
            var parser    = new GLuaParser(tokenizer, this);

            this.PathFiles[name]       = file;
            this.LexerFiles[tokenizer] = file;
            this.ParserFiles[parser]   = file;

            file.Successful = true;
            try
            {
                file.AST = parser.Parse( );
            }
            catch (Exception)
            {
                file.Successful = false;
                throw;
            }

            if (file.Successful)
            {
                foreach (IPriorityContainer module in this.Modules.Values.OrderBy(con => con.Priority))
                {
                    if (module is AnalyserEntry entryA)
                    {
                        entryA.Analyser.File = file;
                        entryA.Analyser.Analyse(file.AST);
                    }
                    else if (module is FolderEntry entryB)
                    {
                        entryB.Folder.File = file;
                        file.AST           = ( StatementList )entryB.Folder.Fold(file.AST);
                    }
                }

                foreach (Error err in file.Errors)
                {
                    if (err.Type == ErrorType.Error || err.Type == ErrorType.Fatal)
                    {
                        file.Successful = false;
                        break;
                    }
                }
            }

            return(file);
        }
Ejemplo n.º 2
0
        protected override ASTNode FoldFunctionCallExpression(FunctionCallExpression node, params Object[] args)
        {
            // Fold args and base
            node = ( FunctionCallExpression )base.FoldFunctionCallExpression(node, args);
            // Fold some functions
            if (node.Base is VariableExpression varExpr)
            {
                if (varExpr.Variable.Name == "RunString"
                    // Assert we have enough arguments for RunString
                    && node.Arguments.Count > 0)
                {
                    if (!(node.Arguments[0] is StringExpression) ||
                        (node.Arguments.Count > 1 && !(node.Arguments[1] is StringExpression)) ||
                        (node.Arguments.Count > 2 && !(node.Arguments[2] is BooleanExpression)))
                    {
                        return(node);
                    }

                    var code = (node.Arguments[0] as StringExpression).Value;
                    var name = node.Arguments.Count > 1
                    ? (node.Arguments[1] as StringExpression).Value
                    : "runstring_" + R.Next( );
                    // Dispose of useless RunString calls
                    if (code.Trim( ) == "")
                    {
                        return(null);
                    }

                    EnvFile file = this.Environment.ProcessFile(name, code);

                    if (file.Successful && file.AST != null)
                    {
                        file.AST.Scope.InternalData.RemoveValue("isRoot");
                        file.AST.Scope.InternalData.RemoveValue("isFunction");
                        // Enclose it in a do...end statement so that it doesn't
                        // breaks other analysers/folders too bad
                        return(GetDoStatement(node, file.AST));
                    }
                }
                // CompileString is almost the same as RunString
                // except it's an anonymous function definition
                else if (varExpr.Variable.Name == "CompileString" && node.Arguments.Count > 0)
                {
                    if (!(node.Arguments[0] is StringExpression) ||
                        (node.Arguments.Count > 1 && !(node.Arguments[1] is StringExpression)))
                    {
                        return(node);
                    }

                    var code = (node.Arguments[0] as StringExpression).Value.Trim( );
                    var id   = node.Arguments.Count > 1
                        ? (node.Arguments[1] as StringExpression).Value
                        : "compilestring_" + R.Next( );
                    // It'll be an empty function anyways
                    if (code == "")
                    {
                        var scope = new Scope(node.Scope.Parser, node.Scope);
                        return(GetAnonymousFunctionExpression(node,
                                                              scope,
                                                              new StatementList(null, scope, new List <LToken> ( ))
                                                              ));
                    }

                    EnvFile file = this.Environment.ProcessFile(id, code);
                    if (file.Successful && file.AST != null)
                    {
                        file.AST.InternalData.RemoveValue("isRoot");
                        var scope = new Scope(node.Scope.Parser, node.Scope);
                        AnonymousFunctionExpression func = GetAnonymousFunctionExpression(node, scope, file.AST);
                        // Add ... as argument because idk what
                        // people might pass to it and there're
                        // no ways to specify argument names so
                        // ¯\_(ツ)_/¯
                        func.AddArgument(new VarArgExpression(
                                             func,
                                             scope,
                                             GetTokenList("...", "...", "...", TokenType.Punctuation, AdjustRange(node.Range, "..."))
                                             ));
                        return(func);
                    }
                }
            }
            return(node);
        }