Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        /// <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;
        }
Ejemplo n.º 3
0
 public virtual void Visit(BinaryExpression binaryExpression)
 {
     VisitDynamic(binaryExpression.Left);
     WriteSpace().Write(binaryExpression.Operator.ConvertToString()).WriteSpace();
     VisitDynamic(binaryExpression.Right);
 }
Ejemplo n.º 4
0
 private static BinaryExpression Clone(BinaryExpression expression)
 {
     return new BinaryExpression(expression.Operator, Clone(expression.Left), Clone(expression.Right));
 }
Ejemplo n.º 5
0
        /// <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;
 }
Ejemplo n.º 7
0
 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);
        }
Ejemplo n.º 9
0
        /// <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));
                        }
                    }
                }
            }
        }