public static ProtoCore.AST.AssociativeAST.ExprListNode BuildArrayExprList(ProtoCore.AST.AssociativeAST.AssociativeNode arrayNode)
 {
     ProtoCore.AST.AssociativeAST.ExprListNode exprlist = new ProtoCore.AST.AssociativeAST.ExprListNode();
     while (arrayNode is ProtoCore.AST.AssociativeAST.ArrayNode)
     {
         ProtoCore.AST.AssociativeAST.ArrayNode array = arrayNode as ProtoCore.AST.AssociativeAST.ArrayNode;
         exprlist.list.Add(array.Expr);
         arrayNode = array.Type;
     }
     return(exprlist);
 }
Пример #2
0
 private void EmitArrayNode(AST.AssociativeAST.ArrayNode arrayNode)
 {
     if (null != arrayNode)
     {
         EmitCode("[");
         DFSTraverse(arrayNode.Expr);
         EmitCode("]");
         if (arrayNode.Type != null)
         {
             DFSTraverse(arrayNode.Type);
         }
     }
 }
Пример #3
0
        public ExportWithUnits()
        {
            SelectedExportedUnit = ConversionUnit.Feet;
            SelectedExportedUnitsSource =
                Conversions.ConversionMetricLookup[ConversionMetricUnit.Length];

            AssociativeNode geometryNode = new ArrayNode();
            AssociativeNode stringNode = new StringNode();
            InPortData.Add(new PortData("geometry", Resources.ExportToSatGeometryInputDescription, geometryNode));
            InPortData.Add(new PortData("filePath", Resources.ExportToSatFilePathDescription, stringNode));
            OutPortData.Add(new PortData("string", Resources.ExportToSatFilePathOutputDescription));

            ShouldDisplayPreviewCore = true;
            RegisterAllPorts();
        }
Пример #4
0
        private void DFSEmitSSA_AST(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist)
        {
            Validity.Assert(null != astlist && null != ssaStack);
            if (node is BinaryExpressionNode)
            {
                BinaryExpressionNode astBNode = node as BinaryExpressionNode;
                AssociativeNode leftNode = null;
                AssociativeNode rightNode = null;
                bool isSSAAssignment = false;
                if (ProtoCore.DSASM.Operator.assign == astBNode.Optr)
                {
                    leftNode = astBNode.LeftNode;
                    DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist);
                    AssociativeNode assocNode = ssaStack.Pop();

                    if (assocNode is BinaryExpressionNode)
                    {
                        rightNode = (assocNode as BinaryExpressionNode).LeftNode;
                    }
                    else
                    {
                        rightNode = assocNode;
                    }
                    isSSAAssignment = false;

                    // Handle SSA if the lhs is not an identifier
                    // A non-identifier LHS is any LHS that is not just an identifier name.
                    //  i.e. a[0], a.b, f(), f(x)
                    var isSingleIdentifier = (leftNode is IdentifierNode) && (leftNode as IdentifierNode).ArrayDimensions == null;
                    if (!isSingleIdentifier)
                    {
                        EmitSSALHS(ref leftNode, ssaStack, ref astlist);
                    }
                }
                else
                {
                    BinaryExpressionNode tnode = new BinaryExpressionNode();
                    tnode.Optr = astBNode.Optr;

                    DFSEmitSSA_AST(astBNode.LeftNode, ssaStack, ref astlist);
                    DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist);

                    AssociativeNode lastnode = ssaStack.Pop();
                    AssociativeNode prevnode = ssaStack.Pop();

                    tnode.LeftNode = prevnode is BinaryExpressionNode ? (prevnode as BinaryExpressionNode).LeftNode : prevnode;
                    tnode.RightNode = lastnode is BinaryExpressionNode ? (lastnode as BinaryExpressionNode).LeftNode : lastnode;

                    // Left node
                    leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));

                    // Right node
                    rightNode = tnode;

                    isSSAAssignment = true;
                }

                var bnode = AstFactory.BuildAssignment(leftNode, rightNode);
                bnode.isSSAAssignment = isSSAAssignment;
                bnode.IsInputExpression = astBNode.IsInputExpression;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is ArrayNode)
            {
                var arrayNode = node as ArrayNode;
                DFSEmitSSA_AST(arrayNode.Expr, ssaStack, ref astlist);

                var bnode = new BinaryExpressionNode { Optr = Operator.assign };

                // Left node
                var tmpIdent = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                Validity.Assert(null != tmpIdent);
                bnode.LeftNode = tmpIdent;

                if (arrayNode.Expr == null && arrayNode.Type == null)
                {
                    // Right node
                    bnode.RightNode = new NullNode();
                    astlist.Add(bnode);
                    ssaStack.Push(bnode);
                    return;
                }

                // pop off the dimension
                var dimensionNode = ssaStack.Pop();
                ArrayNode currentDimensionNode;
                if (dimensionNode is BinaryExpressionNode)
                {
                    currentDimensionNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null);
                }
                else
                {
                    currentDimensionNode = new ArrayNode(dimensionNode, null);
                }

                // Pop the prev SSA node where the current dimension will apply
                AssociativeNode nodePrev = ssaStack.Pop();
                if (nodePrev is BinaryExpressionNode)
                {
                    AssociativeNode rhsIdent =AstFactory.BuildIdentifier((nodePrev as BinaryExpressionNode).LeftNode.Name);
                    (rhsIdent as IdentifierNode).ArrayDimensions = currentDimensionNode;

                    bnode.RightNode = rhsIdent;

                    astlist.Add(bnode);
                    ssaStack.Push(bnode);

                    if (null != arrayNode.Type)
                    {
                        DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist);
                    }
                }
                else if (nodePrev is IdentifierListNode)
                {
                    IdentifierNode iNode = (nodePrev as IdentifierListNode).RightNode as IdentifierNode;
                    Validity.Assert(null != iNode);
                    iNode.ArrayDimensions = currentDimensionNode;


                    if (null != arrayNode.Type)
                    {
                        DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist);
                    }
                }
                else
                {
                    Validity.Assert(false);
                }
            }
            else if (node is IdentifierNode)
            {
                IdentifierNode ident = node as IdentifierNode;

                if (core.Options.GenerateSSA)
                {
                    string ssaTempName = string.Empty;
                    if (null == ident.ArrayDimensions)
                    {
                        BinaryExpressionNode bnode = new BinaryExpressionNode();
                        bnode.Optr = ProtoCore.DSASM.Operator.assign;

                        // Left node
                        ssaTempName = ProtoCore.Utils.CoreUtils.BuildSSATemp(core);
                        var identNode =AstFactory.BuildIdentifier(ssaTempName);
                        bnode.LeftNode = identNode;

                        // Right node
                        bnode.RightNode = ident;

                        bnode.isSSAAssignment = true;

                        astlist.Add(bnode);
                        ssaStack.Push(bnode);

                        // Associate the first pointer with each SSA temp
                        // It is acceptable to store firstVar even if it is not a pointer as ResolveFinalNodeRefs() will just ignore this entry 
                        // if this ssa temp is not treated as a pointer inside the function
                        string firstVar = ident.Name;
                        ssaTempToFirstPointerMap.Add(ssaTempName, firstVar);
                    }
                    else
                    {
                        EmitSSAArrayIndex(ident, ssaStack, ref astlist);
                    }
                }
                else
                {
                    BinaryExpressionNode bnode = new BinaryExpressionNode();
                    bnode.Optr = ProtoCore.DSASM.Operator.assign;

                    // Left node
                    var identNode =AstFactory.BuildIdentifier(ProtoCore.Utils.CoreUtils.BuildSSATemp(core));
                    bnode.LeftNode = identNode;

                    // Right node
                    bnode.RightNode = ident;


                    bnode.isSSAAssignment = true;

                    astlist.Add(bnode);
                    ssaStack.Push(bnode);
                }
            }
            else if (node is FunctionCallNode || node is FunctionDotCallNode)
            {
                FunctionCallNode fcNode = null;
                if (node is FunctionCallNode)
                {
                    fcNode = new FunctionCallNode(node as FunctionCallNode);

                    List<AssociativeNode> astlistArgs = new List<AssociativeNode>();

                    for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++)
                    {
                        AssociativeNode arg = fcNode.FormalArguments[idx];
                        DFSEmitSSA_AST(arg, ssaStack, ref astlistArgs);
                        AssociativeNode argNode = ssaStack.Pop();

                        if (argNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode argBinaryExpr = argNode as BinaryExpressionNode;
                            var argLeftNode = argBinaryExpr.LeftNode as IdentifierNode;
                            argLeftNode.ReplicationGuides = GetReplicationGuides(arg);
                            argLeftNode.AtLevel = GetAtLevel(arg);
                            
                            fcNode.FormalArguments[idx] = argBinaryExpr.LeftNode;
                        }
                        else
                        {
                            fcNode.FormalArguments[idx] = argNode;
                        }
                        astlist.AddRange(astlistArgs);
                        astlistArgs.Clear();
                    }
                }

                // Left node
                var leftNode =AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                if (null != fcNode)
                {
                    leftNode.ReplicationGuides = GetReplicationGuides(fcNode);
                    leftNode.AtLevel = GetAtLevel(fcNode);
                }

                var bnode = AstFactory.BuildAssignment(leftNode, fcNode);
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is IdentifierListNode)
            {
                SSAIdentList(node, ref ssaStack, ref astlist);
                AssociativeNode lastNode = null;
                Validity.Assert(astlist.Count > 0);

                // Get the last identifierlist node and set its flag
                // This is required to reset the pointerlist for every identifierlist traversed
                // i.e. 
                //      a = p.x
                //      reset the flag after traversing p.x
                //
                //      b = p.x + g.y    
                //      reset the flag after traversing p.x and p.y
                //
                int lastIndex = astlist.Count - 1;
                for (int n = lastIndex; n >= 0 ; --n)
                {
                    lastNode = astlist[n];
                    Validity.Assert(lastNode is BinaryExpressionNode);
                    
                    BinaryExpressionNode bnode = lastNode as BinaryExpressionNode;
                    Validity.Assert(bnode.Optr == Operator.assign);
                    if (bnode.RightNode is IdentifierListNode)
                    {
                        IdentifierListNode identList = bnode.RightNode as IdentifierListNode;
                        identList.IsLastSSAIdentListFactor = true;
                        break;
                    }
                }
                
                // Assign the first ssa assignment flag
                BinaryExpressionNode firstBNode = astlist[0] as BinaryExpressionNode;
                Validity.Assert(null != firstBNode);
                Validity.Assert(firstBNode.Optr == Operator.assign);
                firstBNode.isSSAFirstAssignment = true;


                //
                // Get the first pointer
                // The first pointer is the lhs of the next dotcall
                //
                // Given:     
                //      a = x.y.z
                // SSA'd to:     
                //      t0 = x      -> 'x' is the lhs of the first dotcall (x.y)
                //      t1 = t0.y
                //      t2 = t1.z
                //      a = t2

                IdentifierNode lhsIdent = null;
                if (firstBNode.RightNode is IdentifierNode)
                {
                    // In this case the rhs of the ident list is an ident
                    // Get the ident name
                    lhsIdent = (firstBNode.RightNode as IdentifierNode);
                }
                else if(firstBNode.RightNode is FunctionCallNode)
                {
                    // In this case the rhs of the ident list is a function
                    // Get the function name
                    lhsIdent = (firstBNode.RightNode as FunctionCallNode).Function as IdentifierNode;
                }   
                else
                {

                    lhsIdent = null;
                }

                //=========================================================
                //
                // 1. Backtrack and convert all identlist nodes to dot calls
                //    This can potentially be optimized by performing the dotcall transform in SSAIdentList
                //
                // 2. Associate the first pointer with each SSA temp
                //
                //=========================================================
                AssociativeNode prevNode = null;
                for (int n = 0; n <= lastIndex; n++)
                {
                    lastNode = astlist[n];

                    BinaryExpressionNode bnode = lastNode as BinaryExpressionNode;
                    Validity.Assert(bnode.Optr == Operator.assign);

                    // Get the ssa temp name
                    Validity.Assert(bnode.LeftNode is IdentifierNode);
                    string ssaTempName = (bnode.LeftNode as IdentifierNode).Name;
                    Validity.Assert(CoreUtils.IsSSATemp(ssaTempName));

                    if (bnode.RightNode is IdentifierListNode)
                    {
                        IdentifierListNode identList = bnode.RightNode as IdentifierListNode;
                        if (identList.RightNode is IdentifierNode)
                        {
                            IdentifierNode identNode = identList.RightNode as IdentifierNode;

                            ProtoCore.AST.AssociativeAST.FunctionCallNode rcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode();
                            rcall.Function = new IdentifierNode(identNode);
                            rcall.Function.Name = ProtoCore.DSASM.Constants.kGetterPrefix + rcall.Function.Name;

                            ProtoCore.Utils.CoreUtils.CopyDebugData(identList.LeftNode, lhsIdent);
                            FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, rcall, core);
                            dotCall.isLastSSAIdentListFactor = identList.IsLastSSAIdentListFactor;
                            bnode.RightNode = dotCall;
                            ProtoCore.Utils.CoreUtils.CopyDebugData(bnode, lhsIdent);

                            // Update the LHS of the next dotcall
                            //      a = x.y.z
                            //      t0 = x      
                            //      t1 = t0.y   'y' is the lhs of the next dotcall (y.z)
                            //      t2 = t1.z
                            //      a = t2
                            //
                            Validity.Assert(rcall.Function is IdentifierNode);
                            lhsIdent = rcall.Function as IdentifierNode;
                        }
                        else if (identList.RightNode is FunctionCallNode)
                        {
                            FunctionCallNode fCallNode = identList.RightNode as FunctionCallNode;


                            ProtoCore.Utils.CoreUtils.CopyDebugData(identList.LeftNode, lhsIdent);
                            FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, fCallNode, core);
                            dotCall.isLastSSAIdentListFactor = identList.IsLastSSAIdentListFactor;
                            bnode.RightNode = dotCall;

                            ProtoCore.Utils.CoreUtils.CopyDebugData(bnode, lhsIdent);

                            // Update the LHS of the next dotcall
                            //      a = x.y.z
                            //      t0 = x      
                            //      t1 = t0.y   'y' is the lhs of the next dotcall (y.z)
                            //      t2 = t1.z
                            //      a = t2
                            //
                            Validity.Assert(fCallNode.Function is IdentifierNode);
                            lhsIdent = fCallNode.Function as IdentifierNode;
                        }
                        else
                        {
                            Validity.Assert(false);
                        }
                    }
                    prevNode = bnode.RightNode;
                }
            }
            else if (node is ExprListNode)
            {
                ExprListNode exprList = node as ExprListNode;
                for (int n = 0; n < exprList.Exprs.Count; n++)
                {
                    List<AssociativeNode> currentElementASTList = new List<AssociativeNode>();
                    DFSEmitSSA_AST(exprList.Exprs[n], ssaStack, ref currentElementASTList);

                    astlist.AddRange(currentElementASTList);
                    currentElementASTList.Clear();
                    AssociativeNode argNode = ssaStack.Pop();
                    exprList.Exprs[n] = argNode is BinaryExpressionNode ? (argNode as BinaryExpressionNode).LeftNode : argNode;
                }

                var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                var bnode = AstFactory.BuildAssignment(leftNode, exprList);
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is InlineConditionalNode)
            {
                InlineConditionalNode ilnode = node as InlineConditionalNode;

                List<AssociativeNode> inlineExpressionASTList = new List<AssociativeNode>();

                // Emit the boolean condition
                DFSEmitSSA_AST(ilnode.ConditionExpression, ssaStack, ref inlineExpressionASTList);
                AssociativeNode cexpr = ssaStack.Pop();
                ilnode.ConditionExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr;
                var namenode = ilnode.ConditionExpression as ArrayNameNode;
                if (namenode != null)
                {
                    var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; 
                    namenode.ReplicationGuides = GetReplicationGuides(rightNode);
                    namenode.AtLevel = GetAtLevel(rightNode);
                }
                astlist.AddRange(inlineExpressionASTList);
                inlineExpressionASTList.Clear();

                DFSEmitSSA_AST(ilnode.TrueExpression, ssaStack, ref inlineExpressionASTList);
                cexpr = ssaStack.Pop();
                ilnode.TrueExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr;
                namenode = ilnode.TrueExpression as ArrayNameNode;
                if (namenode != null)
                {
                    var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; 
                    namenode.ReplicationGuides = GetReplicationGuides(rightNode);
                    namenode.AtLevel = GetAtLevel(rightNode);
                }
                astlist.AddRange(inlineExpressionASTList);
                inlineExpressionASTList.Clear();

                DFSEmitSSA_AST(ilnode.FalseExpression, ssaStack, ref inlineExpressionASTList);
                cexpr = ssaStack.Pop();
                ilnode.FalseExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr;
                namenode = ilnode.FalseExpression as ArrayNameNode;
                if (namenode != null)
                {
                    var rightNode = (cexpr is BinaryExpressionNode) ? (cexpr as BinaryExpressionNode).RightNode : cexpr; 
                    namenode.ReplicationGuides = GetReplicationGuides(rightNode);
                    namenode.AtLevel = GetAtLevel(rightNode);
                }
                astlist.AddRange(inlineExpressionASTList);
                inlineExpressionASTList.Clear();

                var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                var bnode = AstFactory.BuildAssignment(leftNode, ilnode);
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is RangeExprNode)
            {
                RangeExprNode rangeNode = node as RangeExprNode;

                DFSEmitSSA_AST(rangeNode.From, ssaStack, ref astlist);
                AssociativeNode fromExpr = ssaStack.Pop();
                rangeNode.From = fromExpr is BinaryExpressionNode ? (fromExpr as BinaryExpressionNode).LeftNode : fromExpr;

                DFSEmitSSA_AST(rangeNode.To, ssaStack, ref astlist);
                AssociativeNode toExpr = ssaStack.Pop();
                rangeNode.To = toExpr is BinaryExpressionNode ? (toExpr as BinaryExpressionNode).LeftNode : toExpr;

                if (rangeNode.Step != null)
                {
                    DFSEmitSSA_AST(rangeNode.Step, ssaStack, ref astlist);
                    AssociativeNode stepExpr = ssaStack.Pop();
                    rangeNode.Step = stepExpr is BinaryExpressionNode ? (stepExpr as BinaryExpressionNode).LeftNode : stepExpr;
                }

                var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                var bnode = AstFactory.BuildAssignment(leftNode, rangeNode);
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is GroupExpressionNode)
            {
                if (core.Options.GenerateSSA)
                {
                    GroupExpressionNode groupExpr = node as GroupExpressionNode;
                    if (null == groupExpr.ArrayDimensions)
                    {
                        DFSEmitSSA_AST(groupExpr.Expression, ssaStack, ref astlist);

                        var leftNode =AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                        AssociativeNode groupExprBinaryStmt = ssaStack.Pop();
                        var rightNode = (groupExprBinaryStmt as BinaryExpressionNode).LeftNode;

                        var bnode = AstFactory.BuildAssignment(leftNode, rightNode);
                        bnode.isSSAAssignment = true;

                        astlist.Add(bnode);
                        ssaStack.Push(bnode);
                    }
                    else
                    {
                        EmitSSAArrayIndex(groupExpr, ssaStack, ref astlist);
                    }
                }
                else
                {
                    // We never supported SSA on grouped expressions
                    // Keep it that way if SSA flag is off
                    ssaStack.Push(node);
                }
            }
            // We allow a null to be generated an SSA variable
            // TODO Jun: Generalize this into genrating SSA temps for all literals
            else if (node is NullNode)
            {
                var leftNode = AstFactory.BuildIdentifier(CoreUtils.BuildSSATemp(core));
                var bnode = AstFactory.BuildAssignment(leftNode, node);
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else
            {
                ssaStack.Push(node);
            }
        }
Пример #5
0
        /// <summary>
        /// Emits the SSA form of each dimension in the ArrayNode data structure
        /// The dimensionNode is updated by the function with the SSA'd dimensions
        /// 
        /// Given:
        ///     dimensionNode -> a[b][c] 
        /// Outputs:
        ///     astlist -> t0 = b
        ///             -> t1 = c
        ///     dimensionNode -> a[t0][t1] 
        ///     
        /// </summary>
        /// <param name="dimensionNode"></param>
        /// <param name="astlist"></param>
        private void EmitSSAforArrayDimension(ref ArrayNode dimensionNode, ref List<AssociativeNode> astlist)
        {
            AssociativeNode indexNode = dimensionNode.Expr;

            // Traverse first dimension
            Stack<AssociativeNode> localStack = new Stack<AssociativeNode>();
            DFSEmitSSA_AST(indexNode, localStack, ref astlist);

            AssociativeNode tempIndexNode = localStack.Last();
            if (tempIndexNode is BinaryExpressionNode)
            {
                dimensionNode.Expr = (tempIndexNode as BinaryExpressionNode).LeftNode;

                // Traverse next dimension
                indexNode = dimensionNode.Type;
                while (indexNode is ArrayNode)
                {
                    ArrayNode arrayNode = indexNode as ArrayNode;
                    localStack = new Stack<AssociativeNode>();
                    DFSEmitSSA_AST(arrayNode.Expr, localStack, ref astlist);
                    tempIndexNode = localStack.Last();
                    if (tempIndexNode is BinaryExpressionNode)
                    {
                        arrayNode.Expr = (tempIndexNode as BinaryExpressionNode).LeftNode;
                    }
                    indexNode = arrayNode.Type;
                }
            }
        }
Пример #6
0
        /// <summary>
        /// This function applies SSA tranform to an array indexed identifier or identifier list
        /// 
        /// The transform applies as such:
        ///     i = 0
        ///     j = 1
        ///     x = a[i][j]
        ///     
        ///     t0 = a
        ///     t1 = i
        ///     t2 = t0[t1]
        ///     t3 = j
        ///     t4 = t2[t3]
        ///     x = t4
        /// 
        /// </summary>
        /// <param name="idendNode"></param>
        /// <param name="ssaStack"></param>
        /// <param name="astlist"></param>
        private void EmitSSAArrayIndex(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist, bool isSSAPointerAssignment = false)
        {
            //
            // Build the first SSA binary assignment of the identifier without its indexing
            //  x = a[i][j] -> t0 = a
            //
            BinaryExpressionNode bnode = new BinaryExpressionNode();
            bnode.Optr = ProtoCore.DSASM.Operator.assign;

            // Left node
            string ssaTempName = ProtoCore.Utils.CoreUtils.BuildSSATemp(core);
            var tmpName =AstFactory.BuildIdentifier(ssaTempName);
            bnode.LeftNode = tmpName;
            bnode.isSSAAssignment = true;
            bnode.isSSAPointerAssignment = isSSAPointerAssignment;
            bnode.isSSAFirstAssignment = true;

            IdentifierNode identNode = null;
            ArrayNode arrayDimensions = null;
            string firstVarName = string.Empty;
            if (node is IdentifierNode)
            {
                identNode = node as IdentifierNode;

                // Right node - Array indexing will be applied to this new identifier
                firstVarName = identNode.Name;
                bnode.RightNode =AstFactory.BuildIdentifier(firstVarName);
                ProtoCore.Utils.CoreUtils.CopyDebugData(bnode.RightNode, node);

                // Get the array dimensions of this node
                arrayDimensions = identNode.ArrayDimensions;


                // Associate the first pointer with each SSA temp
                // It is acceptable to store firstVar even if it is not a pointer as ResolveFinalNodeRefs() will just ignore this entry 
                // if this ssa temp is not treated as a pointer inside the function
                if (!ssaTempToFirstPointerMap.ContainsKey(ssaTempName))
                {
                    ssaTempToFirstPointerMap.Add(ssaTempName, firstVarName);
                }
            }
            else if (node is FunctionCallNode)
            {
                FunctionCallNode fcall = node as FunctionCallNode;
                Validity.Assert(fcall.Function is IdentifierNode);
                identNode = fcall.Function as IdentifierNode;

                // Assign the function array and guide properties to the new ident node
                identNode.ArrayDimensions = fcall.ArrayDimensions;
                identNode.ReplicationGuides = fcall.ReplicationGuides;
                identNode.AtLevel = fcall.AtLevel;

                // Right node - Remove the function array indexing.
                // The array indexing to this function will be applied downstream 
                fcall.ArrayDimensions = null;
                bnode.RightNode = fcall;
                //ProtoCore.Utils.CoreUtils.CopyDebugData(bnode.RightNode, node);

                // Get the array dimensions of this node
                arrayDimensions = identNode.ArrayDimensions;
            }
            else if (node is IdentifierListNode)
            {
                // Apply array indexing to the right node of the ident list
                //      a = p.x[i] -> apply it to x
                IdentifierListNode identList = node as IdentifierListNode;
                AssociativeNode rhsNode = identList.RightNode;

                if (rhsNode is IdentifierNode)
                {
                    identNode = rhsNode as IdentifierNode;

                    // Replace the indexed identifier with a new ident with the same name
                    //      i.e. replace x[i] with x
                    AssociativeNode nonIndexedIdent =AstFactory.BuildIdentifier(identNode.Name);
                    identList.RightNode = nonIndexedIdent;

                    // Get the array dimensions of this node
                    arrayDimensions = identNode.ArrayDimensions;
                }
                else if (rhsNode is FunctionCallNode)
                {
                    FunctionCallNode fcall = rhsNode as FunctionCallNode;
                    identNode = fcall.Function as IdentifierNode;

                    AssociativeNode newCall = AstFactory.BuildFunctionCall(identNode.Name, fcall.FormalArguments);

                    // Assign the function array and guide properties to the new ident node
                    identNode.ArrayDimensions = fcall.ArrayDimensions;
                    identNode.ReplicationGuides = fcall.ReplicationGuides;
                    identNode.AtLevel = fcall.AtLevel;

                    identList.RightNode = newCall;

                    // Get the array dimensions of this node
                    arrayDimensions = identNode.ArrayDimensions;
                }
                else
                {
                    Validity.Assert(false, "This token is not indexable");
                }

                // Right node
                bnode.RightNode = identList;
                //ProtoCore.Utils.CoreUtils.CopyDebugData(bnode.RightNode, node);

                bnode.isSSAPointerAssignment = true;
            }
            else if (node is GroupExpressionNode)
            {
                GroupExpressionNode groupExpr = node as GroupExpressionNode;
                DFSEmitSSA_AST(groupExpr.Expression, ssaStack, ref astlist);

                arrayDimensions = groupExpr.ArrayDimensions;
            }
            else
            {
                Validity.Assert(false);
            }

            // Push the first SSA stmt
            astlist.Add(bnode);
            ssaStack.Push(bnode);

            // Traverse the array index
            //      t1 = i
            List<AssociativeNode> arrayDimASTList = new List<AssociativeNode>();
            DFSEmitSSA_AST(arrayDimensions.Expr, ssaStack, ref arrayDimASTList);
            astlist.AddRange(arrayDimASTList);
            arrayDimASTList.Clear();

            //
            // Build the indexing statement
            //      t2 = t0[t1]
            BinaryExpressionNode indexedStmt = new BinaryExpressionNode();
            indexedStmt.Optr = ProtoCore.DSASM.Operator.assign;


            // Build the left node of the indexing statement
#region SSA_INDEX_STMT_LEFT
            ssaTempName = ProtoCore.Utils.CoreUtils.BuildSSATemp(core);
            AssociativeNode tmpIdent =AstFactory.BuildIdentifier(ssaTempName);
            Validity.Assert(null != tmpIdent);
            indexedStmt.LeftNode = tmpIdent;
            //ProtoCore.Utils.CoreUtils.CopyDebugData(bnode, node);



            // Associate the first pointer with each SSA temp
            // It is acceptable to store firstVar even if it is not a pointer as ResolveFinalNodeRefs() will just ignore this entry 
            // if this ssa temp is not treated as a pointer inside the function
            if (!string.IsNullOrEmpty(firstVarName))
            {
                if (!ssaTempToFirstPointerMap.ContainsKey(ssaTempName))
                {
                    ssaTempToFirstPointerMap.Add(ssaTempName, firstVarName);
                }
            }

#endregion

            // Build the right node of the indexing statement
#region SSA_INDEX_STMT_RIGHT
            
            ArrayNode arrayNode = null;

            // pop off the dimension
            AssociativeNode dimensionNode = ssaStack.Pop();
            if (dimensionNode is BinaryExpressionNode)
            {
                arrayNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null);
            }
            else
            {
                arrayNode = new ArrayNode(dimensionNode, null);
            }

            // pop off the prev SSA variable
            AssociativeNode prevSSAStmt = ssaStack.Pop();

            // Assign the curent dimension to the prev SSA variable
            Validity.Assert(prevSSAStmt is BinaryExpressionNode);
            AssociativeNode rhsIdent =AstFactory.BuildIdentifier((prevSSAStmt as BinaryExpressionNode).LeftNode.Name);
            (rhsIdent as IdentifierNode).ArrayDimensions = arrayNode;

            // Right node of the indexing statement
            indexedStmt.RightNode = rhsIdent;

            astlist.Add(indexedStmt);
            ssaStack.Push(indexedStmt);


            // Traverse the next dimension
            //      [j]
            if (null != arrayDimensions.Type)
            {
                DFSEmitSSA_AST(arrayDimensions.Type, ssaStack, ref arrayDimASTList);
                astlist.AddRange(arrayDimASTList);
                arrayDimASTList.Clear();
            }
#endregion
        }
Пример #7
0
        /// <summary>
        /// This function applies SSA tranform to an array indexed identifier or identifier list
        /// 
        /// The transform applies as such:
        ///     i = 0
        ///     j = 1
        ///     x = a[i][j]
        ///     
        ///     t0 = a
        ///     t1 = i
        ///     t2 = t0[t1]
        ///     t3 = j
        ///     t4 = t2[t3]
        ///     x = t4
        /// 
        /// </summary>
        /// <param name="idendNode"></param>
        /// <param name="ssaStack"></param>
        /// <param name="astlist"></param>
        private void EmitSSAArrayIndex(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist, bool isSSAPointerAssignment = false)
        {
            //
            // Build the first SSA binary assignment of the identifier without its indexing
            //  x = a[i][j] -> t0 = a
            //
            BinaryExpressionNode bnode = new BinaryExpressionNode();
            bnode.Optr = ProtoCore.DSASM.Operator.assign;

            // Left node
            var tmpName = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
            bnode.LeftNode = tmpName;
            bnode.isSSAAssignment = true;
            bnode.isSSAPointerAssignment = isSSAPointerAssignment;
            bnode.isSSAFirstAssignment = true;

            IdentifierNode identNode = null;
            if (node is IdentifierNode)
            {
                identNode = node as IdentifierNode;

                // Right node - Array indexing will be applied to this new identifier
                bnode.RightNode = nodeBuilder.BuildIdentfier(identNode.Name);
            }
            else if (node is FunctionCallNode)
            {
                FunctionCallNode fcall = node as FunctionCallNode;
                Validity.Assert(fcall.Function is IdentifierNode);
                identNode = fcall.Function as IdentifierNode;

                // Assign the function array and guide properties to the new ident node
                identNode.ArrayDimensions = fcall.ArrayDimensions;
                identNode.ReplicationGuides = fcall.ReplicationGuides;

                // Right node - Remove the function array indexing.
                // The array indexing to this function will be applied downstream
                fcall.ArrayDimensions = null;
                bnode.RightNode = fcall;
            }
            else if (node is IdentifierListNode)
            {
                // Apply array indexing to the right node of the ident list
                //      a = p.x[i] -> apply it to x
                IdentifierListNode identList = node as IdentifierListNode;
                AssociativeNode rhsNode = identList.RightNode;

                Validity.Assert(rhsNode is IdentifierNode);
                identNode = rhsNode as IdentifierNode;

                // Replace the indexed identifier with a new ident with the same name
                //      i.e. replace x[i] with x
                AssociativeNode nonIndexedIdent = nodeBuilder.BuildIdentfier(identNode.Name);
                identList.RightNode = nonIndexedIdent;

                // Right node
                bnode.RightNode = identList;

                bnode.isSSAPointerAssignment = true;
            }
            else
            {
                Validity.Assert(false);
            }

            // Push the first SSA stmt
            astlist.Add(bnode);
            ssaStack.Push(bnode);

            // Traverse the array index
            //      t1 = i
            DFSEmitSSA_AST(identNode.ArrayDimensions.Expr, ssaStack, ref astlist);

            //
            // Build the indexing statement
            //      t2 = t0[t1]
            BinaryExpressionNode indexedStmt = new BinaryExpressionNode();
            indexedStmt.Optr = ProtoCore.DSASM.Operator.assign;

            // Build the left node of the indexing statement
            #region SSA_INDEX_STMT_LEFT
            AssociativeNode tmpIdent = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
            Validity.Assert(null != tmpIdent);
            indexedStmt.LeftNode = tmpIdent;
            #endregion

            // Build the right node of the indexing statement
            #region SSA_INDEX_STMT_RIGHT

            ArrayNode arrayNode = null;

            // pop off the dimension
            AssociativeNode dimensionNode = ssaStack.Pop();
            if (dimensionNode is BinaryExpressionNode)
            {
                arrayNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null);
            }
            else
            {
                arrayNode = new ArrayNode(dimensionNode, null);
            }

            // pop off the prev SSA variable
            AssociativeNode prevSSAStmt = ssaStack.Pop();

            // Assign the curent dimension to the prev SSA variable
            Validity.Assert(prevSSAStmt is BinaryExpressionNode);
            AssociativeNode rhsIdent = nodeBuilder.BuildIdentfier((prevSSAStmt as BinaryExpressionNode).LeftNode.Name);
            (rhsIdent as IdentifierNode).ArrayDimensions = arrayNode;

            // Right node of the indexing statement
            indexedStmt.RightNode = rhsIdent;

            astlist.Add(indexedStmt);
            ssaStack.Push(indexedStmt);

            // Traverse the next dimension
            //      [j]
            if (null != identNode.ArrayDimensions.Type)
            {
                DFSEmitSSA_AST(identNode.ArrayDimensions.Type, ssaStack, ref astlist);
            }
            #endregion
        }
Пример #8
0
        /*
        proc DFSEmit_SSA_AST(node, ssastack[], astlist[])
            if node is binary expression
                def bnode
                if node.optr is assign op
                    bnode.optr = node.optr
                    bnode.left = node.left
                    DFSEmit_SSA_AST(node.right, ssastack, astlist)
                    bnode.right = ssastack.pop()
                else
                    def tnode
                    tnode.optr = node.optr

                    DFSEmit_SSA_AST(node.left, ssastack, astlist)
                    DFSEmit_SSA_AST(node.right, ssastack, astlist)

                    def lastnode = ssastack.pop()
                    def prevnode = ssastack.pop()

                    if prevnode is binary
                        tnode.left = prevnode.left
                    else
                        tnode.left = prevnode
                    end

                    if lastnode is binary
                        tnode.right = lastnode.left
                    else
                        tnode.right = lastnode
                    end

                    bnode.optr = �=�
                    bnode.left = GetSSATemp()
                    bnode.right = tnode
                end
                astlist.append(bnode)
                ssastack.push(bnode)
            else if node is identifier
                def bnode
                bnode.optr = �=�
                bnode.left = GetSSATemp()
                bnode.right = node
                astlist.append(bnode)
                ssastack.push(bnode)
            else
                ssastack.push(node)
            end
        end
        */
        private void DFSEmitSSA_AST(AssociativeNode node, Stack<AssociativeNode> ssaStack, ref List<AssociativeNode> astlist)
        {
            Debug.Assert(null != astlist && null != ssaStack);
            if (node is BinaryExpressionNode)
            {
                BinaryExpressionNode astBNode = node as BinaryExpressionNode;
                BinaryExpressionNode bnode = new BinaryExpressionNode();
                if (ProtoCore.DSASM.Operator.assign == astBNode.Optr)
                {
                    bnode.Optr = ProtoCore.DSASM.Operator.assign;
                    bnode.LeftNode = astBNode.LeftNode;
                    DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist);
                    AssociativeNode assocNode = ssaStack.Pop();

                    if (assocNode is BinaryExpressionNode)
                    {
                        bnode.RightNode = (assocNode as BinaryExpressionNode).LeftNode;
                    }
                    else
                    {
                        bnode.RightNode = assocNode;
                    }

                    bnode.isSSAAssignment = false;
                }
                else
                {
                    BinaryExpressionNode tnode = new BinaryExpressionNode();
                    tnode.Optr = astBNode.Optr;

                    DFSEmitSSA_AST(astBNode.LeftNode, ssaStack, ref astlist);
                    DFSEmitSSA_AST(astBNode.RightNode, ssaStack, ref astlist);

                    AssociativeNode lastnode = ssaStack.Pop();
                    AssociativeNode prevnode = ssaStack.Pop();
                    tnode.LeftNode = prevnode is BinaryExpressionNode ? (prevnode as BinaryExpressionNode).LeftNode : prevnode;
                    tnode.RightNode = lastnode is BinaryExpressionNode ? (lastnode as BinaryExpressionNode).LeftNode : lastnode;

                    bnode.Optr = ProtoCore.DSASM.Operator.assign;

                    // Left node
                    var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                    bnode.LeftNode = identNode;

                    // Right node
                    bnode.RightNode = tnode;

                    bnode.isSSAAssignment = true;
                }
                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is ArrayNode)
            {
                ArrayNode arrayNode = node as ArrayNode;
                DFSEmitSSA_AST(arrayNode.Expr, ssaStack, ref astlist);

                BinaryExpressionNode bnode = new BinaryExpressionNode();
                bnode.Optr = ProtoCore.DSASM.Operator.assign;

                // Left node
                AssociativeNode tmpIdent = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                Validity.Assert(null != tmpIdent);
                bnode.LeftNode = tmpIdent;

                // pop off the dimension
                AssociativeNode dimensionNode = ssaStack.Pop();
                ArrayNode currentDimensionNode = null;
                if (dimensionNode is BinaryExpressionNode)
                {
                    currentDimensionNode = new ArrayNode((dimensionNode as BinaryExpressionNode).LeftNode, null);
                }
                else
                {
                    currentDimensionNode = new ArrayNode(dimensionNode, null);
                }

                // Pop the prev SSA node where the current dimension will apply
                AssociativeNode nodePrev = ssaStack.Pop();
                if (nodePrev is BinaryExpressionNode)
                {
                    AssociativeNode rhsIdent = nodeBuilder.BuildIdentfier((nodePrev as BinaryExpressionNode).LeftNode.Name);
                    (rhsIdent as IdentifierNode).ArrayDimensions = currentDimensionNode;

                    bnode.RightNode = rhsIdent;

                    astlist.Add(bnode);
                    ssaStack.Push(bnode);

                    if (null != arrayNode.Type)
                    {
                        DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist);
                    }
                }
                else if (nodePrev is IdentifierListNode)
                {
                    IdentifierNode iNode = (nodePrev as IdentifierListNode).RightNode as IdentifierNode;
                    Validity.Assert(null != iNode);
                    iNode.ArrayDimensions = currentDimensionNode;

                    if (null != arrayNode.Type)
                    {
                        DFSEmitSSA_AST(arrayNode.Type, ssaStack, ref astlist);
                    }
                }
                else
                {
                    Validity.Assert(false);
                }

                //bnode.RightNode = rhsIdent;

                //astlist.Add(bnode);
                //ssaStack.Push(bnode);
            }
            else if (node is IdentifierNode)
            {
                IdentifierNode ident = node as IdentifierNode;

                if (null == ident.ArrayDimensions)
                {
                    BinaryExpressionNode bnode = new BinaryExpressionNode();
                    bnode.Optr = ProtoCore.DSASM.Operator.assign;

                    // Left node
                    var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                    bnode.LeftNode = identNode;

                    // Right node
                    bnode.RightNode = ident;

                    bnode.isSSAAssignment = true;

                    astlist.Add(bnode);
                    ssaStack.Push(bnode);
                }
                else
                {
                    EmitSSAArrayIndex(ident, ssaStack, ref astlist);
                }
            }
            else if (node is FunctionCallNode || node is FunctionDotCallNode)
            {
                FunctionCallNode fcNode = null;
                if (node is FunctionCallNode)
                {
                    fcNode = node as FunctionCallNode;

                    for (int idx = 0; idx < fcNode.FormalArguments.Count; idx++)
                    {
                        AssociativeNode arg = fcNode.FormalArguments[idx];
                        DFSEmitSSA_AST(arg, ssaStack, ref astlist);
                        AssociativeNode argNode = ssaStack.Pop();

                        if (argNode is BinaryExpressionNode)
                        {
                            BinaryExpressionNode argBinaryExpr = argNode as BinaryExpressionNode;
                            (argBinaryExpr.LeftNode as IdentifierNode).ReplicationGuides = GetReplicationGuidesFromASTNode(argBinaryExpr.RightNode);

                            fcNode.FormalArguments[idx] = argBinaryExpr.LeftNode;
                        }
                        else
                        {
                            fcNode.FormalArguments[idx] = argNode;
                        }
                    }
                }

                BinaryExpressionNode bnode = new BinaryExpressionNode();
                bnode.Optr = ProtoCore.DSASM.Operator.assign;

                // Left node
                var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                bnode.LeftNode = identNode;

                // Store the replication guide from the function call to the temp
                (identNode as IdentifierNode).ReplicationGuides = GetReplicationGuidesFromASTNode(node);

                //Right node
                bnode.RightNode = node;
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is IdentifierListNode)
            {
                SSAIdentList(node, ref ssaStack, ref astlist);
                AssociativeNode lastNode = null;
                Validity.Assert(astlist.Count > 0);

                // Get the last identifierlist node and set its flag
                // This is required to reset the pointerlist for every identifierlist traversed
                // i.e.
                //      a = p.x
                //      reset the flag after traversing p.x
                //
                //      b = p.x + g.y
                //      reset the flag after traversing p.x and p.y
                //
                int lastIndex = astlist.Count - 1;
                for (int n = lastIndex; n >= 0 ; --n)
                {
                    lastNode = astlist[n];
                    Validity.Assert(lastNode is BinaryExpressionNode);

                    BinaryExpressionNode bnode = lastNode as BinaryExpressionNode;
                    Validity.Assert(bnode.Optr == Operator.assign);
                    if (bnode.RightNode is IdentifierListNode)
                    {
                        IdentifierListNode identList = bnode.RightNode as IdentifierListNode;
                        identList.isLastSSAIdentListFactor = true;
                        break;
                    }
                }

                //
                // Backtrack and convert all identlist nodes to dot calls
                // This can potentially be optimized by performing the dotcall transform in SSAIdentList
                //

                ///////////////////////////

                int x = 0;

                for (int n = lastIndex; n >= 0; --n)
                {
                    lastNode = astlist[n];

                    BinaryExpressionNode bnode = lastNode as BinaryExpressionNode;
                    Validity.Assert(bnode.Optr == Operator.assign);

                    if (bnode.RightNode is IdentifierListNode)
                    {
                        IdentifierListNode identList = bnode.RightNode as IdentifierListNode;
                        if (identList.RightNode is IdentifierNode)
                        {
                            IdentifierNode identNode = identList.RightNode as IdentifierNode;

                            ProtoCore.AST.AssociativeAST.FunctionCallNode rcall = new ProtoCore.AST.AssociativeAST.FunctionCallNode();
                            rcall.Function = new IdentifierNode(identNode);
                            rcall.Function.Name = ProtoCore.DSASM.Constants.kGetterPrefix + rcall.Function.Name;

                            FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, rcall, compileStateTracker);
                            dotCall.isLastSSAIdentListFactor = identList.isLastSSAIdentListFactor;
                            bnode.RightNode = dotCall;

                        }
                        else if (identList.RightNode is FunctionCallNode)
                        {
                            FunctionCallNode fCallNode = identList.RightNode as FunctionCallNode;

                            FunctionDotCallNode dotCall = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(identList.LeftNode, fCallNode, compileStateTracker);
                            dotCall.isLastSSAIdentListFactor = identList.isLastSSAIdentListFactor;
                            bnode.RightNode = dotCall;
                        }
                        else
                        {
                            Validity.Assert(false);
                        }
                    }

                    if (bnode.isSSAFirstAssignment)
                    {
                        break;
                    }
                }

                ///////////////////////////
            }
            else if (node is ExprListNode)
            {
                ExprListNode exprList = node as ExprListNode;
                for (int n = 0; n < exprList.list.Count; n++)
                {
                    DFSEmitSSA_AST(exprList.list[n], ssaStack, ref astlist);
                    AssociativeNode argNode = ssaStack.Pop();
                    exprList.list[n] = argNode is BinaryExpressionNode ? (argNode as BinaryExpressionNode).LeftNode : argNode;
                }

                BinaryExpressionNode bnode = new BinaryExpressionNode();
                bnode.Optr = ProtoCore.DSASM.Operator.assign;

                // Left node
                var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                bnode.LeftNode = identNode;

                //Right node
                bnode.RightNode = exprList;
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is InlineConditionalNode)
            {
                InlineConditionalNode ilnode = node as InlineConditionalNode;

                DFSEmitSSA_AST(ilnode.ConditionExpression, ssaStack, ref astlist);
                AssociativeNode cexpr = ssaStack.Pop();
                ilnode.ConditionExpression = cexpr is BinaryExpressionNode ? (cexpr as BinaryExpressionNode).LeftNode : cexpr;

                DFSEmitSSA_AST(ilnode.TrueExpression, ssaStack, ref astlist);
                AssociativeNode trueExpr = ssaStack.Pop();
                ilnode.TrueExpression = trueExpr is BinaryExpressionNode ? (trueExpr as BinaryExpressionNode).LeftNode : trueExpr;

                DFSEmitSSA_AST(ilnode.FalseExpression, ssaStack, ref astlist);
                AssociativeNode falseExpr = ssaStack.Pop();
                ilnode.FalseExpression = falseExpr is BinaryExpressionNode ? (falseExpr as BinaryExpressionNode).LeftNode : falseExpr;

                BinaryExpressionNode bnode = new BinaryExpressionNode();
                bnode.Optr = ProtoCore.DSASM.Operator.assign;

                // Left node
                var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                bnode.LeftNode = identNode;

                //Right node
                bnode.RightNode = ilnode;
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else if (node is RangeExprNode)
            {
                RangeExprNode rangeNode = node as RangeExprNode;

                DFSEmitSSA_AST(rangeNode.FromNode, ssaStack, ref astlist);
                AssociativeNode fromExpr = ssaStack.Pop();
                rangeNode.FromNode = fromExpr is BinaryExpressionNode ? (fromExpr as BinaryExpressionNode).LeftNode : fromExpr;

                DFSEmitSSA_AST(rangeNode.ToNode, ssaStack, ref astlist);
                AssociativeNode toExpr = ssaStack.Pop();
                rangeNode.ToNode = toExpr is BinaryExpressionNode ? (toExpr as BinaryExpressionNode).LeftNode : toExpr;

                if (rangeNode.StepNode != null)
                {
                    DFSEmitSSA_AST(rangeNode.StepNode, ssaStack, ref astlist);
                    AssociativeNode stepExpr = ssaStack.Pop();
                    rangeNode.StepNode = stepExpr is BinaryExpressionNode ? (stepExpr as BinaryExpressionNode).LeftNode : stepExpr;
                }

                BinaryExpressionNode bnode = new BinaryExpressionNode();
                bnode.Optr = ProtoCore.DSASM.Operator.assign;

                // Left node
                var identNode = nodeBuilder.BuildIdentfier(ProtoCore.Utils.CoreUtils.GetSSATemp(compileStateTracker));
                bnode.LeftNode = identNode;

                //Right node
                bnode.RightNode = rangeNode;
                bnode.isSSAAssignment = true;

                astlist.Add(bnode);
                ssaStack.Push(bnode);
            }
            else
            {
                ssaStack.Push(node);
            }
        }
Пример #9
0
	void Associative_NameReference(out ProtoCore.AST.AssociativeAST.AssociativeNode node) {
		ProtoCore.AST.AssociativeAST.ArrayNameNode nameNode = null; 
		ProtoCore.AST.AssociativeAST.GroupExpressionNode groupExprNode = null;
		
		if (la.kind == 12) {
			Get();
			Associative_Expression(out node);
			if (node is ProtoCore.AST.AssociativeAST.ArrayNameNode)
			{
			   nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			}
			else
			{
			   groupExprNode = new ProtoCore.AST.AssociativeAST.GroupExpressionNode();
			   groupExprNode.Expression = node;
			   nameNode = groupExprNode;
			}
			
			Expect(13);
		} else if (IsFunctionCall()) {
			if (isLeft)
			{
			  errors.SemErr(la.line, la.col, Resources.FunctionCallCannotBeAtLeftSide);
			} 
			
			Associative_FunctionCall(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode; 
			
		} else if (la.kind == 1) {
			Associative_Ident(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode; 
			
		} else if (la.kind == 45) {
			Associative_ArrayExprList(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			
		} else SynErr(99);
		if (la.kind == 10) {
			ProtoCore.AST.AssociativeAST.ArrayNode array = new ProtoCore.AST.AssociativeAST.ArrayNode(); 
			
			Get();
			if (StartOf(4)) {
				bool tmpIsLeft = isLeft; 
				isLeft = false;
				
				Associative_Expression(out node);
				isLeft = tmpIsLeft; 
				array.Expr = node; 
				array.Type = nameNode.ArrayDimensions;
				NodeUtils.SetNodeLocation(array, t);
				nameNode.ArrayDimensions = array; 
				
				
			}
			Expect(11);
			while (la.kind == 10) {
				Get();
				if (StartOf(4)) {
					bool tmpIsLeft = isLeft; 
					isLeft = false;
					
					Associative_Expression(out node);
					isLeft = tmpIsLeft; 
					ProtoCore.AST.AssociativeAST.ArrayNode array2 = new ProtoCore.AST.AssociativeAST.ArrayNode();
					array2.Expr = node; 
					array2.Type = null;
					NodeUtils.SetNodeLocation(array2, t);
					array.Type = array2;
					array = array2;
					
				}
				Expect(11);
			}
			if (groupExprNode != null)
			{
			   var expr = groupExprNode.Expression;
			   if (expr is ProtoCore.AST.AssociativeAST.IdentifierListNode)
			   {
			       var rightNode = (expr as ProtoCore.AST.AssociativeAST.IdentifierListNode).RightNode;
			       if (rightNode is ProtoCore.AST.AssociativeAST.ArrayNameNode)
			       {
			           var rightMostArrayNameNode = rightNode as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			           if (rightMostArrayNameNode.ArrayDimensions == null)
			           {
			               rightMostArrayNameNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			           }
			           else 
			           {
			               rightMostArrayNameNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			           }
			           groupExprNode.ArrayDimensions = null;
			       }
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.RangeExprNode)
			   {    
			       var rangeExprNode = expr as ProtoCore.AST.AssociativeAST.RangeExprNode; 
			       if (rangeExprNode.ArrayDimensions == null)
			       {
			           rangeExprNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			       }
			       else 
			       {
			           rangeExprNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.ExprListNode)
			   {    
			       var exprListNode = expr as ProtoCore.AST.AssociativeAST.ExprListNode; 
			       if (exprListNode.ArrayDimensions == null)
			       {
			           exprListNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			       }
			       else 
			       {
			           exprListNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
			   {
			       var dotCall = (expr as ProtoCore.AST.AssociativeAST.FunctionDotCallNode).DotCall;
			       var arrayExpr = (dotCall.FormalArguments[2] as ProtoCore.AST.AssociativeAST.ExprListNode);
			       var dimCount = (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode);
			
			       var dims = dimCount.Value;
			       var newdims = dims;
			
			       if (arrayExpr != null)
			       {
			           var newarray = groupExprNode.ArrayDimensions;
			           while (newarray != null)
			           {
			               arrayExpr.Exprs.Add(newarray.Expr);
			               newdims++;
			               newarray = (newarray.Type as ProtoCore.AST.AssociativeAST.ArrayNode);
			           }
			           
			           (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode).Value = newdims;
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			}
			
		}
		if (la.kind == 8 || la.kind == 9) {
			AssociativeNode levelNode = null;
			bool isDominant = false;
			
			if (la.kind == 8) {
				Get();
				Associative_Number(out levelNode);
			} else {
				Get();
				Associative_Number(out levelNode);
				isDominant = true; 
			}
			IntNode listAtLevel = levelNode as IntNode;
			if (listAtLevel != null)
			{
			   var atLevel = new AtLevelNode { Level = listAtLevel.Value, IsDominant = isDominant };
			   nameNode.AtLevel = atLevel; 
			}
			
		}
		if (IsReplicationGuide()) {
			var guides = new List<AssociativeNode>();
			Expect(17);
			string repguide = String.Empty;
			bool isLongest = false;
			ReplicationGuideNode repGuideNode = null;
			
			if (IsPostfixedReplicationGuide()) {
				Expect(7);
				isLongest = true; 
			} else if (la.kind == 2) {
				Get();
				isLongest = false; 
			} else SynErr(100);
			repguide = t.val;
			if (isLongest)
			{
			   repguide = repguide.Remove(repguide.Length - 1);
			}
			var numNode = new IdentifierNode() { Value = repguide };
			repGuideNode = new ReplicationGuideNode();
			repGuideNode.RepGuide = numNode;
			repGuideNode.IsLongest = isLongest;
			NodeUtils.SetNodeLocation(numNode, t); 
			
			Expect(18);
			guides.Add(repGuideNode); 
			while (la.kind == 17) {
				Get();
				if (IsPostfixedReplicationGuide()) {
					Expect(7);
					isLongest = true; 
				} else if (la.kind == 2) {
					Get();
					isLongest = false; 
				} else SynErr(101);
				repguide = t.val;
				if (isLongest)
				{
				   repguide = repguide.Remove(repguide.Length - 1);
				}
				numNode = AstFactory.BuildIdentifier(repguide);
				repGuideNode = new ReplicationGuideNode();
				repGuideNode.RepGuide = numNode;
				repGuideNode.IsLongest = isLongest;
				NodeUtils.SetNodeLocation(numNode, t); 
				
				Expect(18);
				guides.Add(repGuideNode); 
			}
			nameNode.ReplicationGuides = guides; 
			if (groupExprNode != null)
			{
			   var expr = groupExprNode.Expression;
			   if (expr is IdentifierListNode)
			   {
			       var rightNode = (expr as IdentifierListNode).RightNode;
			       if (rightNode is ArrayNameNode)
			       {
			           var rightMostArrayNameNode = rightNode as ArrayNameNode;
			           if (rightMostArrayNameNode.ReplicationGuides == null)
			           {
			               rightMostArrayNameNode.ReplicationGuides = guides;
			           }
			           else
			           {
			               rightMostArrayNameNode.ReplicationGuides.InsertRange(0, guides);
			           }
			           groupExprNode.ReplicationGuides = null;
			       }
			   }
			   else if (expr is FunctionDotCallNode)
			   {
			       var functionCall = (expr as FunctionDotCallNode).FunctionCall;
			       var function = (functionCall.Function as ArrayNameNode);
			       if (function.ReplicationGuides == null)
			       {
			           function.ReplicationGuides = guides;
			       }
			       else
			       {
			           function.ReplicationGuides.InsertRange(0, guides);
			       }
			       groupExprNode.ReplicationGuides = null;
			   }
			}
			
		}
		if (groupExprNode != null && groupExprNode.ArrayDimensions == null && (groupExprNode.ReplicationGuides == null || groupExprNode.ReplicationGuides.Count == 0))
		{
		   node = groupExprNode.Expression;
		}
		else
		{
		   node = nameNode; 
		}
		
	}
Пример #10
0
        void Associative_NameReference(out ProtoCore.AST.AssociativeAST.AssociativeNode node)
        {
            ProtoCore.AST.AssociativeAST.ArrayNameNode nameNode = null;
            ProtoCore.AST.AssociativeAST.GroupExpressionNode groupExprNode = null;

            if (la.kind == 9) {
            Get();
            Associative_Expression(out node);
            if (node is ProtoCore.AST.AssociativeAST.FunctionCallNode
               || node is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
               nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;
            }
            else
            {
               groupExprNode = new ProtoCore.AST.AssociativeAST.GroupExpressionNode();
               groupExprNode.Expression = node;
               nameNode = groupExprNode;
            }

            Expect(10);
            } else if (IsFunctionCall()) {
            if (isLeft)
            {
              errors.SemErr(la.line, la.col, "function call is not allowed at the left hand side of an assignment");
            }

            Associative_FunctionCall(out node);
            nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;

            } else if (la.kind == 1) {
            Associative_Ident(out node);
            nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;

            } else if (la.kind == 44) {
            Associative_ArrayExprList(out node);
            nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;

            } else SynErr(102);
            if (la.kind == 7) {
            ProtoCore.AST.AssociativeAST.ArrayNode array = new ProtoCore.AST.AssociativeAST.ArrayNode();

            Get();
            if (StartOf(4)) {
                bool tmpIsLeft = isLeft;
                isLeft = false;

                Associative_Expression(out node);
                isLeft = tmpIsLeft;
                array.Expr = node;
                array.Type = null;
                NodeUtils.SetNodeLocation(array, t);
                nameNode.ArrayDimensions = array;

            }
            Expect(8);
            while (la.kind == 7) {
                Get();
                if (StartOf(4)) {
                    bool tmpIsLeft = isLeft;
                    isLeft = false;

                    Associative_Expression(out node);
                    isLeft = tmpIsLeft;
                    ProtoCore.AST.AssociativeAST.ArrayNode array2 = new ProtoCore.AST.AssociativeAST.ArrayNode();
                    array2.Expr = node;
                    array2.Type = null;
                    NodeUtils.SetNodeLocation(array2, t);
                    array.Type = array2;
                    array = array2;

                }
                Expect(8);
            }
            if (groupExprNode != null)
            {
               var expr = groupExprNode.Expression;
               if (expr is ProtoCore.AST.AssociativeAST.IdentifierListNode)
               {
                   var rightNode = (expr as ProtoCore.AST.AssociativeAST.IdentifierListNode).RightNode;
                   if (rightNode is ProtoCore.AST.AssociativeAST.ArrayNameNode)
                   {
                       var rightMostArrayNameNode = rightNode as ProtoCore.AST.AssociativeAST.ArrayNameNode;
                       if (rightMostArrayNameNode.ArrayDimensions == null)
                       {
                           rightMostArrayNameNode.ArrayDimensions = groupExprNode.ArrayDimensions;
                       }
                       else
                       {
                           rightMostArrayNameNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions;
                       }
                       groupExprNode.ArrayDimensions = null;
                   }
               }
               else if (expr is ProtoCore.AST.AssociativeAST.RangeExprNode)
               {
                   var rangeExprNode = expr as ProtoCore.AST.AssociativeAST.RangeExprNode;
                   if (rangeExprNode.ArrayDimensions == null)
                   {
                       rangeExprNode.ArrayDimensions = groupExprNode.ArrayDimensions;
                   }
                   else
                   {
                       rangeExprNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions;
                   }
                   groupExprNode.ArrayDimensions = null;
               }
               else if (expr is ProtoCore.AST.AssociativeAST.ExprListNode)
               {
                   var exprListNode = expr as ProtoCore.AST.AssociativeAST.ExprListNode;
                   if (exprListNode.ArrayDimensions == null)
                   {
                       exprListNode.ArrayDimensions = groupExprNode.ArrayDimensions;
                   }
                   else
                   {
                       exprListNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions;
                   }
                   groupExprNode.ArrayDimensions = null;
               }
               else if (expr is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
               {
                   var dotCall = (expr as ProtoCore.AST.AssociativeAST.FunctionDotCallNode).DotCall;
                   var arrayExpr = (dotCall.FormalArguments[2] as ProtoCore.AST.AssociativeAST.ExprListNode);
                   var dimCount = (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode);

                   int dims = Int32.Parse(dimCount.value);
                   int newdims = dims;

                   if (arrayExpr != null)
                   {
                       var newarray = groupExprNode.ArrayDimensions;
                       while (newarray != null)
                       {
                           arrayExpr.list.Add(newarray.Expr);
                           newdims++;
                           newarray = (newarray.Type as ProtoCore.AST.AssociativeAST.ArrayNode);
                       }

                       (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode).value = newdims.ToString();
                   }
                   groupExprNode.ArrayDimensions = null;
               }
            }

            }
            if (IsReplicationGuide()) {
            var guides = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>();
            Expect(14);
            Expect(2);
            ProtoCore.AST.AssociativeAST.AssociativeNode numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = t.val };
            NodeUtils.SetNodeLocation(numNode, t);

            Expect(15);
            guides.Add(numNode);
            while (la.kind == 14) {
                Get();
                Expect(2);
                numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = t.val };
                NodeUtils.SetNodeLocation(numNode, t);

                Expect(15);
                guides.Add(numNode);

            }
            nameNode.ReplicationGuides = guides;
            if (groupExprNode != null)
            {
               var expr = groupExprNode.Expression;
               if (expr is ProtoCore.AST.AssociativeAST.IdentifierListNode)
               {
                   var rightNode = (expr as ProtoCore.AST.AssociativeAST.IdentifierListNode).RightNode;
                   if (rightNode is ProtoCore.AST.AssociativeAST.ArrayNameNode)
                   {
                       var rightMostArrayNameNode = rightNode as ProtoCore.AST.AssociativeAST.ArrayNameNode;
                       if (rightMostArrayNameNode.ReplicationGuides == null)
                       {
                           rightMostArrayNameNode.ReplicationGuides = guides;
                       }
                       else
                       {
                           rightMostArrayNameNode.ReplicationGuides.InsertRange(0, guides);
                       }
                       groupExprNode.ReplicationGuides = null;
                   }
               }
               else if (expr is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
               {
                   var functionCall = (expr as ProtoCore.AST.AssociativeAST.FunctionDotCallNode).FunctionCall;
                   var function = (functionCall.Function as ProtoCore.AST.AssociativeAST.ArrayNameNode);
                   if (function.ReplicationGuides == null)
                   {
                       function.ReplicationGuides = guides;
                   }
                   else
                   {
                       function.ReplicationGuides.InsertRange(0, guides);
                   }
                   groupExprNode.ReplicationGuides = null;
               }
            }

            }
            if (groupExprNode != null && groupExprNode.ArrayDimensions == null && groupExprNode.ReplicationGuides == null)
            {
               node = groupExprNode.Expression;
            }
            else
            {
               node = nameNode;
            }
        }
Пример #11
0
        public ArrayNameNode(ArrayNameNode rhs) : base(rhs)
        {
            ArrayDimensions = null;
            if (null != rhs.ArrayDimensions)
            {
                ArrayDimensions = new ArrayNode(rhs.ArrayDimensions);
            }

            ReplicationGuides = null;
            if (null != rhs.ReplicationGuides)
            {
                ReplicationGuides = new List<AssociativeNode>();
                foreach (AssociativeNode argNode in rhs.ReplicationGuides)
                {
                    AssociativeNode tempNode = NodeUtils.Clone(argNode);
                    ReplicationGuides.Add(tempNode);
                }
            }
        }
Пример #12
0
        public ArrayNode(ArrayNode rhs) : base(rhs)
        {
            Expr = null;
            Type = null;
            if (null != rhs)
            {
                if (null != rhs.Expr)
                {
                    Expr = NodeUtils.Clone(rhs.Expr);
                }

                if (null != rhs.Type)
                {
                    Type = NodeUtils.Clone(rhs.Type);
                }
            }
        }
Пример #13
0
	void Associative_NameReference(out ProtoCore.AST.AssociativeAST.AssociativeNode node) {
		ProtoCore.AST.AssociativeAST.ArrayNameNode nameNode = null; 
		ProtoCore.AST.AssociativeAST.GroupExpressionNode groupExprNode = null;
		
		if (la.kind == 10) {
			Get();
			Associative_Expression(out node);
			if (node is ProtoCore.AST.AssociativeAST.ArrayNameNode)
			{
			   nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			}
			else
			{
			   groupExprNode = new ProtoCore.AST.AssociativeAST.GroupExpressionNode();
			   groupExprNode.Expression = node;
			   nameNode = groupExprNode;
			}
			
			Expect(11);
		} else if (IsFunctionCall()) {
			if (isLeft)
			{
			  errors.SemErr(la.line, la.col, "function call is not allowed at the left hand side of an assignment");
			} 
			
			Associative_FunctionCall(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode; 
			
		} else if (la.kind == 1) {
			Associative_Ident(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode; 
			
		} else if (la.kind == 47) {
			Associative_ArrayExprList(out node);
			nameNode = node as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			
		} else SynErr(105);
		if (la.kind == 8) {
			ProtoCore.AST.AssociativeAST.ArrayNode array = new ProtoCore.AST.AssociativeAST.ArrayNode(); 
			
			Get();
			if (StartOf(4)) {
				bool tmpIsLeft = isLeft; 
				isLeft = false;
				
				Associative_Expression(out node);
				isLeft = tmpIsLeft; 
				array.Expr = node; 
				array.Type = nameNode.ArrayDimensions;
				NodeUtils.SetNodeLocation(array, t);
				nameNode.ArrayDimensions = array; 
				
				
			}
			Expect(9);
			while (la.kind == 8) {
				Get();
				if (StartOf(4)) {
					bool tmpIsLeft = isLeft; 
					isLeft = false;
					
					Associative_Expression(out node);
					isLeft = tmpIsLeft; 
					ProtoCore.AST.AssociativeAST.ArrayNode array2 = new ProtoCore.AST.AssociativeAST.ArrayNode();
					array2.Expr = node; 
					array2.Type = null;
					NodeUtils.SetNodeLocation(array2, t);
					array.Type = array2;
					array = array2;
					
				}
				Expect(9);
			}
			if (groupExprNode != null)
			{
			   var expr = groupExprNode.Expression;
			   if (expr is ProtoCore.AST.AssociativeAST.IdentifierListNode)
			   {
			       var rightNode = (expr as ProtoCore.AST.AssociativeAST.IdentifierListNode).RightNode;
			       if (rightNode is ProtoCore.AST.AssociativeAST.ArrayNameNode)
			       {
			           var rightMostArrayNameNode = rightNode as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			           if (rightMostArrayNameNode.ArrayDimensions == null)
			           {
			               rightMostArrayNameNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			           }
			           else 
			           {
			               rightMostArrayNameNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			           }
			           groupExprNode.ArrayDimensions = null;
			       }
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.RangeExprNode)
			   {    
			       var rangeExprNode = expr as ProtoCore.AST.AssociativeAST.RangeExprNode; 
			       if (rangeExprNode.ArrayDimensions == null)
			       {
			           rangeExprNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			       }
			       else 
			       {
			           rangeExprNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.ExprListNode)
			   {    
			       var exprListNode = expr as ProtoCore.AST.AssociativeAST.ExprListNode; 
			       if (exprListNode.ArrayDimensions == null)
			       {
			           exprListNode.ArrayDimensions = groupExprNode.ArrayDimensions;
			       }
			       else 
			       {
			           exprListNode.ArrayDimensions.Type = groupExprNode.ArrayDimensions; 
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
			   {
			       var dotCall = (expr as ProtoCore.AST.AssociativeAST.FunctionDotCallNode).DotCall;
			       var arrayExpr = (dotCall.FormalArguments[2] as ProtoCore.AST.AssociativeAST.ExprListNode);
			       var dimCount = (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode);
			
			       var dims = dimCount.Value;
			       var newdims = dims;
			
			       if (arrayExpr != null)
			       {
			           var newarray = groupExprNode.ArrayDimensions;
			           while (newarray != null)
			           {
			               arrayExpr.list.Add(newarray.Expr);
			               newdims++;
			               newarray = (newarray.Type as ProtoCore.AST.AssociativeAST.ArrayNode);
			           }
			           
			           (dotCall.FormalArguments[3] as ProtoCore.AST.AssociativeAST.IntNode).Value = newdims;
			       }
			       groupExprNode.ArrayDimensions = null;
			   }
			}
			
		}
		if (IsReplicationGuide()) {
			var guides = new List<ProtoCore.AST.AssociativeAST.AssociativeNode>();
			Expect(15);
			string repguide = String.Empty;
			bool isLongest = false;
			ProtoCore.AST.AssociativeAST.AssociativeNode numNode = null;
			ProtoCore.AST.AssociativeAST.ReplicationGuideNode repGuideNode = null;
			
			if (IsPostfixedReplicationGuide()) {
				Expect(7);
				repguide = t.val;
				repguide = repguide.Remove(repguide.Length - 1);
				isLongest = true;
				
				numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = repguide };
				repGuideNode = new ProtoCore.AST.AssociativeAST.ReplicationGuideNode();
				repGuideNode.RepGuide = numNode;
				repGuideNode.IsLongest = isLongest;
				NodeUtils.SetNodeLocation(numNode, t); 
				
			} else if (la.kind == 2) {
				Get();
				repguide = t.val;
				isLongest = false;
				numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = repguide };
				repGuideNode = new ProtoCore.AST.AssociativeAST.ReplicationGuideNode();
				repGuideNode.RepGuide = numNode;
				repGuideNode.IsLongest = isLongest;
				NodeUtils.SetNodeLocation(numNode, t); 
				
			} else SynErr(106);
			Expect(16);
			guides.Add(repGuideNode); 
			while (la.kind == 15) {
				Get();
				if (IsPostfixedReplicationGuide()) {
					Expect(7);
					repguide = t.val;
					repguide = repguide.Remove(repguide.Length - 1);
					isLongest = true;
					
					numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = repguide };
					repGuideNode = new ProtoCore.AST.AssociativeAST.ReplicationGuideNode();
					repGuideNode.RepGuide = numNode;
					repGuideNode.IsLongest = isLongest;
					NodeUtils.SetNodeLocation(numNode, t); 
					
				} else if (la.kind == 2) {
					Get();
					repguide = t.val;
					isLongest = false;
					numNode = new ProtoCore.AST.AssociativeAST.IdentifierNode() { Value = repguide };
					repGuideNode = new ProtoCore.AST.AssociativeAST.ReplicationGuideNode();
					repGuideNode.RepGuide = numNode;
					repGuideNode.IsLongest = isLongest;
					NodeUtils.SetNodeLocation(numNode, t); 
					
				} else SynErr(107);
				Expect(16);
				guides.Add(repGuideNode); 
				
			}
			nameNode.ReplicationGuides = guides; 
			if (groupExprNode != null)
			{
			   var expr = groupExprNode.Expression;
			   if (expr is ProtoCore.AST.AssociativeAST.IdentifierListNode)
			   {
			       var rightNode = (expr as ProtoCore.AST.AssociativeAST.IdentifierListNode).RightNode;
			       if (rightNode is ProtoCore.AST.AssociativeAST.ArrayNameNode)
			       {
			           var rightMostArrayNameNode = rightNode as ProtoCore.AST.AssociativeAST.ArrayNameNode;
			           if (rightMostArrayNameNode.ReplicationGuides == null)
			           {
			               rightMostArrayNameNode.ReplicationGuides = guides;
			           }
			           else
			           {
			               rightMostArrayNameNode.ReplicationGuides.InsertRange(0, guides);
			           }
			           groupExprNode.ReplicationGuides = null;
			       }
			   }
			   else if (expr is ProtoCore.AST.AssociativeAST.FunctionDotCallNode)
			   {
			       var functionCall = (expr as ProtoCore.AST.AssociativeAST.FunctionDotCallNode).FunctionCall;
			       var function = (functionCall.Function as ProtoCore.AST.AssociativeAST.ArrayNameNode);
			       if (function.ReplicationGuides == null)
			       {
			           function.ReplicationGuides = guides;
			       }
			       else
			       {
			           function.ReplicationGuides.InsertRange(0, guides);
			       }
			       groupExprNode.ReplicationGuides = null;
			   }
			}
			
		}
		if (groupExprNode != null && groupExprNode.ArrayDimensions == null && (groupExprNode.ReplicationGuides == null || groupExprNode.ReplicationGuides.Count == 0))
		{
		   node = groupExprNode.Expression;
		}
		else
		{
		   node = nameNode; 
		}
		
	}