示例#1
0
        static Expression CompileNumericFor(Ast.NumericFor stat, LabelTarget returnTarget, Expression Context)
        {
            var varValue = ToNumber(CompileSingleExpression(stat.Var, Context));
            var limit    = ToNumber(CompileSingleExpression(stat.Limit, Context));
            var step     = ToNumber(CompileSingleExpression(stat.Step, Context));

            var var         = Expression.Parameter(LuaObject_Type);
            var scope       = Expression.Parameter(LuaContext_Type);
            var @break      = Expression.Label();
            var assignScope = Expression.Assign(scope, Expression.New(LuaContext_New_parent, Context));
            var assignVar   = Expression.Assign(var, varValue);

            var condition =
                Expression.Or(
                    Expression.And(
                        Expression.GreaterThan(step, Expression.Constant((LuaObject)0)),
                        Expression.LessThanOrEqual(var, limit)),
                    Expression.And(
                        Expression.LessThanOrEqual(step, Expression.Constant((LuaObject)0)),
                        Expression.GreaterThanOrEqual(var, limit)));
            var setLocalVar = Expression.Call(scope, LuaContext_SetLocal, Expression.Constant(stat.Variable), var);
            var innerBlock  = CompileBlock(stat.Block, returnTarget, @break, scope);
            var sum         = Expression.Assign(var, Expression.Add(var, step));
            var check       = Expression.IfThenElse(GetAsBool(condition), Expression.Block(setLocalVar, innerBlock, sum), Expression.Break(@break));
            var loop        = Expression.Loop(check);

            var body = Expression.Block(new[] { var, scope }, assignScope, assignVar, loop, Expression.Label(@break));

            return(body);
        }
示例#2
0
文件: Parser.cs 项目: chenzuo/NetLua
        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");
        }
示例#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");
        }
示例#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");
        }
    }