Beispiel #1
0
        static Expression CompileGenericFor(Ast.GenericFor stat, LabelTarget returnTarget, Expression Context)
        {
            var body   = new List <Expression>();
            var args   = Expression.Parameter(LuaArguments_Type);
            var f      = GetArgument(args, 0);
            var s      = GetArgument(args, 1);
            var var    = GetArgument(args, 2);
            var fVar   = Expression.Parameter(LuaObject_Type);
            var sVar   = Expression.Parameter(LuaObject_Type);
            var varVar = Expression.Parameter(LuaObject_Type);
            var scope  = Expression.Parameter(LuaContext_Type);

            var @break = Expression.Label();

            body.Add(Expression.Assign(args, Expression.New(LuaArguments_New_void)));
            foreach (IExpression expr in stat.Expressions)
            {
                body.Add(Expression.Call(args, LuaArguments_Concat, CompileExpression(expr, Context)));
            }
            body.Add(Expression.Assign(fVar, f));
            body.Add(Expression.Assign(sVar, s));
            body.Add(Expression.Assign(varVar, var));

            body.Add(Expression.Assign(scope, Expression.New(LuaContext_New_parent, Context)));

            var res                 = Expression.Parameter(LuaArguments_Type);
            var buildArgs           = Expression.New(LuaArguments_New, Expression.NewArrayInit(typeof(LuaObject), sVar, varVar));
            var resAssign           = Expression.Assign(res, Expression.Call(fVar, LuaObject_Call, buildArgs));
            List <Expression> exprs = new List <Expression>();

            exprs.Add(resAssign);
            for (int i = 0; i < stat.Variables.Count; i++)
            {
                var val = GetArgument(res, i);
                exprs.Add(Expression.Call(scope, LuaContext_SetLocal, Expression.Constant(stat.Variables[i]), val));
            }
            var check = Expression.IfThen(Expression.Property(GetArgument(res, 0), "IsNil"), Expression.Break(@break));

            exprs.Add(check);
            exprs.Add(Expression.Assign(varVar, GetFirstArgument(res)));
            exprs.Add(CompileBlock(stat.Block, returnTarget, @break, scope));

            var loopBody = Expression.Block(new[] { res }, exprs.ToArray());
            var loop     = Expression.Loop(loopBody);

            body.Add(loop);
            body.Add(Expression.Label(@break));

            var block = Expression.Block(new[] { args, scope, fVar, sVar, varVar }, body.ToArray());

            return(block);
        }
Beispiel #2
0
        Ast.IStatement ParseFor(ParseTreeNode node)
        {
            if (node.Term.Name == "For")
            {
                var block = ParseDoBlock(node.ChildNodes[2]);
                var type = node.ChildNodes[1].ChildNodes[0];
                if (type.Term.Name == "NumericFor")
                {
                    var cycle = new Ast.NumericFor();
                    cycle.Block = block;
                    cycle.Variable = type.ChildNodes[0].Token.ValueString;
                    cycle.Var = ParseExpression(type.ChildNodes[1]);
                    cycle.Limit = ParseExpression(type.ChildNodes[2]);
                    cycle.Step = new Ast.NumberLiteral() { Value = 1 };
                    if (type.ChildNodes[3].ChildNodes.Count > 0)
                    {
                        var child = type.ChildNodes[3].ChildNodes[0];
                        cycle.Step = ParseExpression(child);
                    }

                    return cycle;
                }
                else
                {
                    var cycle = new Ast.GenericFor();
                    cycle.Block = block;

                    var nameList = type.ChildNodes[0];
                    var exprList = type.ChildNodes[2];

                    while (true)
                    {
                        var name = nameList.ChildNodes[0].Token.ValueString;
                        cycle.Variables.Add(name);
                        var child = nameList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                            nameList = child.ChildNodes[0];
                        else
                            break;
                    }

                    while (true)
                    {
                        var expr = ParseExpression(exprList.ChildNodes[0]);
                        cycle.Expressions.Add(expr);
                        var child = exprList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                            exprList = child.ChildNodes[0];
                        else
                            break;
                    }

                    return cycle;
                }
            }
            throw new Exception("Invalid For node");
        }
Beispiel #3
0
        Ast.IStatement ParseFor(ParseTreeNode node)
        {
            if (node.Term.Name == "For")
            {
                var block = ParseDoBlock(node.ChildNodes[2]);
                var type  = node.ChildNodes[1].ChildNodes[0];
                if (type.Term.Name == "NumericFor")
                {
                    var cycle = new Ast.NumericFor();
                    cycle.Block    = block;
                    cycle.Variable = type.ChildNodes[0].Token.ValueString;
                    cycle.Var      = ParseExpression(type.ChildNodes[1]);
                    cycle.Limit    = ParseExpression(type.ChildNodes[2]);
                    cycle.Step     = new Ast.NumberLiteral()
                    {
                        Value = 1
                    };
                    if (type.ChildNodes[3].ChildNodes.Count > 0)
                    {
                        var child = type.ChildNodes[3].ChildNodes[0];
                        cycle.Step = ParseExpression(child);
                    }

                    return(cycle);
                }
                else
                {
                    var cycle = new Ast.GenericFor();
                    cycle.Block = block;

                    var nameList = type.ChildNodes[0];
                    var exprList = type.ChildNodes[2];

                    while (true)
                    {
                        var name = nameList.ChildNodes[0].Token.ValueString;
                        cycle.Variables.Add(name);
                        var child = nameList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            nameList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    while (true)
                    {
                        var expr = ParseExpression(exprList.ChildNodes[0]);
                        cycle.Expressions.Add(expr);
                        var child = exprList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            exprList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    return(cycle);
                }
            }
            throw new Exception("Invalid For node");
        }
Beispiel #4
0
        Ast.IExpression ParseExpression(ParseTreeNode node)
        {
            if (node.Term.Name == "Expression")
            {
                ParseTreeNode child = node.ChildNodes[0];
                if (child.Token != null && child.Token.Terminal is NumberLiteral)
                {
                    return(new Ast.NumberLiteral()
                    {
                        Span = child.Span, Value = (child.Token.Value is double?(double)(child.Token.Value) : (int)(child.Token.Value))
                    });
                }
                else if (child.Token != null && child.Token.Terminal is StringLiteral)
                {
                    return(new Ast.StringLiteral()
                    {
                        Span = child.Span, Value = (string)(child.Token.Value)
                    });
                }
                else if (child.Token != null && child.Token.Terminal is KeyTerm)
                {
                    string val = child.Token.ValueString;
                    if (val == "true")
                    {
                        return new Ast.BoolLiteral()
                               {
                                   Span = child.Span, Value = true
                               }
                    }
                    ;
                    else if (val == "false")
                    {
                        return new Ast.BoolLiteral()
                               {
                                   Span = child.Span, Value = false
                               }
                    }
                    ;
                    else if (val == "nil")
                    {
                        return new Ast.NilLiteral()
                               {
                                   Span = child.Span
                               }
                    }
                    ;
                }
                else if (child.Term != null && child.Term.Name == "Prefix")
                {
                    return(ParsePrefix(child));
                }
                else if (child.Term != null && child.Term.Name == "OrOp")
                {
                    return(ParseOrOp(child));
                }
                else if (child.Term != null && child.Term.Name == "FunctionDef")
                {
                    return(ParseFunctionDef(child));
                }
                else if (child.Term != null && child.Term.Name == "UnaryExpr")
                {
                    return(ParseUnaryExpr(child));
                }
                else if (child.Term != null && child.Term.Name == "TableConstruct")
                {
                    return(ParseTableConstruct(child));
                }
                else if (child.Term != null && child.Term.Name == "OopCall")
                {
                    return(ParseOopCall(child));
                }
                else if (child.Term != null && child.Term.Name == "Varargs")
                {
                    return(new Ast.VarargsLiteral());
                }
            }
            throw new Exception("Invalid Expression node");
        }

        #endregion

        Ast.Block ParseBlock(ParseTreeNode node)
        {
            Ast.Block block = new Ast.Block();
            block.Statements = new List <Ast.IStatement>();
            foreach (ParseTreeNode child in node.ChildNodes)
            {
                switch (child.Term.Name)
                {
                case "Assignment":
                    block.Statements.Add(ParseAssign(child)); break;

                case "LocalAssignment":
                    block.Statements.Add(ParseLocalAssign(child)); break;

                case "FunctionCall":
                    block.Statements.Add(ParseFunctionCall(child)); break;

                case "ReturnStat":
                    block.Statements.Add(ParseReturnStat(child)); break;

                case "BreakStat":
                    block.Statements.Add(new Ast.BreakStat()); break;

                case "DoBlock":
                    block.Statements.Add(ParseDoBlock(child)); break;

                case "If":
                    block.Statements.Add(ParseIf(child)); break;

                case "While":
                    block.Statements.Add(ParseWhile(child)); break;

                case "Repeat":
                    block.Statements.Add(ParseRepeat(child)); break;

                case "FunctionDecl":
                    block.Statements.Add(ParseFunctionDecl(child)); break;

                case "For":
                    block.Statements.Add(ParseFor(child)); break;

                case "OopCall":
                    block.Statements.Add(ParseOopCall(child)); break;

                case ";":
                    break;

                default:
                    throw new NotImplementedException("Node not yet implemented");
                }
            }
            return(block);
        }

        Ast.IStatement ParseFor(ParseTreeNode node)
        {
            if (node.Term.Name == "For")
            {
                var block = ParseDoBlock(node.ChildNodes[2]);
                var type  = node.ChildNodes[1].ChildNodes[0];
                if (type.Term.Name == "NumericFor")
                {
                    var cycle = new Ast.NumericFor();
                    cycle.Span     = node.Span;
                    cycle.Block    = block;
                    cycle.Variable = type.ChildNodes[0].Token.ValueString;
                    cycle.Var      = ParseExpression(type.ChildNodes[1]);
                    cycle.Limit    = ParseExpression(type.ChildNodes[2]);
                    cycle.Step     = new Ast.NumberLiteral()
                    {
                        Span = new SourceSpan(cycle.Limit.Span.Location, 0), Value = 1
                    };
                    if (type.ChildNodes[3].ChildNodes.Count > 0)
                    {
                        var child = type.ChildNodes[3].ChildNodes[0];

                        cycle.Step = ParseExpression(child);
                    }

                    return(cycle);
                }
                else
                {
                    var cycle = new Ast.GenericFor()
                    {
                        Span = node.Span
                    };
                    cycle.Block = block;

                    var nameList = type.ChildNodes[0];
                    var exprList = type.ChildNodes[2];

                    while (true)
                    {
                        var name = nameList.ChildNodes[0].Token.ValueString;
                        cycle.Variables.Add(name);
                        var child = nameList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            nameList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    while (true)
                    {
                        var expr = ParseExpression(exprList.ChildNodes[0]);
                        cycle.Expressions.Add(expr);
                        var child = exprList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            exprList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    return(cycle);
                }
            }
            throw new Exception("Invalid For node");
        }
    }