Beispiel #1
0
 /// <summary>
 /// Parses and executes the specified string
 /// </summary>
 public LuaArguments DoString(string Chunk)
 {
     FunctionDefinition def = new FunctionDefinition();
     def.Arguments = new List<Argument>();
     def.Body = p.ParseString(Chunk);
     var function = LuaCompiler.CompileFunction(def, Expression.Constant(ctx)).Compile();
     return function().Call(Lua.Return());
 }
Beispiel #2
0
        public static Expression <Func <LuaObject> > CompileFunction(Ast.FunctionDefinition func, Expression Context)
        {
            var exprs = new List <Expression>();

            var args   = Expression.Parameter(LuaArguments_Type, "args");
            var label  = Expression.Label(LuaArguments_Type, "exit");
            var @break = Expression.Label("break");

            var scopeVar    = Expression.Parameter(LuaContext_Type, "funcScope");
            var assignScope = Expression.Assign(scopeVar, Expression.New(LuaContext_New_parent, Context));

            #region Arguments init
            var len      = Expression.Property(args, "Length");
            var argLen   = Expression.Constant(func.Arguments.Count);
            var argCount = Expression.Constant(func.Arguments.Count);

            var i           = Expression.Parameter(typeof(int), "i");
            var assignI     = Expression.Assign(i, Expression.Constant(0));
            var names       = Expression.Parameter(typeof(string[]), "names");
            var assignNames = Expression.Assign(names, Expression.Constant(Array.ConvertAll <Argument, string>(func.Arguments.ToArray(), x => x.Name)));

            var innerCond = Expression.LessThan(i, argLen);
            var outerCond = Expression.LessThan(i, len);

            var innerIf   = Expression.Call(scopeVar, LuaContext_SetLocal, Expression.ArrayAccess(names, i), Expression.Property(args, "Item", i));
            var varargs   = Expression.Property(scopeVar, "Varargs");
            var innerElse = Expression.Call(varargs, LuaArguments_Add, Expression.Property(args, "Item", i));

            var outerIf   = Expression.Block(Expression.IfThenElse(innerCond, innerIf, innerElse), Expression.Assign(i, Expression.Add(i, Expression.Constant(1))));
            var outerElse = Expression.Break(@break);

            var loopBody = Expression.IfThenElse(outerCond, outerIf, outerElse);
            var loop     = Expression.Loop(loopBody);

            var breakLabel = Expression.Label(@break);
            #endregion

            var body = CompileBlock(func.Body, label, null, scopeVar);

            exprs.Add(assignScope);
            exprs.Add(assignI);
            exprs.Add(assignNames);
            exprs.Add(loop);
            exprs.Add(breakLabel);
            exprs.Add(body);
            exprs.Add(Expression.Label(label, Expression.Constant(VoidArguments)));

            var funcBody = Expression.Block(new[] { i, names, scopeVar }, exprs.ToArray());

            var function    = Expression.Lambda <LuaFunction>(funcBody, args);
            var returnValue = Expression.Lambda <Func <LuaObject> >(Expression.Convert(function, LuaObject_Type), null);

            return(returnValue);
        }
Beispiel #3
0
        Ast.Assignment ParseFunctionDecl(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDecl")
            {
                Ast.IAssignable expr = ParseVariable(node.ChildNodes[1]);

                ParseTreeNode argsNode  = node.ChildNodes[3].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[4];

                Ast.Block block            = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Arguments = new List <Ast.Argument>();

                var nameNode = node.ChildNodes[2];
                if (nameNode.ChildNodes.Count > 0)
                {
                    def.Arguments.Add(new Ast.Argument()
                    {
                        Name = "self"
                    });
                    expr = new Ast.Variable()
                    {
                        Name   = nameNode.ChildNodes[0].Token.ValueString,
                        Prefix = expr
                    };
                }
                def.Body = block;
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        string ident = argsNode.ChildNodes[0].Token.ValueString;
                        def.Arguments.Add(new Ast.Argument()
                        {
                            Name = ident
                        });
                        if (argsNode.ChildNodes.Count == 1)
                        {
                            break;
                        }
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                Ast.Assignment assign = new Ast.Assignment();
                assign.Variables.Add(expr);
                assign.Expressions.Add(def);
                return(assign);
            }
            throw new Exception("Invalid FunctionDecl node");
        }
Beispiel #4
0
        Ast.FunctionDefinition ParseFunctionDef(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDef")
            {
                ParseTreeNode argsNode  = node.ChildNodes[1].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[2];

                Ast.Block block            = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Body      = block;
                def.Arguments = new List <Ast.Argument>();

                if (argsNode.ChildNodes.Count == 0)
                {
                    return(def);
                }
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        var argsNodeChild = argsNode.ChildNodes[0];
                        if (argsNodeChild.Token == null)
                        {
                            def.Arguments.Add(new Ast.Argument()
                            {
                                Name = "...", Span = argsNodeChild.Span
                            });
                        }
                        else
                        {
                            string ident = argsNodeChild.Token.ValueString;
                            def.Arguments.Add(new Ast.Argument()
                            {
                                Name = ident, Span = argsNodeChild.Span
                            });
                        }
                        if (argsNode.ChildNodes.Count == 1)
                        {
                            break;
                        }
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                return(def);
            }
            throw new Exception("Invalid FunctionDef node");
        }
Beispiel #5
0
        Ast.LocalAssignment ParseLocalAssign(ParseTreeNode node)
        {
            if (node.Term.Name == "LocalAssignment")
            {
                Ast.LocalAssignment assign = new Ast.LocalAssignment();


                var child = node.ChildNodes[1];

                if (child.ChildNodes[0].Term.Name == "LocalFunction")
                {
                    child = child.ChildNodes[0];

                    var argsNode  = child.ChildNodes[2];
                    var blockNode = child.ChildNodes[3];

                    assign.Names.Add(child.ChildNodes[1].Token.ValueString);
                    var func = new Ast.FunctionDefinition();

                    if (argsNode.ChildNodes.Count > 0)
                    {
                        argsNode = argsNode.ChildNodes[0];
                        while (argsNode.ChildNodes.Count > 0)
                        {
                            string ident = argsNode.ChildNodes[0].Token.ValueString;
                            func.Arguments.Add(new Ast.Argument()
                            {
                                Name = ident
                            });
                            if (argsNode.ChildNodes.Count == 1)
                            {
                                break;
                            }
                            argsNode = argsNode.ChildNodes[1];
                        }
                    }

                    func.Body = ParseBlock(blockNode);

                    assign.Values.Add(func);
                    return(assign);
                }

                var left  = child.ChildNodes[0];
                var right = child.ChildNodes[1];

                assign.Names.Add(left.ChildNodes[0].Token.ValueString);

                left = left.ChildNodes[1];

                while (left.ChildNodes.Count > 0)
                {
                    left = left.ChildNodes[0];
                    assign.Names.Add(left.ChildNodes[0].Token.ValueString);
                    left = left.ChildNodes[1];
                }

                while (right.ChildNodes.Count > 0)
                {
                    right = right.ChildNodes[0];
                    assign.Values.Add(ParseExpression(right.ChildNodes[0]));
                    right = right.ChildNodes[1];
                }

                return(assign);
            }
            throw new Exception("Invalid LocalAssignment node");
        }
Beispiel #6
0
        Ast.FunctionDefinition ParseFunctionDef(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDef")
            {
                ParseTreeNode argsNode = node.ChildNodes[1].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[2];

                Ast.Block block = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Body = block;
                def.Arguments = new List<Ast.Argument>();

                if (argsNode.ChildNodes.Count == 0)
                    return def;
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        string ident = argsNode.ChildNodes[0].Token.ValueString;
                        def.Arguments.Add(new Ast.Argument() { Name = ident });
                        if (argsNode.ChildNodes.Count == 1)
                            break;
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                return def;
            }
            throw new Exception("Invalid FunctionDef node");
        }
Beispiel #7
0
        Ast.Assignment ParseFunctionDecl(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDecl")
            {
                Ast.IAssignable expr = ParseVariable(node.ChildNodes[1]);

                ParseTreeNode argsNode = node.ChildNodes[3].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[4];

                Ast.Block block = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Arguments = new List<Ast.Argument>();

                var nameNode = node.ChildNodes[2];
                if (nameNode.ChildNodes.Count > 0)
                {
                    def.Arguments.Add(new Ast.Argument() { Name = "self" });
                    expr = new Ast.Variable()
                    {
                        Name = nameNode.ChildNodes[0].Token.ValueString,
                        Prefix = expr
                    };
                }
                def.Body = block;
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        string ident = argsNode.ChildNodes[0].Token.ValueString;
                        def.Arguments.Add(new Ast.Argument() { Name = ident });
                        if (argsNode.ChildNodes.Count == 1)
                            break;
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                Ast.Assignment assign = new Ast.Assignment();
                assign.Variables.Add(expr);
                assign.Expressions.Add(def);
                return assign;
            }
            throw new Exception("Invalid FunctionDecl node");
        }
Beispiel #8
0
        Ast.LocalAssignment ParseLocalAssign(ParseTreeNode node)
        {
            if (node.Term.Name == "LocalAssignment")
            {
                Ast.LocalAssignment assign = new Ast.LocalAssignment();


                var child = node.ChildNodes[1];

                if (child.ChildNodes[0].Term.Name == "LocalFunction")
                {
                    child = child.ChildNodes[0];

                    var argsNode = child.ChildNodes[2];
                    var blockNode = child.ChildNodes[3];

                    assign.Names.Add(child.ChildNodes[1].Token.ValueString);
                    var func = new Ast.FunctionDefinition();

                    if (argsNode.ChildNodes.Count > 0)
                    {
                        argsNode = argsNode.ChildNodes[0];
                        while (argsNode.ChildNodes.Count > 0)
                        {
                            string ident = argsNode.ChildNodes[0].Token.ValueString;
                            func.Arguments.Add(new Ast.Argument() { Name = ident });
                            if (argsNode.ChildNodes.Count == 1)
                                break;
                            argsNode = argsNode.ChildNodes[1];
                        }
                    }

                    func.Body = ParseBlock(blockNode);

                    assign.Values.Add(func);
                    return assign;
                }

                var left = child.ChildNodes[0];
                var right = child.ChildNodes[1];

                assign.Names.Add(left.ChildNodes[0].Token.ValueString);

                left = left.ChildNodes[1];

                while (left.ChildNodes.Count > 0)
                {
                    left = left.ChildNodes[0];
                    assign.Names.Add(left.ChildNodes[0].Token.ValueString);
                    left = left.ChildNodes[1];
                }

                while (right.ChildNodes.Count > 0)
                {
                    right = right.ChildNodes[0];
                    assign.Values.Add(ParseExpression(right.ChildNodes[0]));
                    right = right.ChildNodes[1];
                }

                return assign;
            }
            throw new Exception("Invalid LocalAssignment node");
        }
Beispiel #9
0
 static Expression CompileFunctionDef(FunctionDefinition def, Expression Context)
 {
     return Expression.Invoke(CompileFunction(def, Context));
 }