protected Expression Visit(BinaryExpression expression) { // First, dispatch to resolve type of node at deeper level Visit((Node)expression); var leftType = expression.Left.TypeInference.TargetType; var rightType = expression.Right.TypeInference.TargetType; var returnType = expression.TypeInference.ExpectedType ?? expression.TypeInference.TargetType; bool isNumericOperator = true; switch (expression.Operator) { case BinaryOperator.LogicalAnd: case BinaryOperator.LogicalOr: isNumericOperator = false; returnType = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, true); expression.TypeInference.TargetType = returnType; break; case BinaryOperator.Less: case BinaryOperator.LessEqual: case BinaryOperator.Greater: case BinaryOperator.GreaterEqual: case BinaryOperator.Equality: case BinaryOperator.Inequality: isNumericOperator = false; returnType = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, false); TypeBase resultType = ScalarType.Bool; if (returnType is VectorType) { resultType = new VectorType(ScalarType.Bool, ((VectorType)returnType).Dimension); } else if (returnType is MatrixType) { var matrixType = (MatrixType)returnType; resultType = new MatrixType(ScalarType.Bool, matrixType.RowCount, matrixType.ColumnCount); } expression.TypeInference.TargetType = resultType; break; } if (returnType != null) { if (returnType == ScalarType.Bool && isNumericOperator) { var typeToCheck = leftType ?? rightType; if (typeToCheck != null) return ConvertExpressionToBool(expression, typeToCheck); } } if (!isNumericOperator || CastHelper.NeedConvertForBinary(leftType, returnType)) expression.Left = Cast(leftType, returnType, expression.Left); if (!isNumericOperator || CastHelper.NeedConvertForBinary(rightType, returnType)) expression.Right = Cast(rightType, returnType, expression.Right); return expression; }
/// <summary> /// Visits the specified binary expression. /// </summary> /// <param name="binaryExpression">The binary expression.</param> public override Node Visit(BinaryExpression binaryExpression) { base.Visit(binaryExpression); var leftType = binaryExpression.Left.TypeInference.TargetType; var rightType = binaryExpression.Right.TypeInference.TargetType; // No need to log an error as it has been done by the initial base.Visit( if (leftType == null || rightType == null) return binaryExpression; switch (binaryExpression.Operator) { case BinaryOperator.Multiply: binaryExpression.TypeInference.TargetType = GetMultiplyImplicitConversionType(binaryExpression.Span, leftType, rightType); break; case BinaryOperator.Divide: binaryExpression.TypeInference.TargetType = GetDivideImplicitConversionType(binaryExpression.Span, leftType, rightType); break; case BinaryOperator.Minus: case BinaryOperator.Plus: case BinaryOperator.Modulo: case BinaryOperator.LogicalAnd: case BinaryOperator.LogicalOr: case BinaryOperator.BitwiseOr: case BinaryOperator.BitwiseAnd: case BinaryOperator.BitwiseXor: case BinaryOperator.RightShift: case BinaryOperator.LeftShift: binaryExpression.TypeInference.TargetType = GetBinaryImplicitConversionType(binaryExpression.Span, leftType, rightType, false); break; case BinaryOperator.Less: case BinaryOperator.LessEqual: case BinaryOperator.Greater: case BinaryOperator.GreaterEqual: case BinaryOperator.Equality: case BinaryOperator.Inequality: var returnType = GetBinaryImplicitConversionType(binaryExpression.Span, leftType, rightType, true); binaryExpression.TypeInference.TargetType = TypeBase.CreateWithBaseType(returnType, ScalarType.Bool); break; } return binaryExpression; }
public virtual void Visit(BinaryExpression binaryExpression) { VisitDynamic(binaryExpression.Left); WriteSpace().Write(binaryExpression.Operator.ConvertToString()).WriteSpace(); VisitDynamic(binaryExpression.Right); }
private static BinaryExpression Clone(BinaryExpression expression) { return new BinaryExpression(expression.Operator, Clone(expression.Left), Clone(expression.Right)); }
/// <summary> /// Creates a ForStatement with the same behavior /// </summary> /// <param name="forEachStatement">the ForEachStatement</param> /// <returns>the ForStatement</returns> private static ForStatement ExpandForEachStatement(ForEachStatement forEachStatement) { if (forEachStatement != null) { var collec = forEachStatement.Collection.TypeInference.Declaration as Variable; LiteralExpression dimLit = null; if (collec.Type is ArrayType) { if ((collec.Type as ArrayType).Dimensions.Count == 1) { dimLit = (collec.Type as ArrayType).Dimensions[0] as LiteralExpression; } } if (dimLit != null) { var initializer = new Variable(ScalarType.Int, forEachStatement.Variable.Name.Text + "Iter", new LiteralExpression(0)); var vre = new VariableReferenceExpression(initializer.Name); var condition = new BinaryExpression(BinaryOperator.Less, vre, dimLit); var next = new UnaryExpression(UnaryOperator.PreIncrement, vre); ForStatement forStatement = new ForStatement(new DeclarationStatement(initializer), condition, next); var body = new BlockStatement(); var variable = forEachStatement.Variable; variable.InitialValue = new IndexerExpression(forEachStatement.Collection, new VariableReferenceExpression(initializer)); body.Statements.Add(new DeclarationStatement(variable)); if (forEachStatement.Body is BlockStatement) body.Statements.AddRange((forEachStatement.Body as BlockStatement).Statements); else body.Statements.Add(forEachStatement.Body); forStatement.Body = body; return forStatement; } // TODO: multidimension-array? // TODO: unroll? // TODO: multiple foreach? } return null; }
public override void Visit(BinaryExpression expression) { var prevStreamUsage = currentStreamUsage; currentStreamUsage = StreamUsage.Read; base.Visit(expression); currentStreamUsage = prevStreamUsage; }
protected void Visit(BinaryExpression expression) { var prevStreamUsage = currentStreamUsage; currentStreamUsage = StreamUsage.Read; Visit((Node)expression); currentStreamUsage = prevStreamUsage; }
/// <inheritdoc/> public override void Visit(BinaryExpression binaryExpression) { base.Visit( binaryExpression); if (values.Count < 2) { return; } var rightValue = values.Pop(); var leftValue = values.Pop(); var resultValue = 0.0; switch (binaryExpression.Operator) { case BinaryOperator.Plus: resultValue = leftValue + rightValue; break; case BinaryOperator.Minus: resultValue = leftValue - rightValue; break; case BinaryOperator.Multiply: resultValue = leftValue*rightValue; break; case BinaryOperator.Divide: resultValue = leftValue/rightValue; break; case BinaryOperator.Modulo: resultValue = leftValue%rightValue; break; case BinaryOperator.LeftShift: resultValue = (int) leftValue << (int) rightValue; break; case BinaryOperator.RightShift: resultValue = (int) leftValue >> (int) rightValue; break; case BinaryOperator.BitwiseOr: resultValue = ((int) leftValue) | ((int) rightValue); break; case BinaryOperator.BitwiseAnd: resultValue = ((int) leftValue) & ((int) rightValue); break; case BinaryOperator.BitwiseXor: resultValue = ((int) leftValue) ^ ((int) rightValue); break; case BinaryOperator.LogicalAnd: resultValue = leftValue != 0.0 && rightValue != 0.0 ? 1.0 : 0.0; break; case BinaryOperator.LogicalOr: resultValue = leftValue != 0.0 || rightValue != 0.0 ? 1.0 : 0.0; break; case BinaryOperator.GreaterEqual: resultValue = leftValue >= rightValue ? 1.0 : 0.0; break; case BinaryOperator.Greater: resultValue = leftValue > rightValue ? 1.0 : 0.0; break; case BinaryOperator.Less: resultValue = leftValue < rightValue ? 1.0 : 0.0; break; case BinaryOperator.LessEqual: resultValue = leftValue <= rightValue ? 1.0 : 0.0; break; case BinaryOperator.Equality: resultValue = leftValue == rightValue ? 1.0 : 0.0; break; case BinaryOperator.Inequality: resultValue = leftValue != rightValue ? 1.0 : 0.0; break; default: result.Error("Binary operator [{0}] is not supported", binaryExpression.Span, binaryExpression); break; } values.Push(resultValue); }
/// <summary> /// Creates assignement statements with its default value /// </summary> /// <param name="streamStruct">the stream structure</param> /// <param name="streamName">the name of the stream</param> /// <param name="inputStruct">the input structure</param> /// <param name="initialValue">the initial value</param> /// <param name="scopeStack">???</param> /// <returns>A collection of statements</returns> private static IEnumerable<Statement> AssignStreamFromInput(StructType streamStruct, string streamName, StructType inputStruct, Expression initialValue, bool basicTransformation) { foreach (var currentField in inputStruct.Fields) { // Ignore fields that don't exist in Streams. // It could happen if HSConstantMain references a stream (gets added to HS_OUTPUT), // and in HSMain CreateStreamFromInput() is called (this stream doesn't exist in DS_STREAMS). if (streamStruct.Fields.All(x => x.Name != currentField.Name)) continue; // If we have a scope stack (advanced analysis), then convert expression by appending // field to each reference to a variable of inputStruct type // i.e. "output = input1 * 3 + input2 * 5" will become "output.A = input1.A * 3 + input2.A * 5" // Otherwise consider it is as a simple a variable reference and directly append field. if (basicTransformation) { yield return new ExpressionStatement( new AssignmentExpression( AssignmentOperator.Default, new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), new MemberReferenceExpression(initialValue, currentField.Name))); } else { //yield return AssignStreamFieldFromInput(streamName, inputStruct, initialValue, scopeStack, currentField); foreach (var field in streamStruct.Fields.Where(x => x.Name == currentField.Name)) // TODO: where might be useless { if (field.Type is ArrayType) { //create a for loop var iteratorName = field.Name.Text + "_Iter"; var iterator = new Variable(ScalarType.Int, iteratorName, new LiteralExpression(0)); var start = new DeclarationStatement(iterator); var condition = new BinaryExpression(BinaryOperator.Less, new VariableReferenceExpression(iterator), (field.Type as ArrayType).Dimensions[0]); var next = new UnaryExpression(UnaryOperator.PreIncrement, new VariableReferenceExpression(iterator)); var forLoop = new ForStatement(start, condition, next); var fieldAssigner = new StreamFieldVisitor(field, new VariableReferenceExpression(iterator)); var clonedExpression = fieldAssigner.Run(ParadoxAssignmentCloner.Run(initialValue)); forLoop.Body = new ExpressionStatement( new AssignmentExpression( AssignmentOperator.Default, new IndexerExpression(new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), new VariableReferenceExpression(iterator)), clonedExpression)); yield return forLoop; } else { var fieldAssigner = new StreamFieldVisitor(field); //var clonedExpression = fieldAssigner.Run(initialValue.DeepClone()); var clonedExpression = fieldAssigner.Run(ParadoxAssignmentCloner.Run(initialValue)); yield return new ExpressionStatement( new AssignmentExpression( AssignmentOperator.Default, new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), clonedExpression)); } } } } }