예제 #1
0
        private void EmitRangeExprNode(ImperativeNode node, ref ProtoCore.Type inferedType)
        {
            // (Ayush) Using Decimal type instead of Double for the sake of precision. For eg. doing 0.3d - 0.1d gives a result a little less than 0.2. These inaccuracies propogate
            // through a range expression and quickly cause wrong values to be returned.
            // TODO: Revert to using double, and use extension methods to compare with tolerance

            RangeExprNode range = node as RangeExprNode;

            if ((range.FromNode is NullNode || range.FromNode is BooleanNode)
                 || (range.ToNode is NullNode || range.ToNode is BooleanNode)
                 || (range.StepNode is NullNode || range.StepNode is BooleanNode))
            {
                throw new ProtoCore.Exceptions.CompileErrorsOccured("Invalid range expression");
            }
            else if ((range.FromNode is IntNode || range.FromNode is DoubleNode)
                && (range.ToNode is IntNode || range.ToNode is DoubleNode)
                && (range.StepNode is IntNode || range.StepNode is DoubleNode))
            {
                ProtoCore.Type type = new ProtoCore.Type();
                type.UID = (int)PrimitiveType.kTypeVoid;
                type.IsIndexable = true;
                type.Name = "double";
                type.UID = (int)PrimitiveType.kTypeDouble;
                type.rank = 1;

                int totalSteps = 0;
                bool terminate = false;
                decimal current = (range.FromNode is IntNode) ? Int64.Parse((range.FromNode as IntNode).value) : Decimal.Parse((range.FromNode as DoubleNode).value);
                decimal end = (range.ToNode is IntNode) ? Int64.Parse((range.ToNode as IntNode).value) : Decimal.Parse((range.ToNode as DoubleNode).value);
                ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator;
                decimal step = (range.StepNode is IntNode) ? Int64.Parse((range.StepNode as IntNode).value) : Decimal.Parse((range.StepNode as DoubleNode).value);
                decimal stepsize = 1.0M;

                if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize)
                {
                    if (step == 0)
                    {
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    if ((end > current && step < 0) || (end < current && step > 0))
                    {
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    stepsize = step;
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num)
                {
                    if (!(range.StepNode is IntNode))
                    {
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }

                    if (step <= 0)
                    {
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    if ((step - 1) == 0)
                        stepsize = 0;
                    else
                        stepsize = (end - current) / (step - 1);
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize)
                {
                    if (step == 0)
                    {
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    RangeExprNode rnode = range;
                    IntNode newStep = new IntNode();
                    rnode.StepNode = newStep; rnode.stepoperator = ProtoCore.DSASM.RangeStepOperator.num;

                    decimal dist = end - current;
                    if (dist == 0)
                    {
                        newStep.value = "1";
                    }
                    else
                    {
                        decimal ceilStepSize = Math.Ceiling((dist) / step);
                        decimal floorStepSize = Math.Floor((dist) / step);
                        decimal numOfSteps;

                        if ((ceilStepSize == 0) || (floorStepSize == 0))
                            numOfSteps = 2;
                        else
                            numOfSteps = (Math.Abs(dist / ceilStepSize - step) < Math.Abs(dist / floorStepSize - step)) ? ceilStepSize + 1 : floorStepSize + 1;
                        newStep.value = numOfSteps.ToString();
                    }

                    EmitRangeExprNode(rnode, ref inferedType);
                    return;
                }

                bool isIntArray = (range.FromNode is IntNode) &&
                                  (range.ToNode is IntNode) &&
                                  (range.StepNode is IntNode) &&
                                  (Math.Equals(stepsize, Math.Truncate(stepsize)));
                if (isIntArray)
                {
                    type.Name = "int";
                    type.UID = (int)ProtoCore.PrimitiveType.kTypeInt;
                }

                if (stepsize == 0)
                {
                    for (int i = 0; i < step; ++i)
                    {
                        if (isIntArray)
                            EmitIntNode(new IntNode { value = current.ToString() }, ref type);
                        else
                            EmitDoubleNode(new DoubleNode { value = current.ToString() }, ref type);
                        ++totalSteps;
                    }
                }
                else
                {
                    while (true)
                    {
                        if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize)
                            terminate = (step < 0) ? ((current < end) ? true : false) : ((current > end) ? true : false);
                        else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num)
                            terminate = (totalSteps >= step) ? true : false;
                        if (terminate) break;

                        if (isIntArray)
                            EmitIntNode(new IntNode { value = current.ToString() }, ref type);
                        else
                            EmitDoubleNode(new DoubleNode { value = current.ToString() }, ref type);

                        current += stepsize;
                        ++totalSteps;
                    }
                }
                inferedType = type;
            }
            else
            {
                //traverse the from node
                DfsTraverse(range.FromNode, ref inferedType);

                //traverse the To node
                DfsTraverse(range.ToNode, ref inferedType);

                //traverse the step node
                DfsTraverse(range.StepNode, ref inferedType);

                inferedType.IsIndexable = true;
                inferedType.rank++;
            }
        }
예제 #2
0
        private void EmitRangeExprNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            RangeExprNode range = node as RangeExprNode;

            // Do some static checking...probably it is not necessary.
            // Need to move these checkings to built-in function.
            if ((range.FromNode is IntNode || range.FromNode is DoubleNode) &&
                (range.ToNode is IntNode || range.ToNode is DoubleNode) &&
                (range.StepNode == null || (range.StepNode != null && (range.StepNode is IntNode || range.StepNode is DoubleNode))))
            {
                decimal current = (range.FromNode is IntNode) ? Int64.Parse((range.FromNode as IntNode).value) : Decimal.Parse((range.FromNode as DoubleNode).value);
                decimal end = (range.ToNode is IntNode) ? Int64.Parse((range.ToNode as IntNode).value) : Decimal.Parse((range.ToNode as DoubleNode).value);
                ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator;

                decimal step = 1;
                if (range.StepNode != null)
                {
                    step = (range.StepNode is IntNode) ? Int64.Parse((range.StepNode as IntNode).value) : Decimal.Parse((range.StepNode as DoubleNode).value);
                }

                if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize)
                {
                    if (range.StepNode == null && end < current)
                    {
                        step = -1;
                    }

                    if (step == 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                    if ((end > current && step < 0) || (end < current && step > 0))
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithInvalidStepSize, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num)
                {
                    if (range.StepNode != null && !(range.StepNode is IntNode))
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNonIntegerStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }

                    if (step <= 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNegativeStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize)
                {
                    if (step == 0)
                    {
                        buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col);
                        EmitNullNode(new NullNode(), ref inferedType);
                        return;
                    }
                }
            }

            // Replace with build-in RangeExpression() function. - Yu Ke
            var tmpFrom = nodeBuilder.BuildTempVariable();
            var assignFrom = nodeBuilder.BuildBinaryExpression(tmpFrom, range.FromNode);
            EmitBinaryExpressionNode(assignFrom, ref inferedType);

            var tmpTo = nodeBuilder.BuildTempVariable();
            var assignTo = nodeBuilder.BuildBinaryExpression(tmpTo, range.ToNode);
            EmitBinaryExpressionNode(assignTo, ref inferedType);

            var tmpStep = nodeBuilder.BuildTempVariable();
            var assignStep = nodeBuilder.BuildBinaryExpression(tmpStep, range.StepNode == null ? new NullNode() : range.StepNode);
            EmitBinaryExpressionNode(assignStep, ref inferedType);

            BooleanNode hasStep = new BooleanNode { value = range.StepNode == null ? "false" : "true" };
            var tmpStepSkip = nodeBuilder.BuildTempVariable();
            var assignStepSkip = nodeBuilder.BuildBinaryExpression(tmpStepSkip, hasStep);
            EmitBinaryExpressionNode(assignStepSkip, ref inferedType);

            IntNode op = new IntNode();
            switch (range.stepoperator)
            {
                case ProtoCore.DSASM.RangeStepOperator.stepsize:
                    op.value = "0";
                    break;
                case ProtoCore.DSASM.RangeStepOperator.num:
                    op.value = "1";
                    break;
                case ProtoCore.DSASM.RangeStepOperator.approxsize:
                    op.value = "2";
                    break;
                default:
                    op.value = "-1";
                    break;
            }

            var rangeExprFunc = nodeBuilder.BuildFunctionCall(Constants.kFunctionRangeExpression,
                new List<ImperativeNode> { tmpFrom, tmpTo, tmpStep, op, tmpStepSkip });

            NodeUtils.CopyNodeLocation(rangeExprFunc, range);
            EmitFunctionCallNode(rangeExprFunc, ref inferedType, false, graphNode);

            if (range.ArrayDimensions != null)
            {
                int dimensions = DfsEmitArrayIndexHeap(range.ArrayDimensions);
                EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                EmitPushArrayIndex(dimensions);
            }
        }
예제 #3
0
        private void EmitRangeExprNode(ImperativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null)
        {
            RangeExprNode range = node as RangeExprNode;

            // Do some static checking...probably it is not necessary. 
            // Need to move these checkings to built-in function.
            if ((range.FromNode is IntNode || range.FromNode is DoubleNode) &&
                (range.ToNode is IntNode || range.ToNode is DoubleNode) &&
                (range.StepNode == null || (range.StepNode != null && (range.StepNode is IntNode || range.StepNode is DoubleNode))))
            {
                double current = (range.FromNode is IntNode) ? (range.FromNode as IntNode).Value : (range.FromNode as DoubleNode).Value;
                double end = (range.ToNode is IntNode) ? (range.ToNode as IntNode).Value : (range.ToNode as DoubleNode).Value;
                ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator;

                double step = 1;
                if (range.StepNode != null)
                {
                    step = (range.StepNode is IntNode) ? (range.StepNode as IntNode).Value : (range.StepNode as DoubleNode).Value;
                }

                bool hasAmountOp = range.HasRangeAmountOperator;
                string warningMsg = String.Empty;

                if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize)
                {
                    if (!hasAmountOp)
                    {
                        if (range.StepNode == null && end < current)
                        {
                            step = -1;
                        }

                        if (step == 0)
                        {
                            warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithStepSizeZero;
                        }
                        else if ((end > current && step < 0) || (end < current && step > 0))
                        {
                            warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithInvalidStepSize;
                        }
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num)
                {
                    if (hasAmountOp)
                    {
                        warningMsg = ProtoCore.Properties.Resources.kRangeExpressionConflictOperator;
                    }
                    else if (range.StepNode != null && !(range.StepNode is IntNode))
                    {
                        warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithNonIntegerStepNumber;
                    }
                    else if (step <= 0)
                    {
                        warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithNegativeStepNumber;
                    }
                }
                else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize)
                {
                    if (hasAmountOp)
                    {
                        warningMsg = ProtoCore.Properties.Resources.kRangeExpressionConflictOperator;
                    }
                    else if (step == 0)
                    {
                        warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithStepSizeZero;
                    }
                }

                if (!string.IsNullOrEmpty(warningMsg))
                {
                    buildStatus.LogWarning(WarningID.kInvalidRangeExpression,
                                           warningMsg,
                                           core.CurrentDSFileName,
                                           range.StepNode.line,
                                           range.StepNode.col,
                                           graphNode);
                    EmitNullNode(new NullNode(), ref inferedType);
                    return;
                }
            }

            IntNode op = null;
            switch (range.stepoperator)
            {
                case ProtoCore.DSASM.RangeStepOperator.stepsize:
                    op = new IntNode(0);
                    break;
                case ProtoCore.DSASM.RangeStepOperator.num:
                    op = new IntNode(1);
                    break;
                case ProtoCore.DSASM.RangeStepOperator.approxsize:
                    op = new IntNode(2);
                    break;
                default:
                    op = new IntNode(-1);
                    break;
            }

            var rangeExprFunc = nodeBuilder.BuildFunctionCall(
                Constants.kFunctionRangeExpression,
                new List<ImperativeNode> 
                { 
                    range.FromNode, 
                    range.ToNode, 
                    range.StepNode ?? new NullNode(),
                    op, 
                    new BooleanNode(range.StepNode != null),
                    new BooleanNode(range.HasRangeAmountOperator) 
                });

            NodeUtils.CopyNodeLocation(rangeExprFunc, range);
            EmitFunctionCallNode(rangeExprFunc, ref inferedType, false, graphNode);

            if (range.ArrayDimensions != null)
            {
                int dimensions = DfsEmitArrayIndexHeap(range.ArrayDimensions);
                EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]");
                EmitPushArrayIndex(dimensions);
            }
        }
예제 #4
0
 public IntNode(IntNode rhs)
     : base(rhs)
 {
     Value = rhs.Value;
 }
예제 #5
0
 public IntNode(IntNode rhs)
     : base(rhs)
 {
     value = rhs.value;
 }
예제 #6
0
 public IntNode(IntNode rhs)
     : base(rhs)
 {
     value = rhs.value;
 }
예제 #7
0
 public IntNode(IntNode rhs)
     : base(rhs)
 {
     Value = rhs.Value;
 }