public dynamic Visit(CallOrAssign stm) { stm.AssignExpression = (ExpressionBase)(stm.AssignExpression?.Optimize() ?? stm.AssignExpression); if (OptimizeMode.Variables && LoopsCount <= 0) { var left = stm.LeftSideExpr as LeftSideExprVariable; if (left != null) { var symbol = left.Namespace.Symbols.FirstOrDefault(x => x.Name == left.Name); if (symbol != null) { symbol.Value = null; } var right = stm.AssignExpression as LiteralExpr; if (right != null) { if (symbol != null) { symbol.Value = right.Value; } } } } return(stm); }
public dynamic Visit(CallOrAssign stm) { stm.OrderNumber = _count; _callStack.Push(stm); Visit((dynamic)stm.LeftSideExpr); VisitNext(stm); return(null); }
public dynamic Visit(CallOrAssign stm) { var node = new TreeNode("CallOrAssign") { Tag = stm.Node }; node.Nodes.Add(new TreeNode("LeftSide") { Nodes = { Visit((dynamic)stm.LeftSideExpr) } }); if (stm.AssignExpression != null) { node.Nodes.Add(new TreeNode("AssignExpr") { Nodes = { Visit((dynamic)stm.AssignExpression) } }); } return(node); }
public dynamic Visit(CallOrAssign stm) { if (stm.AssignExpression == null) { Visit((dynamic)stm.LeftSideExpr); return(null); } string name = stm.LeftSideExpr.Name; var symbol = stm.Namespace.Symbols.SingleOrDefault(x => x.Name == name); if (symbol.Type == SymbolType.Array) { var left = stm.LeftSideExpr as LeftSideExprArray; if (ReferenceEquals(symbol.CodeGenField, null)) { var dict = _codeGen.Local(_currentMethod.ExpressionFactory.New(typeof(Hashtable))); symbol.CodeGenField = dict; _codeGen.Assign(dict[Visit((dynamic)left.Index)], Visit((dynamic)stm.AssignExpression)); } else { _codeGen.Assign(((ContextualOperand)symbol.CodeGenField)[Visit((dynamic)left.Index)], Visit((dynamic)stm.AssignExpression)); } return(null); } if (ReferenceEquals(symbol.CodeGenField, null)) { symbol.CodeGenField = _codeGen.Local(Visit((dynamic)stm.AssignExpression)); } else { _codeGen.Assign(symbol.CodeGenField, Visit((dynamic)stm.AssignExpression)); } return(null); }
/// <summary> /// Rule: CallOrAssign -> Variable (Assign)? ; /// </summary> protected override object EvalCallOrAssign(ParseTree tree, params object[] paramlist) { var callOrAssignStm = new CallOrAssign { Node = this }; var assignNode = GetNode(TokenType.Assign); var leftSide = (LeftSideExprBase)GetNode(TokenType.Variable).Eval(tree, true); callOrAssignStm.LeftSideExpr = leftSide; if (assignNode != null) { if (leftSide.Type == LeftSideExprType.Call) { throw new ParseException("Попытка присвоить значение вызову функции", assignNode); } var symbol = Namespaces.Current.Symbols.SingleOrDefault(x => x.Name == leftSide.Name); var expr = (ExpressionBase)assignNode.Eval(tree); callOrAssignStm.AssignExpression = expr; var exprType = expr.GetExprType(); if (leftSide.Type == LeftSideExprType.Variable) { ((LeftSideExprVariable)leftSide).VariableType = exprType; if (symbol != null) { if (symbol.Type == SymbolType.Unknown) { symbol.Type = exprType; } else { if (symbol.Type != exprType) { throw new ParseException("Невозможно изменить тип переменной", assignNode); } } } else { Namespaces.Current.AddSymbol( new Symbol(exprType, leftSide.Name), GetNode(TokenType.Variable)); } } if (leftSide.Type == LeftSideExprType.Array) { var leftsidearray = (LeftSideExprArray)leftSide; if (symbol != null) { if (symbol.Type == SymbolType.Array) { if (symbol.ArrayKeyType != leftsidearray.ArrayKeyType) { throw new ParseException("Невозможно изменить тип ключа у массива", assignNode); } if (symbol.ArrayValueType != exprType) { throw new ParseException("Невозможно изменить тип значений массива", assignNode); } } else { throw new ParseException("Нельзя использовать скалярную переменную как массив!", assignNode); } } else { Namespaces.Current.AddSymbol( new Symbol(SymbolType.Array, leftSide.Name) { ArrayKeyType = leftsidearray.ArrayKeyType, ArrayValueType = exprType }, GetNode(TokenType.Variable)); } } } if (assignNode == null) { if (leftSide.Type == LeftSideExprType.Variable || leftSide.Type == LeftSideExprType.Array) { throw new ParseException("Отсутствует правая часть выражения", GetNode(TokenType.Variable)); } } return(callOrAssignStm); }
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); }