Пример #1
0
        /// <summary>
        /// Rule: ForStm -> FOR CallOrAssign TO Expr (INCBY Expr )? Statements ;
        /// </summary>
        protected override object EvalForStm(ParseTree tree, params object[] paramlist)
        {
            Namespaces.LevelDown(new Namespace("for loop"));
            var callOrAssign = (CallOrAssign)GetNode(TokenType.CallOrAssign).Eval(tree);

            if (callOrAssign.LeftSideExpr.Type == LeftSideExprType.Call || callOrAssign.LeftSideExpr.Type == LeftSideExprType.Array)
            {
                throw new ParseException("В циклах for разрешается использовать только переменнные", callOrAssign.Node);
            }
            var forStm = new ForStm
            {
                Variable         = (LeftSideExprVariable)callOrAssign.LeftSideExpr,
                AssignExpression = callOrAssign.AssignExpression,
                ToExpression     = (ExpressionBase)nodes.OfTokenType(TokenType.Expr).First().Eval(tree),
                IncByExpression  = nodes.OfTokenType(TokenType.Expr).Count() > 1 ? (ExpressionBase)nodes.OfTokenType(TokenType.Expr).Last().Eval(tree) : null,
                Statements       = (CodeBlock)GetNode(TokenType.Statements).Eval(tree),
                Node             = this
            };

            Namespaces.LevelUp();
            if (forStm.AssignExpression.GetExprType() == forStm.ToExpression.GetExprType() && (forStm.IncByExpression == null || forStm.IncByExpression.GetExprType() == forStm.AssignExpression.GetExprType()))
            {
                return(forStm);
            }
            throw new ParseException("Несовместимые типы", forStm.Node);
        }
Пример #2
0
        public dynamic Visit(ForStm stm)
        {
            var node = new TreeNode("ForLoop")
            {
                Tag = stm.Node
            };

            node.Nodes.Add(new TreeNode("Variable")
            {
                Nodes = { Visit(stm.Variable) }
            });
            node.Nodes.Add(new TreeNode("AssignExpression")
            {
                Nodes = { Visit((dynamic)stm.AssignExpression) }
            });
            node.Nodes.Add(new TreeNode("ToExpression")
            {
                Nodes = { Visit((dynamic)stm.ToExpression) }
            });
            if (stm.IncByExpression != null)
            {
                node.Nodes.Add(new TreeNode("IncByExpression")
                {
                    Nodes = { Visit((dynamic)stm.IncByExpression) }
                });
            }
            node.Nodes.Add(new TreeNode("Statements")
            {
                Nodes = { Visit(stm.Statements) }
            });
            return(node);
        }
 public dynamic Visit(ForStm stm)
 {
     return(null);
 }
 public dynamic Visit(ForStm stm)
 {
     throw new System.NotImplementedException();
 }
        public dynamic Visit(ForStm stm)
        {
            LoopsCount++;
            stm.AssignExpression = Visit(stm.AssignExpression);
            stm.Statements       = Visit(stm.Statements);
            stm.ToExpression     = Visit(stm.ToExpression);
            if (stm.IncByExpression != null)
            {
                stm.IncByExpression = Visit(stm.IncByExpression);
            }
            var strNamespace = Namespaces.Current;

            Namespaces.Current = stm.Namespace;
            stm.Variable       = Visit(stm.Variable);
            if (OptimizeMode.LoopExpansion)
            {
                var assignExpr = stm.AssignExpression as LiteralExpr;
                var toExpr     = stm.ToExpression as LiteralExpr;
                if (toExpr != null && assignExpr != null && assignExpr.GetExprType() == SymbolType.Integer)
                {
                    int startValue = assignExpr.Value;
                    int toValue    = toExpr.Value;
                    int incByValue = 1;
                    if (stm.IncByExpression != null)
                    {
                        incByValue = ((LiteralExpr)Visit((dynamic)stm.IncByExpression))?.Value ?? 1;
                    }

                    var steps = (toValue - startValue) / incByValue;
                    if (steps >= 0 && steps < OptimizeMode.LoopExpansionRepeatLimit)
                    {
                        var block = new CodeBlock {
                            Namespace = stm.Namespace, Node = stm.Node, Statements = new List <StatementBase>()
                        };
                        for (var i = startValue; i <= toValue; i += incByValue)
                        {
                            var assig = Visit(new CallOrAssign
                            {
                                Namespace        = stm.AssignExpression.Namespace,
                                Node             = stm.AssignExpression.Node,
                                AssignExpression = new LiteralExpr {
                                    Namespace = stm.Namespace, SymbolType = stm.Variable.VariableType, Value = i
                                },
                                LeftSideExpr = new LeftSideExprVariable
                                {
                                    Name         = stm.Variable.Name,
                                    Namespace    = stm.Variable.Namespace,
                                    Type         = LeftSideExprType.Variable,
                                    VariableType = stm.Variable.VariableType
                                }
                            });
                            block.Statements.Add(assig);
                            block.Statements.AddRange(Visit(stm.Statements).Statements);
                        }
                        Namespaces.Current = strNamespace;
                        LoopsCount--;
                        return(block);
                    }
                }
            }

            var assign = new CallOrAssign
            {
                Namespace        = stm.Namespace,
                Node             = stm.AssignExpression.Node,
                AssignExpression = stm.AssignExpression,
                LeftSideExpr     = new LeftSideExprVariable
                {
                    Name         = stm.Variable.Name,
                    Namespace    = stm.Namespace,
                    Type         = LeftSideExprType.Variable,
                    VariableType = stm.Variable.VariableType
                }
            };

            var loopBody = new CodeBlock
            {
                Namespace  = stm.Namespace,
                Node       = stm.Node,
                Statements = new List <StatementBase>
                {
                    stm.Statements,
                    new CallOrAssign
                    {
                        Namespace        = stm.Namespace,
                        Node             = stm.AssignExpression.Node,
                        AssignExpression = Visit(new AddExpr
                        {
                            First = new GetVariableExpr
                            {
                                Name = assign.LeftSideExpr.Name, Type = stm.Variable.VariableType
                            },
                            Second = stm.IncByExpression ?? new LiteralExpr
                            {
                                SymbolType = SymbolType.Integer,
                                Value      = 1
                            },
                            OperationText = "+",
                            Namespace     = stm.Namespace
                        }),
                        LeftSideExpr = new LeftSideExprVariable
                        {
                            Name         = stm.Variable.Name,
                            Namespace    = stm.Namespace,
                            Type         = LeftSideExprType.Variable,
                            VariableType = stm.Variable.VariableType
                        }
                    }
                }
            };

            var loop = new DoWhileStm
            {
                Namespace = stm.Namespace,
                Condition = Visit(new CompareExpr
                {
                    First = Visit(new GetVariableExpr {
                        Name = assign.LeftSideExpr.Name, Type = stm.Variable.VariableType, Namespace = stm.Namespace
                    }),
                    OperationText = "<=",
                    Second        = stm.ToExpression,
                    Namespace     = stm.Namespace
                }),
                Statements = loopBody,
                Type       = LoopType.While
            };

            var outerBlock = new CodeBlock
            {
                Statements = new List <StatementBase>(),
                Namespace  = stm.Namespace
            };

            outerBlock.Statements.Add(assign);
            outerBlock.Statements.Add(loop);

            Namespaces.Current = strNamespace;
            LoopsCount--;
            return(outerBlock);
        }