示例#1
0
        /// <summary>
        /// Adds a dependency using the "require" function (for loading Lua modules)
        /// </summary>
        /// <param name="c"></param>
        /// <param name="name">The name of the module to reference</param>
        /// <param name="varName">Optional. The variable name to assign to the module</param>
        public static void AddModuleDependency(Chunk c, string name, string varName = "")
        {
            if (varName == "")
            {
                // FunctionCall
                StringCallExpr call = new StringCallExpr();

                Variable require = c.Scope.GetVariable("require");
                VariableExpression v = new VariableExpression();
                if (require == null)
                {
                    require = c.Scope.CreateGlobal("require");
                    require.IsGlobal = true;
                }
                v.Var = require;
                call.Base = v;

                call.Arguments.Add(new StringExpr(name) { StringType = TokenType.DoubleQuoteString });

                c.Body.Insert(0, new CallStatement() { Expression = call, Scope = c.Scope });
            }
            else
            {
                // Assignment with FunctionCall
                AssignmentStatement a = new AssignmentStatement();

                StringCallExpr call = new StringCallExpr();
                call.Scope = c.Scope;
                Variable require = c.Scope.GetVariable("require");
                VariableExpression v = new VariableExpression();
                if (require == null)
                {
                    require = c.Scope.CreateGlobal("require");
                    require.IsGlobal = true;
                }
                v.Var = require;
                call.Base = v;
                call.Arguments.Add(new StringExpr(name) { StringType = TokenType.DoubleQuoteString });
                a.IsLocal = true; // local import
                a.Rhs.Add(call);

                Variable var = c.Scope.GetVariable(varName);
                VariableExpression v2 = new VariableExpression();
                if (var == null)
                {
                    var = c.Scope.CreateLocal(varName);
                }
                v2.Var = var;
                a.Lhs.Add(v2);

                c.Body.Insert(0, a);
            }
        }
示例#2
0
        /// <summary>
        /// Adds a dependency to a .NET/CLR library using clr.load,
        /// then it sets type to the type in the assembly.
        /// </summary>
        /// <param name="c"></param>
        /// <param name="assembly"></param>
        /// <param name="type"></param>
        public static void AddClrDependency(Chunk c, string assembly, string type)
        {
            AddClrDependency(c, assembly);

            // Assignment with FunctionCall
            AssignmentStatement a = new AssignmentStatement();

            CallExpr call = new CallExpr();
            call.Scope = c.Scope;
            Variable require = c.Scope.GetVariable("clr");
            VariableExpression v = new VariableExpression();
            if (require == null)
            {
                require = c.Scope.CreateGlobal("clr");
                require.IsGlobal = true;
            }

            string name = "", varName = "";

            if (type.Contains('.'))
            {
                name = type.Substring(0, type.LastIndexOf('.'));
                varName = type.Substring(type.LastIndexOf('.') + 1);
            }
            else
            {
                name = assembly;
                varName = type;
            }

            v.Var = require;
            MemberExpr me = new MemberExpr();
            me.Base = v;
            me.Indexer = ".";
            me.Ident = "getns";
            call.Base = me;
            call.Arguments.Add(new StringExpr(name) { StringType = TokenType.DoubleQuoteString });
            a.IsLocal = true; // local import
            MemberExpr me2 = new MemberExpr();
            me2.Base = call;
            me2.Indexer = ".";
            me2.Ident = varName;
            a.Rhs.Add(me2);

            Variable var = c.Scope.GetVariable(varName);
            VariableExpression v2 = new VariableExpression();
            if (var == null)
            {
                var = c.Scope.CreateLocal(varName);
            }
            v2.Var = var;
            a.Lhs.Add(v2);

            // Insert after the load
            c.Body.Insert(1, a);
        }
示例#3
0
        Statement ParseStatement(Scope scope)
        {
            int startP = reader.p;
            int startLine = reader.Peek().Line;
            Statement stat = null;
            // print(tok.Peek().Print())
            if (reader.ConsumeKeyword("if"))
            {
                //setup
                IfStmt _if = new IfStmt();

                //clauses
                do
                {
                    int sP = reader.p;
                    Expression nodeCond = ParseExpr(scope);

                    if (!reader.ConsumeKeyword("then"))
                        error("'then' expected");

                    List<Statement> nodeBody = ParseStatementList(scope);

                    List<Token> range = new List<Token>();
                    range.Add(reader.tokens[sP - 1]);
                    range.AddRange(reader.Range(sP, reader.p));

                    _if.Clauses.Add(new ElseIfStmt(scope)
                    {
                        Condition = nodeCond,
                        Body = nodeBody,
                        ScannedTokens = range
                    });
                }
                while (reader.ConsumeKeyword("elseif"));

                // else clause
                if (reader.ConsumeKeyword("else"))
                {
                    int sP = reader.p;
                    List<Statement> nodeBody = ParseStatementList(scope);
                    List<Token> range = new List<Token>();
                    range.Add(reader.tokens[sP - 1]);
                    range.AddRange(reader.Range(sP, reader.p));

                    _if.Clauses.Add(new ElseStmt(scope)
                    {
                        Body = nodeBody,
                        ScannedTokens = range
                    });
                }

                // end
                if (!reader.ConsumeKeyword("end"))
                    error("'end' expected");

                stat = _if;
            }
            else if (reader.ConsumeKeyword("while"))
            {
                WhileStatement w = new WhileStatement(scope);

                // condition
                Expression nodeCond = ParseExpr(scope);

                // do
                if (!reader.ConsumeKeyword("do"))
                    error("'do' expected");

                // body
                List<Statement> body = ParseStatementList(scope);

                //end
                if (!reader.ConsumeKeyword("end"))
                    error("'end' expected");


                // return
                w.Condition = nodeCond;
                w.Body = body;
                stat = w;
            }
            else if (reader.ConsumeKeyword("do"))
            {
                // do block
                List<Statement> b = ParseStatementList(scope);

                if (!reader.ConsumeKeyword("end"))
                    error("'end' expected");

                stat = new DoStatement(scope) { Body = b };
            }
            else if (reader.ConsumeKeyword("for"))
            {
                //for block
                if (!reader.Is(TokenType.Ident))
                    error("<ident> expected");

                Token baseVarName = reader.Get();
                if (reader.ConsumeSymbol('='))
                {
                    //numeric for
                    NumericForStatement forL = new NumericForStatement(scope);
                    Variable forVar = new Variable() { Name = baseVarName.Data };
                    forL.Scope.AddLocal(forVar);

                    Expression startEx = ParseExpr(scope);

                    if (!reader.ConsumeSymbol(','))
                        error("',' expected");

                    Expression endEx = ParseExpr(scope);

                    Expression stepEx = null;
                    if (reader.ConsumeSymbol(','))
                    {
                        stepEx = ParseExpr(scope);
                    }
                    if (!reader.ConsumeKeyword("do"))
                        error("'do' expected");


                    List<Statement> body = ParseStatementList(forL.Scope);

                    if (!reader.ConsumeKeyword("end"))
                        error("'end' expected");


                    forL.Variable = forVar;
                    forL.Start = startEx;
                    forL.End = endEx;
                    forL.Step = stepEx;
                    forL.Body = body;
                    stat = forL;
                }
                else
                {
                    // generic for
                    GenericForStatement forL = new GenericForStatement(scope);

                    List<Variable> varList = new List<Variable> { forL.Scope.CreateLocal(baseVarName.Data) };
                    while (reader.ConsumeSymbol(','))
                    {
                        if (!reader.Is(TokenType.Ident))
                            error("for variable expected");

                        varList.Add(forL.Scope.CreateLocal(reader.Get().Data));
                    }
                    if (!reader.ConsumeKeyword("in"))
                        error("'in' expected");

                    List<Expression> generators = new List<Expression>();
                    Expression first = ParseExpr(scope);

                    generators.Add(first);
                    while (reader.ConsumeSymbol(','))
                    {
                        Expression gen = ParseExpr(scope);
                        generators.Add(gen);
                    }
                    if (!reader.ConsumeKeyword("do"))
                        error("'do' expected");

                    List<Statement> body = ParseStatementList(forL.Scope);

                    if (!reader.ConsumeKeyword("end"))
                        error("'end' expected");

                    forL.VariableList = varList;
                    forL.Generators = generators;
                    forL.Body = body;
                    stat = forL;
                }
            }
            else if (reader.ConsumeKeyword("repeat"))
            {
                List<Statement> body = ParseStatementList(scope);

                if (!reader.ConsumeKeyword("until"))
                    error("'until' expected");

                Expression cond = ParseExpr(scope);

                RepeatStatement r = new RepeatStatement(scope);
                r.Condition = cond;
                r.Body = body;
                stat = r;
            }
            else if (reader.ConsumeKeyword("function"))
            {
                if (!reader.Is(TokenType.Ident))
                    error("function name expected");

                Expression name = ParseSuffixedExpr(scope, true);
                // true: only dots and colons

                FunctionStatement func = ParseFunctionArgsAndBody(scope);

                func.IsLocal = false;
                func.Name = name;
                stat = func;
            }
            else if (reader.ConsumeKeyword("local"))
            {
                if (reader.Is(TokenType.Ident))
                {
                    List<string> varList = new List<string> { reader.Get().Data };
                    while (reader.ConsumeSymbol(','))
                    {
                        if (!reader.Is(TokenType.Ident))
                            error("local variable name expected");
                        varList.Add(reader.Get().Data);
                    }

                    List<Expression> initList = new List<Expression>();
                    if (reader.ConsumeSymbol('='))
                    {
                        do
                        {
                            Expression ex = ParseExpr(scope);
                            initList.Add(ex);
                        } while (reader.ConsumeSymbol(','));
                    }

                    //now patch var list
                    //we can't do this before getting the init list, because the init list does not
                    //have the locals themselves in scope.
                    List<Expression> newVarList = new List<Expression>();
                    for (int i = 0; i < varList.Count; i++)
                    {
                        Variable x = scope.CreateLocal(varList[i]);
                        newVarList.Add(new VariableExpression { Var = x });
                    }

                    AssignmentStatement l = new AssignmentStatement();
                    l.Lhs = newVarList;
                    l.Rhs = initList;
                    l.IsLocal = true;
                    stat = l;
                }
                else if (reader.ConsumeKeyword("function"))
                {
                    if (!reader.Is(TokenType.Ident))
                        error("Function name expected");
                    string name = reader.Get().Data;
                    Variable localVar = scope.CreateLocal(name);

                    FunctionStatement func = ParseFunctionArgsAndBody(scope);

                    func.Name = new VariableExpression { Var = localVar };
                    func.IsLocal = true;
                    stat = func;
                }
                else
                    error("local variable or function definition expected");
            }
#if !VANILLA_LUA
            else if (reader.ConsumeSymbol("::"))
            {
                if (!reader.Is(TokenType.Ident))
                    error("label name expected");

                string label = reader.Get().Data;
                if (!reader.ConsumeSymbol("::"))
                    error("'::' expected");

                LabelStatement l = new LabelStatement();
                l.Label = label;
                stat = l;
            }
#endif
            else if (reader.ConsumeKeyword("return"))
            {
                List<Expression> exprList = new List<Expression>();
                if (!reader.IsKeyword("end") && !reader.IsEof())
                {
                    Expression firstEx = ParseExpr(scope);
                    exprList.Add(firstEx);
                    while (reader.ConsumeSymbol(','))
                    {
                        Expression ex = ParseExpr(scope);
                        exprList.Add(ex);
                    }
                }
                ReturnStatement r = new ReturnStatement();
                r.Arguments = exprList;
                stat = r;
            }
            else if (reader.ConsumeKeyword("break"))
            {
                stat = new BreakStatement();
            }
            else if (reader.ConsumeKeyword("continue"))
            {
                stat = new ContinueStatement();
            }
#if !VANILLA_LUA
            else if (reader.ConsumeKeyword("goto"))
            {
                if (!reader.Is(TokenType.Ident))
                    error("label expected");

                string label = reader.Get().Data;
                GotoStatement g = new GotoStatement();
                g.Label = label;
                stat = g;
            }
            else if (reader.ConsumeKeyword("using"))
            {
                // using <a, b = 1, x()> do <statements> end
                UsingStatement us = new UsingStatement(scope);
                us.Scope = new Scope(scope);

                List<Expression> lhs = new List<Expression> { ParseExpr(us.Scope) };
                while (reader.ConsumeSymbol(','))
                {
                    lhs.Add(ParseSuffixedExpr(us.Scope, true));
                }

                // equals
                if (!reader.ConsumeSymbol('='))
                    error("'=' expected");

                //rhs
                List<Expression> rhs = new List<Expression>();
                rhs.Add(ParseExpr(us.Scope));
                while (reader.ConsumeSymbol(','))
                {
                    rhs.Add(ParseExpr(scope));
                }

                AssignmentStatement a = new AssignmentStatement();
                a.Lhs = lhs;
                a.Rhs = rhs;
                a.IsLocal = true;

                if (!reader.ConsumeKeyword("do"))
                    error("'do' expected");

                List<Statement> block = ParseStatementList(us.Scope);

                if (!reader.ConsumeKeyword("end"))
                    error("'end' expected");

                us.Vars = a;
                us.Body = block;
                stat = us;
            }
#endif
            else
            {
                // statementParseExpr
                Expression suffixed = ParseSuffixedExpr(scope);
                // assignment or call?
                if (reader.IsSymbol(',') || reader.IsSymbol('='))
                {
                    // check that it was not parenthesized, making it not an lvalue
                    if (suffixed.ParenCount > 0)
                        error("Can not assign to parenthesized expression, it is not an lvalue");

                    // more processing needed
                    List<Expression> lhs = new List<Expression> { suffixed };
                    while (reader.ConsumeSymbol(','))
                    {
                        lhs.Add(ParseSuffixedExpr(scope));
                    }

                    // equals
                    if (!reader.ConsumeSymbol('='))
                        error("'=' expected");

                    //rhs
                    List<Expression> rhs = new List<Expression>();
                    rhs.Add(ParseExpr(scope));
                    while (reader.ConsumeSymbol(','))
                    {
                        rhs.Add(ParseExpr(scope));
                    }

                    AssignmentStatement a = new AssignmentStatement();
                    a.Lhs = lhs;
                    a.Rhs = rhs;
                    stat = a;
                }
#if !VANILLA_LUA
                else if (isAugmentedAssignment(reader.Peek()))
                {
                    AugmentedAssignmentStatement aas = new AugmentedAssignmentStatement();
                    Expression left = suffixed;
                    Expression right = null;
                    string augmentedOp = reader.Get().Data;
                    right = ParseExpr(scope);
                    BinOpExpr nRight = new BinOpExpr();
                    nRight.Lhs = left;
                    nRight.Op = augmentedOp.Substring(0, augmentedOp.Length - 1); // strip the '='
                    nRight.Rhs = right;

                    aas.Lhs = new List<Expression> { left };
                    aas.Rhs = new List<Expression> { nRight };
                    stat = aas;
                }
#endif
                else if (suffixed is CallExpr ||
                       suffixed is TableCallExpr ||
                       suffixed is StringCallExpr)
                {
                    //it's a call statement
                    CallStatement c = new CallStatement();
                    c.Expression = suffixed;
                    stat = c;
                }
                else
                    error("assignment statement expected");
            }

            stat.ScannedTokens = reader.Range(startP, reader.p);
            if (reader.Peek().Data == ";" && reader.Peek().Type == TokenType.Symbol)
            {
                stat.HasSemicolon = true;
                stat.SemicolonToken = reader.Get();
            }
            if (stat.Scope == null)
                stat.Scope = scope;
            stat.LineNumber = startLine;
            return stat;
        }