/// <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); }
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); }