예제 #1
0
            /*public override void CaseAValueReturnStm(AValueReturnStm node)
             * {
             *  GetNode(node);
             *  PStm stm = GetNext(whileStm);
             *  if (stm != null)
             *      graphNode.AddSucc(GetNode(stm));
             * }*/

            public override void CaseAIfThenStm(AIfThenStm node)
            {
                //Create graph node
                Node graphNode = GetNode(node);

                //Process inner if
                node.GetBody().Apply(this);
                //Add successor and predessors
                PStm stm = GetFirst(node.GetBody());

                if (stm != null)
                {
                    graphNode.AddSucc(GetNode(stm));
                }
                stm = GetNext(node);
                if (stm != null)
                {
                    Node nextGraphNode = GetNode(stm);
                    graphNode.AddSucc(nextGraphNode);
                    List <PStm> stms = GetLast(node.GetBody());
                    foreach (PStm pStm in stms)
                    {
                        nextGraphNode.AddPred(GetNode(pStm));
                    }
                }
            }
        private PStm RemoveVariableStatement(PStm stm, PExp rightSide, int line, int pos)
        {
            if (rightSide != null)
            {
                List <PStm> statements = MakeStatements(rightSide, line, pos);

                if (statements.Count == 0)
                {
                    stm.Parent().RemoveChild(stm);
                }
                else
                {
                    PStm statement;
                    if (statements.Count == 1)
                    {
                        statement = statements[0];
                    }
                    else
                    {
                        statement = new ABlockStm(new TLBrace("{"), new AABlock(statements, new TRBrace("}")));
                    }
                    stm.ReplaceBy(statement);
                    return(statement);
                }
            }
            else
            {
                stm.Parent().RemoveChild(stm);
            }
            return(null);
        }
예제 #3
0
 public ScopeInfo(ABlockStm stm, Scope scope)
 {
     mBlock    = stm;
     mFunction = null;
     mType     = ScopeType.Block;
     mScope    = scope;
 }
        public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
        {
            PExp  expNode = (PExp)node;
            PType type    = data.ExpTypes[expNode];

            if (type is APointerType)
            {
                type = new ANamedType(new TIdentifier("string"), null);
            }
            ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName", 0, 0));
            ALvalueExp   exp   = new ALvalueExp(local);
            PStm         stm   = Util.GetAncestor <PStm>(node);
            AABlock      block = (AABlock)stm.Parent();

            node.ReplaceBy(exp);
            AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    Util.MakeClone(type, data),
                                                    new TIdentifier(varName, 0, 0), expNode);
            ALocalDeclStm newStm = new ALocalDeclStm(new TSemicolon(";"), localDecl);

            block.GetStatements().Insert(block.GetStatements().IndexOf(stm), newStm);
            NewStatements.Add(newStm);

            data.LvalueTypes[local] = type;
            data.ExpTypes[exp]      = type;
            data.LocalLinks[local]  = localDecl;
            //localDecl.Apply(this);
            exp.Apply(this);
            return;
        }
예제 #5
0
 public override void OutAMethodDecl(AMethodDecl node)
 {
     //If void return is missing, insert it.
     if (node.GetReturnType() is AVoidType && node.GetBlock() != null)
     {
         AABlock block        = (AABlock)node.GetBlock();
         bool    insertReturn = false;
         while (true)
         {
             if (block.GetStatements().Count == 0)
             {
                 insertReturn = true;
                 break;
             }
             PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
             if (lastStm is AVoidReturnStm)
             {
                 break;
             }
             if (lastStm is ABlockStm)
             {
                 block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock();
                 continue;
             }
             insertReturn = true;
             break;
         }
         if (insertReturn)
         {
             block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos)));
         }
     }
     base.OutAMethodDecl(node);
 }
예제 #6
0
 public ScopeInfo(Scope scope)
 {
     mBlock    = null;
     mFunction = null;
     mType     = ScopeType.Global;
     mScope    = scope;
 }
예제 #7
0
 private static PStm GetNext(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor <AABlock>(stm);
         if (pBlock == null)
         {
             return(null);
         }
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index < pBlock.GetStatements().Count - 1)
         {
             stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]);
             if (stm != null)
             {
                 return(stm);
             }
             index++;
         }
         stm = Util.GetAncestor <PStm>(pBlock);
         if (stm == null)
         {
             return(null);
         }
     }
 }
예제 #8
0
 public override void DefaultIn(Node node)
 {
     if ((!first || Stm == null) && node is PStm && !(node is ABlockStm))
     {
         Stm = (PStm)node;
     }
 }
예제 #9
0
 private static PStm GetPrevious(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor <AABlock>(stm);
         if (pBlock == null)
         {
             return(null);
         }
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index > 0)
         {
             stm = GetLast((PStm)pBlock.GetStatements()[index - 1]);
             if (stm != null)
             {
                 return(stm);
             }
             index--;
         }
         stm = Util.GetAncestor <PStm>(pBlock);
         if (stm == null)
         {
             return(null);
         }
     }
 }
예제 #10
0
 public ScopeInfo(AFuncDecl decl, Scope scope)
 {
     mFunction = decl;
     mBlock    = null;
     mType     = ScopeType.Function;
     mScope    = scope;
 }
            public static bool HasMoreThanOneUses(PStm statement, AALocalDecl decl, SharedData data, out ALocalLvalue lvalue)
            {
                GetUses uses = new GetUses(decl, data);

                statement.Apply(uses);
                lvalue = uses.lvalue;
                return(uses.count > 1);
            }
예제 #12
0
            public override void CaseABreakStm(ABreakStm node)
            {
                Node      graphNode = GetNode(node);
                AWhileStm whileStm  = Util.GetAncestor <AWhileStm>(node);
                PStm      stm       = GetNext(whileStm);

                if (stm != null)
                {
                    graphNode.AddSucc(GetNode(stm));
                }
            }
예제 #13
0
            private Node GetNode(PStm node)
            {
                if (StatementNodes.ContainsKey(node))
                {
                    return(StatementNodes[node]);
                }
                Node graphNode = new Node(node);

                Nodes.AddLast(graphNode);
                StatementNodes[node] = graphNode;
                return(graphNode);
            }
예제 #14
0
        public override void CaseAAssignmentExp(AAssignmentExp node)
        {
            if (!(node.Parent() is AExpStm))
            {
                PStm parentStm = Util.GetAncestor <PStm>(node);

                MoveMethodDeclsOut mover = new MoveMethodDeclsOut("multipleAssignmentsVar", finalTrans.data);
                node.GetLvalue().Apply(mover);
                PLvalue    lvalue = Util.MakeClone(node.GetLvalue(), finalTrans.data);
                ALvalueExp exp    = new ALvalueExp(lvalue);
                finalTrans.data.ExpTypes[exp] = finalTrans.data.LvalueTypes[lvalue];
                node.ReplaceBy(exp);

                AExpStm stm = new AExpStm(new TSemicolon(";"), node);



                AABlock block = (AABlock)parentStm.Parent();
                //block.GetStatements().Insert(block.GetStatements().IndexOf(parentStm), localDeclStm);
                block.GetStatements().Insert(block.GetStatements().IndexOf(parentStm), stm);

                //localDeclStm.Apply(this);
                stm.Apply(this);

                if (parentStm is AWhileStm && Util.IsAncestor(exp, ((AWhileStm)parentStm).GetCondition()))
                {
                    AWhileStm aStm = (AWhileStm)parentStm;
                    //Copy assignment before continues
                    //Before each continue in the while, and at the end.

                    //Add continue statement, if not present
                    block = (AABlock)((ABlockStm)aStm.GetBody()).GetBlock();
                    if (block.GetStatements().Count == 0 || !(block.GetStatements()[block.GetStatements().Count - 1] is AContinueStm))
                    {
                        block.GetStatements().Add(new AContinueStm(new TContinue("continue")));
                    }

                    //Get all continue statements in the while
                    ContinueFinder finder = new ContinueFinder();
                    block.Apply(finder);
                    foreach (AContinueStm continueStm in finder.Continues)
                    {
                        stm = new AExpStm(new TSemicolon(";"), Util.MakeClone(node, finalTrans.data));
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), stm);

                        stm.Apply(this);
                    }
                }
                return;
            }

            base.CaseAAssignmentExp(node);
        }
예제 #15
0
        //Convert struct variables to a collection of local variables
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)node.GetType()) && Util.HasAncestor <PStm>(node))
            {
                //Can not have init - it would be bulk copy
                AStructDecl str = data.StructTypeLinks[(ANamedType)node.GetType()];
                Dictionary <AALocalDecl, AALocalDecl> variableMap = new Dictionary <AALocalDecl, AALocalDecl>();
                PStm    pStm   = (PStm)node.Parent();
                AABlock pBlock = (AABlock)pStm.Parent();
                foreach (AALocalDecl structLocal in str.GetLocals())
                {
                    AALocalDecl replacementLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                   Util.MakeClone(structLocal.GetType(), data),
                                                                   new TIdentifier(node.GetName().Text + "_" +
                                                                                   structLocal.GetName().Text), null);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), replacementLocal));


                    AALocalDecl baseLocal = structLocal;
                    if (data.EnheritanceLocalMap.ContainsKey(baseLocal))
                    {
                        baseLocal = data.EnheritanceLocalMap[baseLocal];
                    }
                    List <AALocalDecl> localsToAdd = new List <AALocalDecl>();
                    localsToAdd.AddRange(data.EnheritanceLocalMap.Where(pair => pair.Value == baseLocal).Select(pair => pair.Key));
                    localsToAdd.Add(baseLocal);
                    foreach (AALocalDecl localDecl in localsToAdd)
                    {
                        variableMap[localDecl] = replacementLocal;
                    }
                }
                List <ALocalLvalue> uses = new List <ALocalLvalue>();
                uses.AddRange(data.LocalLinks.Where(k => k.Value == node && Util.GetAncestor <AAProgram>(k.Key) != null).Select(k => k.Key));
                foreach (ALocalLvalue lvalue in uses)
                {
                    AStructLvalue structLocalRef = (AStructLvalue)lvalue.Parent().Parent();

                    AALocalDecl  replacementLocal  = variableMap[data.StructFieldLinks[structLocalRef]];
                    ALocalLvalue replacementLvalue = new ALocalLvalue(new TIdentifier(replacementLocal.GetName().Text));
                    data.LocalLinks[replacementLvalue]  = replacementLocal;
                    data.LvalueTypes[replacementLvalue] = replacementLocal.GetType();
                    structLocalRef.ReplaceBy(replacementLvalue);
                }
                foreach (AALocalDecl replacementLocal in variableMap.Select(k => k.Value))
                {
                    replacementLocal.Apply(this);
                }
            }
            base.CaseAALocalDecl(node);
        }
예제 #16
0
 public override void DefaultIn(Node node)
 {
     if (node is PStm)
     {
         safeVariables = new List <VariableDecl>();
         PStm prev = GetPrevious((PStm)node);
         if (prev != null)
         {
             safeVariables.AddRange(safeVariablesAfterStatement[prev]);
         }
         unsafeVariables = new List <VariableDecl>();
     }
     base.DefaultIn(node);
 }
예제 #17
0
 private static PStm GetNext(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor <AABlock>(stm);
         if (pBlock == null)
         {
             return(null);
         }
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index < pBlock.GetStatements().Count - 1)
         {
             stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]);
             if (stm != null)
             {
                 return(stm);
             }
             index++;
         }
         ASTNode node = pBlock;
         stm = null;
         while (true)
         {
             if (node == null)
             {
                 return(null);
             }
             node = Util.GetNearestAncestor(node.Parent(), typeof(AABlock), typeof(PStm));
             if (node is PStm)
             {
                 stm = (PStm)node;
             }
             else if (stm == null)
             {
                 continue;
             }
             else
             {
                 break;
             }
         }
         //stm = Util.GetAncestor<PStm>(pBlock);
         if (stm == null)
         {
             return(null);
         }
     }
 }
예제 #18
0
            private void MoveOut(PExp exp, PType type)
            {
                PStm    pStm   = Util.GetAncestor <PStm>(exp);
                AABlock pBlock = (AABlock)pStm.Parent();

                ALocalLvalue lvalue    = new ALocalLvalue(new TIdentifier("gppVar"));
                ALvalueExp   lvalueExp = new ALvalueExp(lvalue);

                exp.ReplaceBy(lvalueExp);
                AALocalDecl decl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier("gppVar"), exp);

                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), decl));

                data.LvalueTypes[lvalue]     =
                    data.ExpTypes[lvalueExp] = decl.GetType();
                data.LocalLinks[lvalue]      = decl;
            }
예제 #19
0
 private static PStm GetFirst(PStm stm)
 {
     if (stm is ABlockStm)
     {
         AABlock block = (AABlock)((ABlockStm)stm).GetBlock();
         stm = null;
         for (int i = 0; i < block.GetStatements().Count; i++)
         {
             stm = GetFirst((PStm)block.GetStatements()[i]);
             if (stm != null)
             {
                 return(stm);
             }
         }
     }
     return(stm);
 }
예제 #20
0
 //Returns true if execution cannot continue after the stm
 private bool removeDeadCode(PStm stm)
 {
     if (stm is ABreakStm || stm is AContinueStm || stm is AVoidReturnStm || stm is AValueReturnStm)
     {
         return(true);
     }
     if (stm is AIfThenStm)
     {
         AIfThenStm aStm    = (AIfThenStm)stm;
         bool       stopped = removeDeadCode(aStm.GetBody());
         if (IsBoolConst(aStm.GetCondition(), true))
         {
             return(stopped);
         }
         return(false);
     }
     if (stm is AIfThenElseStm)
     {
         AIfThenElseStm aStm     = (AIfThenElseStm)stm;
         bool           stopped1 = removeDeadCode(aStm.GetThenBody());
         if (IsBoolConst(aStm.GetCondition(), true))
         {
             return(stopped1);
         }
         bool stopped2 = removeDeadCode(aStm.GetElseBody());
         if (IsBoolConst(aStm.GetCondition(), false))
         {
             return(stopped2);
         }
         return(stopped1 && stopped2);
     }
     if (stm is AWhileStm)
     {
         AWhileStm aStm = (AWhileStm)stm;
         removeDeadCode(aStm.GetBody());
         return(false);
     }
     if (stm is ABlockStm)
     {
         ABlockStm aStm = (ABlockStm)stm;
         return(removeDeadCode((AABlock)aStm.GetBlock()));
     }
     return(false);
 }
예제 #21
0
        //Returns true if execution cannot continue after the block
        private bool removeDeadCode(AABlock block)
        {
            bool isDead = false;

            for (int i = 0; i < block.GetStatements().Count; i++)
            {
                PStm stm = (PStm)block.GetStatements()[i];
                if (isDead)
                {
                    block.GetStatements().RemoveAt(i);
                    i--;
                }
                else
                {
                    isDead = removeDeadCode(stm);
                }
            }
            return(isDead);
        }
예제 #22
0
            public override void CaseAWhileStm(AWhileStm node)
            {
                //Create graph node
                Node graphNode = GetNode(node);

                //Processes inner while
                node.GetBody().Apply(this);
                //Add successor and predessors
                PStm stm = GetFirst(node.GetBody());

                if (stm != null)
                {
                    graphNode.AddSucc(GetNode(stm));
                }
                List <PStm> stms = GetLast(node.GetBody());

                foreach (PStm pStm in stms)
                {
                    graphNode.AddPred(GetNode(pStm));
                }
            }
예제 #23
0
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType)
            {
                ANamedType type = (ANamedType)node.GetType();
                if (finalTrans.data.StructTypeLinks.ContainsKey(type))
                {
                    AStructDecl strDecl = finalTrans.data.StructTypeLinks[type];
                    if (strDecl.GetLocals().Cast <PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                    {
                        MoveMethodDeclsOut mover = new MoveMethodDeclsOut("removedStructVar", finalTrans.data);
                        node.Apply(mover);
                        foreach (PStm stm in mover.NewStatements)
                        {
                            stm.Apply(this);
                        }
                        PStm pStm = Util.GetAncestor <PStm>(node);
                        if (pStm == null)
                        {
                            strDecl = Util.GetAncestor <AStructDecl>(node);


                            node.Parent().RemoveChild(node);

                            if (strDecl != null && strDecl.GetLocals().Cast <PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                            {
                                reqRerun = true;
                            }
                        }
                        else
                        {
                            pStm.Parent().RemoveChild(pStm);
                        }
                        return;
                    }
                }
            }
            base.CaseAALocalDecl(node);
        }
예제 #24
0
            private static List <PStm> GetLast(PStm stm)
            {
                List <PStm> returner = new List <PStm>();

                if (stm is ABlockStm)
                {
                    AABlock block = (AABlock)((ABlockStm)stm).GetBlock();
                    stm = null;
                    for (int i = block.GetStatements().Count - 1; i >= 0; i--)
                    {
                        returner.AddRange(GetLast((PStm)block.GetStatements()[i]));
                        if (returner.Count > 0)
                        {
                            return(returner);
                        }
                    }
                }
                else if (stm is AIfThenElseStm)
                {
                    List <PStm> stms = new List <PStm>();
                    stms.AddRange(GetLast(((AIfThenElseStm)stm).GetThenBody()));
                    bool zero = stms.Count == 0;
                    returner.AddRange(stms);
                    stms.Clear();
                    stms.AddRange(GetLast(((AIfThenElseStm)stm).GetElseBody()));
                    zero |= stms.Count == 0;
                    returner.AddRange(stms);
                    if (zero)
                    {
                        returner.Add(stm);
                    }
                }
                else
                {
                    returner.Add(stm);
                }
                return(returner);
            }
예제 #25
0
        public override void CaseAMultiLocalDecl(AMultiLocalDecl node)
        {
            PStm pStm = Util.GetAncestor <PStm>(node);

            if (!(pStm.Parent() is AABlock))
            {
                return;
            }
            AABlock            pBlock   = (AABlock)pStm.Parent();
            List <AALocalDecl> newDecls = new List <AALocalDecl>();

            foreach (AALocalDeclRight right in node.GetLocalDeclRight())
            {
                if (right.GetName() == null)
                {
                    continue;
                }
                if ((right.GetAssignop() == null) != (right.GetInit() == null))
                {
                    continue;
                }
                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null,
                                                        node.GetConst() != null
                                                            ? (TConst)node.GetConst().Clone()
                                                            : null,
                                                        (PType)node.GetType().Clone(),
                                                        right.GetName(),
                                                        right.GetInit());
                newDecls.Add(localDecl);
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl));
            }
            pBlock.RemoveChild(pStm);
            foreach (AALocalDecl localDecl in newDecls)
            {
                localDecl.Apply(this);
            }
        }
 //Returns true if execution cannot continue after the stm
 private bool removeDeadCode(PStm stm)
 {
     if (stm is ABreakStm || stm is AContinueStm || stm is AVoidReturnStm || stm is AValueReturnStm)
         return true;
     if (stm is AIfThenStm)
     {
         AIfThenStm aStm = (AIfThenStm) stm;
         bool stopped = removeDeadCode(aStm.GetBody());
         if (IsBoolConst(aStm.GetCondition(), true))
             return stopped;
         return false;
     }
     if (stm is AIfThenElseStm)
     {
         AIfThenElseStm aStm = (AIfThenElseStm)stm;
         bool stopped1 = removeDeadCode(aStm.GetThenBody());
         if (IsBoolConst(aStm.GetCondition(), true))
             return stopped1;
         bool stopped2 = removeDeadCode(aStm.GetElseBody());
         if (IsBoolConst(aStm.GetCondition(), false))
             return stopped2;
         return stopped1 && stopped2;
     }
     if (stm is AWhileStm)
     {
         AWhileStm aStm = (AWhileStm)stm;
         removeDeadCode(aStm.GetBody());
         return false;
     }
     if (stm is ABlockStm)
     {
         ABlockStm aStm = (ABlockStm)stm;
         return removeDeadCode((AABlock) aStm.GetBlock());
     }
     return false;
 }
예제 #27
0
            public override void CaseAABlock(AABlock node)
            {
                //Craete nodes
                base.CaseAABlock(node);
                //Set pred/succ
                for (int i = 0; i < node.GetStatements().Count - 1; i++)
                {
                    List <PStm> stms = GetLast((PStm)node.GetStatements()[i]);
                    for (int j = i - 1; stms.Count == 0 && j >= 0; j--)
                    {
                        stms = GetLast((PStm)node.GetStatements()[j]);
                    }

                    PStm stm2 = GetFirst((PStm)node.GetStatements()[i + 1]);
                    for (int j = i + 2; stm2 == null && j < node.GetStatements().Count; j++)
                    {
                        stm2 = GetFirst((PStm)node.GetStatements()[j]);
                    }
                    foreach (PStm stm1 in stms)
                    {
                        if (stm1 == null || stm2 == null)
                        {
                            continue;
                        }
                        if (stm1 is AIfThenElseStm ||
                            stm1 is AValueReturnStm ||
                            stm1 is AVoidReturnStm ||
                            stm1 is AContinueStm ||
                            stm1 is ABreakStm)
                        {
                            continue;
                        }
                        GetNode(stm1).AddSucc(GetNode(stm2));
                    }
                }
            }
예제 #28
0
        public static List <AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans)
        {
            /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel")
             *  node = node;*/

            SharedData data = finalTrans.data;
            //If this node is inside the condition of a while, replace it with a new local var,
            //make a clone before the while, one before each continue in the while, and one at the end of the while
            //(unless the end is a return or break)
            AABlock pBlock;

            if (Util.HasAncestor <AWhileStm>(node))
            {
                AWhileStm whileStm = Util.GetAncestor <AWhileStm>(node);
                if (Util.IsAncestor(node, whileStm.GetCondition()))
                {
                    List <ASimpleInvokeExp> toInline = new List <ASimpleInvokeExp>();
                    //Above while
                    AALocalDecl replaceVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                 Util.MakeClone(data.ExpTypes[node], data),
                                                                 new TIdentifier("whileVar"), null);
                    ALocalLvalue replaceVarRef    = new ALocalLvalue(new TIdentifier("whileVar"));
                    ALvalueExp   replaceVarRefExp = new ALvalueExp(replaceVarRef);
                    data.LocalLinks[replaceVarRef]  = replaceVarDecl;
                    data.ExpTypes[replaceVarRefExp] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                    node.ReplaceBy(replaceVarRefExp);
                    replaceVarDecl.SetInit(node);
                    pBlock = (AABlock)whileStm.Parent();
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(whileStm), new ALocalDeclStm(new TSemicolon(";"), replaceVarDecl));
                    toInline.Add(node);


                    //In the end of the while
                    PStm lastStm = whileStm.GetBody();
                    while (lastStm is ABlockStm)
                    {
                        AABlock block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        if (block.GetStatements().Count == 0)
                        {
                            lastStm = null;
                            break;
                        }
                        lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
                    }
                    if (lastStm == null || !(lastStm is AValueReturnStm || lastStm is AVoidReturnStm || lastStm is ABreakStm))
                    {
                        lastStm = whileStm.GetBody();
                        AABlock block;
                        if (lastStm is ABlockStm)
                        {
                            block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        }
                        else
                        {
                            block = new AABlock(new ArrayList(), new TRBrace("}"));
                            block.GetStatements().Add(lastStm);
                            whileStm.SetBody(new ABlockStm(new TLBrace("{"), block));
                        }

                        replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar"));
                        ASimpleInvokeExp clone = (ASimpleInvokeExp)Util.MakeClone(node, data);
                        toInline.Add(clone);
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), replaceVarRef, clone);
                        data.LocalLinks[replaceVarRef] = replaceVarDecl;
                        data.ExpTypes[assignment]      = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                        block.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));
                    }

                    //After each continue
                    CloneBeforeContinue cloner = new CloneBeforeContinue(node, replaceVarDecl, data);
                    whileStm.GetBody().Apply(cloner);
                    toInline.AddRange(cloner.replacementExpressions);
                    List <AABlock> visitBlocks = new List <AABlock>();
                    foreach (ASimpleInvokeExp invoke in toInline)
                    {
                        visitBlocks.AddRange(Inline(invoke, finalTrans));
                    }
                    return(visitBlocks);
                }
            }



            AMethodDecl           decl = finalTrans.data.SimpleMethodLinks[node];
            FindAssignedToFormals assignedToFormalsFinder = new FindAssignedToFormals(finalTrans.data);

            decl.Apply(assignedToFormalsFinder);
            List <AALocalDecl> assignedToFormals = assignedToFormalsFinder.AssignedFormals;


            /*
             * inline int foo(int a)
             * {
             *      int b = 2;
             *      int c;
             *      ...
             *      while(...)
             *      {
             *          ...
             *          break;
             *          ...
             *          return c;
             *      }
             *      ...
             *      return 2;
             * }
             *
             * bar(foo(<arg for a>));
             * ->
             *
             * {
             *      bool inlineMethodReturned = false;
             *      int inlineReturner;
             *      int a = <arg for a>;
             *      while (!inlineMethodReturned)
             *      {
             *          int b = 2;
             *          int c;
             *          ...
             *          while(...)
             *          {
             *              ...
             *              break
             *              ...
             *              inlineReturner = c;
             *              inlineMethodReturned = true;
             *              break;
             *          }
             *          if (inlineMethodReturned)
             *          {
             *              break;
             *          }
             *          ...
             *          inlineReturner = 2;
             *          inlineMethodReturned = true;
             *          break;
             *          break;
             *      }
             *      bar(inlineReturner);
             * }
             *
             *
             */


            AABlock outerBlock = new AABlock();
            PExp    exp        = new ABooleanConstExp(new AFalseBool());

            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            AALocalDecl hasMethodReturnedVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null),
                                                               new TIdentifier("hasInlineReturned"), exp);

            finalTrans.data.GeneratedVariables.Add(hasMethodReturnedVar);
            PStm stm = new ALocalDeclStm(new TSemicolon(";"), hasMethodReturnedVar);

            outerBlock.GetStatements().Add(stm);

            AALocalDecl methodReturnerVar = null;

            if (!(decl.GetReturnType() is AVoidType))
            {
                methodReturnerVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(decl.GetReturnType(), finalTrans.data),
                                                    new TIdentifier("inlineReturner"), null);
                stm = new ALocalDeclStm(new TSemicolon(";"), methodReturnerVar);
                outerBlock.GetStatements().Add(stm);
            }

            AABlock afterBlock = new AABlock();

            //A dictionary from the formals of the inline method to a cloneable replacement lvalue
            Dictionary <AALocalDecl, PLvalue> Parameters    = new Dictionary <AALocalDecl, PLvalue>();
            Dictionary <AALocalDecl, PExp>    ParameterExps = new Dictionary <AALocalDecl, PExp>();

            for (int i = 0; i < decl.GetFormals().Count; i++)
            {
                AALocalDecl formal = (AALocalDecl)decl.GetFormals()[i];
                PExp        arg    = (PExp)node.GetArgs()[0];
                PLvalue     lvalue;
                //if ref, dont make a new var
                if (formal.GetRef() != null && arg is ALvalueExp)
                {
                    arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                    arg.Parent().RemoveChild(arg);
                    lvalue = ((ALvalueExp)arg).GetLvalue();
                }
                else if (!assignedToFormals.Contains(formal) && Util.IsLocal(arg, finalTrans.data))
                {
                    lvalue = new ALocalLvalue(new TIdentifier("I hope I dont make it"));
                    finalTrans.data.LvalueTypes[lvalue] = formal.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = formal;
                    ParameterExps[formal] = arg;
                    arg.Parent().RemoveChild(arg);
                }
                else
                {
                    AAssignmentExp assExp = null;
                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                        lvalue = ((ALvalueExp)arg).GetLvalue();
                        assExp = new AAssignmentExp(new TAssign("="), lvalue, null);
                        finalTrans.data.ExpTypes[assExp] = finalTrans.data.LvalueTypes[lvalue];
                        arg.Parent().RemoveChild(arg);
                        arg = null;
                    }
                    AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data),
                                                            new TIdentifier(formal.GetName().Text),
                                                            arg);
                    stm = new ALocalDeclStm(new TSemicolon(";"), parameter);
                    outerBlock.GetStatements().Add(stm);

                    lvalue = new ALocalLvalue(new TIdentifier(parameter.GetName().Text));
                    finalTrans.data.LvalueTypes[lvalue] = parameter.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = parameter;


                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(lvalue, finalTrans.data));
                        finalTrans.data.ExpTypes[lvalueExp] = finalTrans.data.LvalueTypes[lvalue];
                        assExp.SetExp(lvalueExp);
                        afterBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assExp));
                    }
                }
                Parameters.Add(formal, lvalue);
            }

            AABlock innerBlock = (AABlock)decl.GetBlock().Clone();

            exp = new ABooleanConstExp(new ATrueBool());
            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            ABlockStm innerBlockStm = new ABlockStm(new TLBrace("{"), innerBlock);

            bool needWhile = CheckIfWhilesIsNeeded.IsWhileNeeded(decl.GetBlock());

            if (needWhile)
            {
                stm = new AWhileStm(new TLParen("("), exp, innerBlockStm);
            }
            else
            {
                stm = innerBlockStm;
            }
            outerBlock.GetStatements().Add(stm);

            outerBlock.GetStatements().Add(new ABlockStm(new TLBrace("{"), afterBlock));

            //Clone method contents to inner block.
            CloneMethod cloneFixer = new CloneMethod(finalTrans, Parameters, ParameterExps, innerBlockStm);

            decl.GetBlock().Apply(cloneFixer);
            foreach (KeyValuePair <PLvalue, PExp> pair in cloneFixer.ReplaceUsAfter)
            {
                PLvalue    lvalue       = pair.Key;
                PExp       replacement  = Util.MakeClone(pair.Value, finalTrans.data);
                ALvalueExp lvalueParent = (ALvalueExp)lvalue.Parent();
                lvalueParent.ReplaceBy(replacement);
            }
            innerBlockStm.Apply(new FixTypes(finalTrans.data));

            innerBlock.Apply(new FixReturnsAndWhiles(hasMethodReturnedVar, methodReturnerVar, finalTrans.data, needWhile));

            GetNonBlockStm stmFinder = new GetNonBlockStm(false);

            innerBlock.Apply(stmFinder);
            if (needWhile && (stmFinder.Stm == null || !(stmFinder.Stm is ABreakStm)))
            {
                innerBlock.GetStatements().Add(new ABreakStm(new TBreak("break")));
            }

            //Insert before current statement
            ABlockStm outerBlockStm = new ABlockStm(new TLBrace("{"), outerBlock);

            PStm pStm = Util.GetAncestor <PStm>(node);

            pBlock = (AABlock)pStm.Parent();

            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), outerBlockStm);

            if (node.Parent() == pStm && pStm is AExpStm)
            {
                pBlock.RemoveChild(pStm);
            }
            else
            {
                PLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text));
                finalTrans.data.LvalueTypes[lvalue] = methodReturnerVar.GetType();
                finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = methodReturnerVar;
                exp = new ALvalueExp(lvalue);
                finalTrans.data.ExpTypes[exp] = methodReturnerVar.GetType();

                node.ReplaceBy(exp);
            }
            return(new List <AABlock>()
            {
                outerBlock
            });
        }
 private static PStm GetNext(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor<AABlock>(stm);
         if (pBlock == null)
             return null;
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index < pBlock.GetStatements().Count - 1)
         {
             stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]);
             if (stm != null)
                 return stm;
             index++;
         }
         ASTNode node = pBlock;
         stm = null;
         while (true)
         {
             if (node == null)
                 return null;
             node = Util.GetNearestAncestor(node.Parent(), typeof(AABlock), typeof(PStm));
             if (node is PStm)
                 stm = (PStm)node;
             else if (stm == null)
                 continue;
             else
                 break;
         }
         //stm = Util.GetAncestor<PStm>(pBlock);
         if (stm == null)
             return null;
     }
 }
 private Node GetNode(PStm node)
 {
     if (StatementNodes.ContainsKey(node))
         return StatementNodes[node];
     Node graphNode = new Node(node);
     Nodes.AddLast(graphNode);
     StatementNodes[node] = graphNode;
     return graphNode;
 }
 public StmEnum(PStm stm)
 {
     this.stm = stm;
 }
 public bool MoveNext()
 {
     NextStm next = new NextStm(stm);
     stm.Apply(next);
     stm = next.nextStm;
     return stm != null;
 }
예제 #33
0
 public AForStm(
         TLParen _token_,
         PStm _init_,
         PExp _cond_,
         PStm _update_,
         PStm _body_
 )
 {
     SetToken(_token_);
     SetInit(_init_);
     SetCond(_cond_);
     SetUpdate(_update_);
     SetBody(_body_);
 }
예제 #34
0
        public void SetUpdate(PStm node)
        {
            if (_update_ != null)
            {
                _update_.Parent(null);
            }

            if (node != null)
            {
                if (node.Parent() != null)
                {
                    node.Parent().RemoveChild(node);
                }

                node.Parent(this);
            }

            _update_ = node;
        }
 public override void DefaultIn(Node node)
 {
     if (node is PStm)
     {
         if (node == oldStm)
             oldStm = null;
         else if (oldStm == null && nextStm == null)
             nextStm = (PStm)node;
     }
     base.DefaultIn(node);
 }
 public override void DefaultIn(Node node)
 {
     if ((!first || Stm == null) && node is PStm && !(node is ABlockStm))
         Stm = (PStm)node;
 }
 public NextStm(PStm oldStm)
 {
     this.oldStm = oldStm;
 }
예제 #38
0
        public override void OutATriggerDecl(ATriggerDecl node)
        {
            //If no actions, insert it
            if (node.GetActions() == null)
            {
                node.SetActions(new AABlock(new ArrayList(), new TRBrace("}", -1, -1)));
                node.SetActionsToken(new TActions("actions", -1, -1));
            }

            //If return in events is missing, insert it.
            if (node.GetEvents() != null)
            {
                AABlock block        = (AABlock)node.GetEvents();
                bool    insertReturn = false;
                while (true)
                {
                    if (block.GetStatements().Count == 0)
                    {
                        insertReturn = true;
                        break;
                    }
                    PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
                    if (lastStm is AVoidReturnStm)
                    {
                        break;
                    }
                    if (lastStm is ABlockStm)
                    {
                        block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock();
                        continue;
                    }
                    insertReturn = true;
                    break;
                }
                if (insertReturn)
                {
                    block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos)));
                }
            }
            //Also for actions
            //if (node.GetActions() != null)
            {
                AABlock block        = (AABlock)node.GetActions();
                bool    insertReturn = false;
                while (true)
                {
                    if (block.GetStatements().Count == 0)
                    {
                        insertReturn = true;
                        break;
                    }
                    PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
                    if (lastStm is AVoidReturnStm)
                    {
                        break;
                    }
                    if (lastStm is ABlockStm)
                    {
                        block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock();
                        continue;
                    }
                    insertReturn = true;
                    break;
                }
                if (insertReturn)
                {
                    block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos)));
                }
            }
        }
예제 #39
0
        public override void OutAIfExp(AIfExp node)
        {
            //Transform to

            /*
             * var expIfVar;
             * if (<cond>)
             * {
             *     expIfVar = <then>;
             * }
             * else
             * {
             *     expIfVar = <else>;
             * }
             * ... expIfVar ...
             */

            AALocalDecl expIfVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("expIfVar"), null);

            ALocalLvalue thenExpIfVarLink  = new ALocalLvalue(new TIdentifier("expIfVar"));
            ALocalLvalue elseExpIfVarLink  = new ALocalLvalue(new TIdentifier("expIfVar"));
            ALocalLvalue usageExpIfVarLink = new ALocalLvalue(new TIdentifier("expIfVar"));

            ALvalueExp usageExpIfVarLinkExp = new ALvalueExp(usageExpIfVarLink);

            AAssignmentExp thenAssignment = new AAssignmentExp(new TAssign("="), thenExpIfVarLink, node.GetThen());
            AAssignmentExp elseAssignment = new AAssignmentExp(new TAssign("="), elseExpIfVarLink, node.GetElse());

            AIfThenElseStm ifStm = new AIfThenElseStm(new TLParen("("), node.GetCond(),
                                                      new ABlockStm(new TLBrace("{"),
                                                                    new AABlock(
                                                                        new ArrayList()
            {
                new AExpStm(new TSemicolon(";"),
                            thenAssignment)
            },
                                                                        new TRBrace("}"))),
                                                      new ABlockStm(new TLBrace("{"),
                                                                    new AABlock(
                                                                        new ArrayList()
            {
                new AExpStm(new TSemicolon(";"),
                            elseAssignment)
            },
                                                                        new TRBrace("}"))));

            data.LocalLinks[thenExpIfVarLink]          =
                data.LocalLinks[elseExpIfVarLink]      =
                    data.LocalLinks[usageExpIfVarLink] = expIfVarDecl;

            data.LvalueTypes[thenExpIfVarLink]                =
                data.LvalueTypes[elseExpIfVarLink]            =
                    data.LvalueTypes[usageExpIfVarLink]       =
                        data.ExpTypes[usageExpIfVarLinkExp]   =
                            data.ExpTypes[thenAssignment]     =
                                data.ExpTypes[elseAssignment] = expIfVarDecl.GetType();



            PStm    pStm   = Util.GetAncestor <PStm>(node);
            AABlock pBlock = (AABlock)pStm.Parent();

            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), expIfVarDecl));
            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), ifStm);
            node.ReplaceBy(usageExpIfVarLinkExp);


            base.OutAIfExp(node);
        }
        private void TransformBreaks(PStm stm, SwitchCaseData switchCase, AALocalDecl continueDecl, AALocalDecl fallthroughDecl, ref int currI)
        {
            if (stm is ABreakStm)
            {
                AABlock pBlock = (AABlock) stm.Parent();
                if (!switchCase.IsLast && (switchCase.RequiresContinue || switchCase.ContainsFallthrough))
                {
                    //Add continue = false;
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(continueDecl.GetName().Text));
                    ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool());
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment));

                    data.LocalLinks[lvalue] = continueDecl;
                    data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = continueDecl.GetType();
                    currI++;
                }
                if (!switchCase.IsLast && switchCase.TargetForFallThrough)
                {
                    //Add fallthrough = false;
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(fallthroughDecl.GetName().Text));
                    ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool());
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment));

                    data.LocalLinks[lvalue] = fallthroughDecl;
                    data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = fallthroughDecl.GetType();
                    currI++;
                }
                if (!switchCase.RequiresWhile)
                {//Remove break
                    stm.Parent().RemoveChild(stm);
                    currI--;
                }
            }
            if (stm is ABlockStm)
                TransformBreaks((AABlock)((ABlockStm)stm).GetBlock(), switchCase, continueDecl, fallthroughDecl);
            if (stm is AIfThenStm)
                TransformBreaks(((AIfThenStm)stm).GetBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
            if (stm is AIfThenElseStm)
            {
                TransformBreaks(((AIfThenElseStm)stm).GetThenBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
                TransformBreaks(((AIfThenElseStm)stm).GetElseBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
            }
        }
 private bool CanFallthrough(PStm stm, out bool containsBreak, out bool requiresWhile)
 {
     containsBreak = stm is ABreakStm;
     requiresWhile = false;
     if (stm is ABreakStm || stm is AVoidReturnStm || stm is AValueReturnStm)
         return false;
     if (stm is ABlockStm)
         return CanFallthrough((AABlock)((ABlockStm)stm).GetBlock(), out containsBreak, out requiresWhile);
     if (stm is AIfThenStm)
     {
         CanFallthrough(((AIfThenStm) stm).GetBody(), out containsBreak, out requiresWhile);
         return true;
     }
     if (stm is AIfThenElseStm)
     {
         bool b1 = CanFallthrough(((AIfThenElseStm) stm).GetThenBody(), out containsBreak, out requiresWhile);
         bool hasBreak;
         bool reqWhile;
         bool b2 = CanFallthrough(((AIfThenElseStm)stm).GetElseBody(), out hasBreak, out reqWhile);
         containsBreak |= hasBreak;
         requiresWhile |= reqWhile;
         return b1 || b2;
     }
     return true;
 }
 public static bool HasMoreThanOneUses(PStm statement, AALocalDecl decl, SharedData data, out ALocalLvalue lvalue)
 {
     GetUses uses = new GetUses(decl, data);
     statement.Apply(uses);
     lvalue = uses.lvalue;
     return uses.count > 1;
 }
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (firstMethodCall)
                StatementRemover.Parse(node);
            firstMethodCall = false;

            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);

            setSpans = true;
            base.CaseAMethodDecl(node);
            setSpans = false;

            //Join locals of same type, unless they are both parameters or they are listed as intersecting
            for (int i = 0; i < definedLocals.Count; i++)
            {
                for (int j = i + 1; j < definedLocals.Count; j++)
                {
                    AALocalDecl decl1 = definedLocals[i];
                    AALocalDecl decl2 = definedLocals[j];

                    if (Util.TypeToString(decl1.GetType()) == Util.TypeToString(decl2.GetType()) &&
                        !intersectingLocals.Contains(new Pair(decl1, decl2)))
                    {
                        if (Util.GetAncestor<AABlock>(decl1) == null &&
                            Util.GetAncestor<AABlock>(decl2) == null)
                            continue;

                        AALocalDecl replacement = decl1;
                        AALocalDecl replaced = decl2;

                        //Dont replace the parameter
                        if (Util.GetAncestor<AABlock>(replaced) == null)
                        {
                            replacement = decl2;
                            replaced = decl1;
                            i--;
                        }
                        j--;

                        renamedLocals.Add(replaced, replacement);
                        definedLocals.Remove(replaced);
                        foreach (Pair pair in intersectingLocals)
                        {
                            if (pair.Local1 == replaced)
                                pair.Local1 = replacement;
                            if (pair.Local2 == replaced)
                                pair.Local2 = replacement;
                        }

                        //Assign defaults
                        if (replaced.GetInit() == null)
                        {
                            ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(replaced.GetName().Text));
                            finalTrans.data.LocalLinks[lvalue] = replaced;
                            finalTrans.data.LvalueTypes[lvalue] = replaced.GetType();
                            List<PStm> statements = AssignDefault(lvalue);
                            PStm pStm = Util.GetAncestor<PStm>(replaced);
                            AABlock pBlock = (AABlock) pStm.Parent();
                            foreach (PStm statement in statements)
                            {
                                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement);
                            }
                            pBlock.RemoveChild(pStm);
                        }
                        else
                        {
                            //Make an assignment expression instead
                            ALocalDeclStm declStm = (ALocalDeclStm)replaced.Parent();
                            ALocalLvalue lvalue = new ALocalLvalue((TIdentifier)replaced.GetName().Clone());
                            finalTrans.data.LvalueTypes[lvalue] = replaced.GetType();
                            AAssignmentExp exp = new AAssignmentExp(new TAssign("=", lvalue.GetName().Line, lvalue.GetName().Pos), lvalue, replaced.GetInit());
                            AExpStm expStm = new AExpStm(declStm.GetToken(), exp);
                            declStm.ReplaceBy(expStm);
                            finalTrans.data.LvalueTypes[lvalue] = replacement.GetType();
                            finalTrans.data.ExpTypes[exp] = replacement.GetType();
                            finalTrans.data.LocalLinks[lvalue] = replacement;
                        }
                    }
                }
            }

            //Unique names
            List<string> names = new List<string>();
            //Avoid clash with methods/fields/structs
            names.AddRange(finalTrans.data.Methods.Select(declItem => declItem.Decl.GetName().Text));
            names.AddRange(finalTrans.data.Fields.Select(declItem => declItem.Decl.GetName().Text));
            names.AddRange(finalTrans.data.Structs.Select(declItem => declItem.Decl.GetName().Text));
            foreach (AALocalDecl local in definedLocals)
            {
                string name = local.GetName().Text;
                int version = 1;
                while (names.Contains(name))
                {
                    version++;
                    name = local.GetName().Text + version;
                }
                local.GetName().Text = name;
                names.Add(name);
            }

            //Move defined locals to the start of the method
            foreach (AALocalDecl formal in node.GetFormals())
            {
                definedLocals.Remove(formal);
            }
            AABlock block = (AABlock)node.GetBlock();
            for (int i = 0; i < block.GetStatements().Count; i++)
            {
                ALocalDeclStm stm;
                if (block.GetStatements()[i] is ALocalDeclStm)
                {
                    stm = (ALocalDeclStm)block.GetStatements()[i];
                    definedLocals.Remove((AALocalDecl)stm.GetLocalDecl());
                    continue;
                }
                //Add the rest at i
                if (definedLocals.Count == 0)
                    break;
                AALocalDecl decl = definedLocals[0];
                definedLocals.RemoveAt(0);

                if (decl.GetInit() == null)
                {
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text));
                    finalTrans.data.LocalLinks[lvalue] = decl;
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    List<PStm> statements = AssignDefault(lvalue);
                    PStm pStm = Util.GetAncestor<PStm>(decl);
                    AABlock pBlock = (AABlock) pStm.Parent();
                    foreach (PStm statement in statements)
                    {
                        pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement);
                    }
                    pBlock.RemoveChild(pStm);
                }
                else
                {
                    //Make an assignment expression before moving
                    stm = (ALocalDeclStm)decl.Parent();
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text));
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    AAssignmentExp exp = new AAssignmentExp(new TAssign("="), lvalue, decl.GetInit());
                    AExpStm expStm = new AExpStm(new TSemicolon(";"), exp);
                    stm.ReplaceBy(expStm);
                    finalTrans.data.LvalueTypes[lvalue] = decl.GetType();
                    finalTrans.data.ExpTypes[exp] = decl.GetType();
                    finalTrans.data.LocalLinks[lvalue] = decl;
                }

                stm = new ALocalDeclStm(new TSemicolon(";"), decl);
                block.GetStatements().Insert(i, stm);
            }

            fixRefferences = true;
            base.CaseAMethodDecl(node);
            fixRefferences = false;

            //If we have an assignment to a local where the stored result is never used, remove the assignment

            //Since we changed some statements, rebuild stuff
            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);

            PStm[] stms = new PStm[before.Keys.Count];
            before.Keys.CopyTo(stms, 0);
            foreach (PStm stm in stms)
            {
                if (assigns[stm] != null && //Assignment exp
                    !after[stm].Contains(assigns[stm]) && //Assignment unused
                    Util.GetAncestor<AMethodDecl>(assigns[stm]) != null &&
                    !(stm is ALocalDeclStm))//It is to a local
                {
                    stm.Apply(new MoveMethodDeclsOut(finalTrans.data));
                    stm.Parent().RemoveChild(stm);
                }
            }

            //Remove foo = foo;
            RemoveStupidAssignments assignmentRemover = new RemoveStupidAssignments(finalTrans.data);
            node.Apply(assignmentRemover);

            //Remove unused local variables
            foreach (AALocalDecl local in definedLocals)
            {
                if (Util.GetAncestor<AAProgram>(local) != null && Util.GetAncestor<AABlock>(local) != null &&
                    !finalTrans.data.LocalLinks.Where(p => p.Value == local).Any(p => Util.GetAncestor<AAProgram>(p.Key) != null))
                    local.Parent().Parent().RemoveChild(local.Parent());
            }

            if (assignmentRemover.RemovedOne)
            {
                CaseAMethodDecl(node);
                return;
            }

            //If an assignment to a variable is completely local, and that assignment is only used once, put the assignment where it is used
            //Since we changed some statements, rebuild stuff
            before.Clear();
            after.Clear();
            uses.Clear();
            intersectingLocals.Clear();
            definedLocals.Clear();
            renamedLocals.Clear();
            assigns.Clear();
            changes = false;

            //Make uses
            setUses = true;
            base.CaseAMethodDecl(node);
            setUses = false;

            //Build a list of what's visible
            do
            {
                changes = false;
                base.CaseAMethodDecl(node);
            } while (changes);
            foreach (KeyValuePair<PStm, AALocalDecl> pair in assigns)
            {
                PStm assignStm = pair.Key;
                AALocalDecl assignVar = pair.Value;
                bool isLocal = Util.IsLocal(assignStm, finalTrans.data);
                bool containsInvokeInPrevStm = false;
                if (assignVar != null && after[assignStm].Contains(assignVar))
                {
                    bool dontMove = false;
                    //First, if there are any conditional parrent statement, where the variable is in live before the stm, then we can't move it
                    PStm condParent = (PStm) Util.GetNearestAncestor(assignStm, typeof (AIfThenStm), typeof (AIfThenElseStm),
                                                                     typeof (AWhileStm));
                    while (condParent != null)
                    {
                        if (before[condParent].Contains(assignVar))
                        {
                            dontMove = true;
                            break;
                        }
                        condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                     typeof(AWhileStm));
                    }

                    PStm useStm = null;
                    List<PStm> successors = GetSuccessor(assignStm);
                    bool containsConditionalAssignments = false;
                    while (successors.Count > 0)
                    {
                        if (successors.Count > 500)
                            useStm = useStm;
                        PStm successor = successors[0];
                        successors.RemoveAt(0);
                        if (uses[successor].Contains(assignVar))
                        {
                            if (useStm == null && !containsConditionalAssignments && !(successor is AWhileStm))
                                useStm = successor;
                            else
                            {
                                dontMove = true;
                                break;
                            }
                        }
                        if (after[successor].Contains(assignVar) && !(assigns.ContainsKey(successor) && assigns[successor] == assignVar))
                        {
                            List<PStm> newSuccessors = GetSuccessor(successor);
                            foreach (PStm stm in newSuccessors)
                            {
                                if (!successors.Contains(stm))
                                    successors.Add(stm);
                            }
                        }
                        if (assigns.ContainsKey(successor) && uses[assignStm].Contains(assigns[successor]))
                        {
                            dontMove = true;
                            break;
                        }

                        if (assigns.ContainsKey(successor) && assigns[successor] == assignVar)
                        {
                            condParent = (PStm)Util.GetNearestAncestor(successor, typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                       typeof(AWhileStm));
                            while (condParent != null)
                            {
                                if (!Util.IsAncestor(assignStm, condParent))
                                {
                                    containsConditionalAssignments = true;
                                    break;
                                }
                                condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm),
                                                                             typeof(AWhileStm));
                            }

                            //If we found a usage, and it is inside a while that the assignStm is not inside, but we are inside, don't move
                            if (useStm != null)
                            {
                                AWhileStm whileParant = Util.GetAncestor<AWhileStm>(successor);
                                while (whileParant != null)
                                {
                                    if (Util.IsAncestor(useStm, whileParant) && !Util.IsAncestor(assignStm, whileParant))
                                    {
                                        dontMove = true;
                                        break;
                                    }
                                    whileParant = Util.GetAncestor<AWhileStm>(whileParant.Parent());
                                }
                            }
                        }

                        FindInvoke finder  = new FindInvoke();
                        successor.Apply(finder);
                        if (finder.ContainsInvoke && useStm == null)
                            containsInvokeInPrevStm = true;
                    }

                    if (useStm != null && !dontMove)
                    {
                        //If assignStm is inside an if, and the use stm is not, and there is another assignment
                        //to the same variable in an else block, then don't join
                        AIfThenElseStm ifThenElse = Util.GetAncestor<AIfThenElseStm>(assignStm);
                        while (ifThenElse != null)
                        {
                            if (!Util.IsAncestor(useStm, ifThenElse))
                            {
                                ABlockStm otherBlock;
                                if (Util.IsAncestor(assignStm, ifThenElse.GetThenBody()))
                                    otherBlock = (ABlockStm) ifThenElse.GetElseBody();
                                else
                                    otherBlock = (ABlockStm)ifThenElse.GetThenBody();
                                StmEnum enumerator = new StmEnum(otherBlock);
                                while (enumerator.MoveNext())
                                {
                                    PStm stm = (PStm) enumerator.Current;
                                    if (assigns.ContainsKey(stm) && assigns[stm] == assignVar)
                                    {
                                        dontMove = true;
                                        break;
                                    }
                                }
                                if (dontMove)
                                    break;
                            }
                            ifThenElse = Util.GetAncestor<AIfThenElseStm>(ifThenElse.Parent());
                        }

                        //If the assignStm or useStm is inside a while, it could get complicated
                        //if (Util.HasAncestor<AWhileStm>(assignStm) || Util.HasAncestor<AWhileStm>(useStm))
                        //    dontMove = true;
                    }

                    if (useStm != null && dontMove == false && (isLocal || !containsInvokeInPrevStm))
                    {

                        //Ensure that it is not used twice in this stm
                        FindLvalue finder = new FindLvalue(assignVar, finalTrans.data);
                        useStm.Apply(finder);
                        if (!finder.IsUsedTwice && (isLocal || !finder.HasPrevInvoke))
                        {
                            PExp rightside;
                            if (assignStm is ALocalDeclStm)
                            {
                                rightside = ((AALocalDecl)((ALocalDeclStm)assignStm).GetLocalDecl()).GetInit();
                            }
                            else
                            {
                                rightside = ((AAssignmentExp)((AExpStm)assignStm).GetExp()).GetExp();
                                assignStm.Parent().RemoveChild(assignStm);
                            }
                            if (rightside != null)
                            {
                                finder.Lvalue.Parent().ReplaceBy(rightside);
                                CaseAMethodDecl(node);
                                return;
                            }
                        }
                    }
                }
            }

            if (StatementRemover.Parse(node))
            {
                CaseAMethodDecl(node);
                return;
            }
            firstMethodCall = true;
        }
예제 #44
0
        public override void CaseADelegateInvokeExp(ADelegateInvokeExp node)
        {
            //Build a list of the possible methods
            AASourceFile       currentFile    = Util.GetAncestor <AASourceFile>(node);
            List <AMethodDecl> methods        = new List <AMethodDecl>();
            ANamedType         type           = (ANamedType)finalTrans.data.ExpTypes[node.GetReceiver()];
            AMethodDecl        delegateMethod = finalTrans.data.DelegateTypeLinks[type];

            foreach (KeyValuePair <ADelegateExp, AMethodDecl> delegateCreationPair in finalTrans.data.DelegateCreationMethod)
            {
                if (TypeChecking.Assignable(delegateCreationPair.Key.GetType(), type))
                {
                    if (!methods.Contains(delegateCreationPair.Value))
                    {
                        methods.Add(delegateCreationPair.Value);
                    }
                }
            }
            MoveMethodDeclsOut mover;

            if (methods.Count == 0)
            {
                //Can only remove it if the return value is unused
                if (!(node.Parent() is AExpStm))
                {
                    finalTrans.errors.Add(new ErrorCollection.Error(node.GetToken(),
                                                                    currentFile,
                                                                    "No possible methods found for delegate invoke."));
                    throw new ParserException(node.GetToken(), "Delegates.OutADelegateInvokeExp");
                }

                mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data);
                foreach (Node arg in node.GetArgs())
                {
                    arg.Apply(mover);
                }
                node.Parent().Parent().RemoveChild(node.Parent());
                foreach (PStm stm in mover.NewStatements)
                {
                    stm.Apply(this);
                }
                return;
            }
            if (methods.Count == 1)
            {
                ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList());
                while (node.GetArgs().Count > 0)
                {
                    invoke.GetArgs().Add(node.GetArgs()[0]);
                }

                //If we have a struct method, add the pointer from the delegate
                if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(methods[0])))
                {
                    AStructDecl      targetStr        = finalTrans.data.StructMethods.First(str => str.Value.Contains(methods[0])).Key;
                    AMethodDecl      getPointerDecl   = GetPointerMethod(targetStr.GetDimention() != null);
                    ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()
                    {
                        node.GetReceiver()
                    });
                    invoke.GetArgs().Add(getPointerInvoke);

                    finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl;
                    finalTrans.data.ExpTypes[getPointerInvoke]          = getPointerDecl.GetReturnType();
                }

                finalTrans.data.SimpleMethodLinks[invoke] = methods[0];
                finalTrans.data.ExpTypes[invoke]          = methods[0].GetReturnType();
                node.ReplaceBy(invoke);
                return;
            }
            //Multiple methods. Make

            /*
             * <Methods moved out from reciever>
             * string delegate = GetMethodPart(<reciever>);
             * if (delegate == "...")
             * {
             *    Foo(...);
             * }
             * else if (delegate == "...")
             * {
             *    Bar(..., GetPointerPart(<reciever>);
             * }
             * else if(...)
             * ...
             * else
             * {
             *     UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("[<file>:<line>]: No methods matched delegate."));
             *     int i = 1/0;
             *     return;
             * }
             *
             */
            AABlock block = new AABlock(new ArrayList(), new TRBrace("}"));

            mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data);
            node.GetReceiver().Apply(mover);
            AMethodDecl      methodPartMethod = GetMethodMethod();
            ASimpleInvokeExp methodPartInvoke = new ASimpleInvokeExp(new TIdentifier("GetMethodPart"),
                                                                     new ArrayList()
            {
                Util.MakeClone(node.GetReceiver(),
                               finalTrans.data)
            });

            finalTrans.data.SimpleMethodLinks[methodPartInvoke] = methodPartMethod;
            finalTrans.data.ExpTypes[methodPartInvoke]          = methodPartMethod.GetReturnType();
            AALocalDecl methodPartDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                         new ANamedType(new TIdentifier("string"), null),
                                                         new TIdentifier("methodPart"), methodPartInvoke);

            block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), methodPartDecl));
            //If the invoke's return value is used, get the lvalue
            PLvalue leftSide;

            if (node.Parent() is AALocalDecl)
            {
                leftSide = new ALocalLvalue(new TIdentifier("renameMe"));
                finalTrans.data.LocalLinks[(ALocalLvalue)leftSide] = (AALocalDecl)node.Parent();
                finalTrans.data.LvalueTypes[leftSide] = new ANamedType(new TIdentifier("string"), null);
                PStm    pStm   = Util.GetAncestor <PStm>(node);
                AABlock pBlock = (AABlock)pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ABlockStm(new TLBrace("{"), block));
                node.Parent().RemoveChild(node);
            }
            else if (node.Parent() is AAssignmentExp)
            {
                AAssignmentExp assignExp = (AAssignmentExp)node.Parent();
                leftSide = assignExp.GetLvalue();
                leftSide.Apply(mover);

                PStm pStm = Util.GetAncestor <PStm>(node);
                pStm.ReplaceBy(new ABlockStm(new TLBrace("{"), block));
            }
            else if (node.Parent() is AExpStm)
            {
                //No assignments needed
                leftSide = null;
                node.Parent().ReplaceBy(new ABlockStm(new TLBrace("{"), block));
            }
            else
            {
                //Create a new local
                AALocalDecl leftSideDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                           Util.MakeClone(delegateMethod.GetReturnType(),
                                                                          finalTrans.data),
                                                           new TIdentifier("delegateVar"), null);
                ALocalLvalue leftSideLink    = new ALocalLvalue(new TIdentifier("delegateVar"));
                ALvalueExp   leftSideLinkExp = new ALvalueExp(leftSideLink);


                PStm    pStm   = Util.GetAncestor <PStm>(node);
                AABlock pBlock = (AABlock)pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ABlockStm(new TLBrace("{"), block));

                node.ReplaceBy(leftSideLinkExp);

                finalTrans.data.LocalLinks[leftSideLink]      = leftSideDecl;
                finalTrans.data.LvalueTypes[leftSideLink]     =
                    finalTrans.data.ExpTypes[leftSideLinkExp] = leftSideDecl.GetType();

                leftSide = leftSideLink;
                block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), leftSideDecl));
            }

            ABlockStm elseBranch;

            //Make final else branch

            /* {
             *     UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("<file>[<line>, <pos>]: No methods matched delegate."));
             *     IntToString(1/0);
             *     return;
             * }
             */
            {
                AABlock          innerBlock         = new AABlock(new ArrayList(), new TRBrace("}"));
                ASimpleInvokeExp playerGroupInvoke  = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList());
                AFieldLvalue     messageAreaLink    = new AFieldLvalue(new TIdentifier("c_messageAreaDebug"));
                ALvalueExp       messageAreaLinkExp = new ALvalueExp(messageAreaLink);
                AStringConstExp  stringConst        =
                    new AStringConstExp(
                        new TStringLiteral("\"" + currentFile.GetName().Text.Replace('\\', '/') + "[" +
                                           node.GetToken().Line + ", " + node.GetToken().Pos +
                                           "]: Got a null delegate.\""));
                ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"),
                                                                           new ArrayList()
                {
                    stringConst
                });
                ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp(new TIdentifier("UIDisplayMessage"),
                                                                             new ArrayList()
                {
                    playerGroupInvoke,
                    messageAreaLinkExp,
                    stringToTextInvoke
                });

                AIntConstExp     intConst1         = new AIntConstExp(new TIntegerLiteral("1"));
                AIntConstExp     intConst2         = new AIntConstExp(new TIntegerLiteral("0"));
                ABinopExp        binop             = new ABinopExp(intConst1, new ADivideBinop(new TDiv("/")), intConst2);
                ASimpleInvokeExp intToStringInvoke = new ASimpleInvokeExp(new TIdentifier("IntToString"),
                                                                          new ArrayList()
                {
                    binop
                });

                innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke));
                innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), intToStringInvoke));
                //innerBlock.GetStatements().Add(new AVoidReturnStm(new TReturn("return")));

                elseBranch = new ABlockStm(new TLBrace("{"), innerBlock);


                finalTrans.data.SimpleMethodLinks[playerGroupInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == playerGroupInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[stringToTextInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == stringToTextInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[displayMessageInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == displayMessageInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[intToStringInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == intToStringInvoke.GetName().Text);
                finalTrans.data.FieldLinks[messageAreaLink] =
                    finalTrans.data.Libraries.Fields.First(m => m.GetName().Text == messageAreaLink.GetName().Text);

                finalTrans.data.ExpTypes[playerGroupInvoke] =
                    finalTrans.data.SimpleMethodLinks[playerGroupInvoke].GetReturnType();
                finalTrans.data.LvalueTypes[messageAreaLink]     =
                    finalTrans.data.ExpTypes[messageAreaLinkExp] =
                        finalTrans.data.FieldLinks[messageAreaLink].GetType();
                finalTrans.data.ExpTypes[stringToTextInvoke] =
                    finalTrans.data.SimpleMethodLinks[stringToTextInvoke].GetReturnType();
                finalTrans.data.ExpTypes[stringConst]           =
                    finalTrans.data.ExpTypes[intToStringInvoke] = new ANamedType(new TIdentifier("string"), null);
                finalTrans.data.ExpTypes[displayMessageInvoke]  = new AVoidType();

                finalTrans.data.ExpTypes[intConst1]     =
                    finalTrans.data.ExpTypes[intConst2] =
                        finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("int"), null);
            }

            foreach (AMethodDecl method in methods)
            {
                /*  * if (delegate == "...")
                 * {
                 *    Foo(...);
                 * }
                 * else if (delegate == "...")
                 * {
                 *    Bar(..., GetPointerPart(<reciever>);
                 * }
                 * else if(...)
                 * ...
                 */
                AABlock          innerBlock = new AABlock(new ArrayList(), new TRBrace("}"));
                ASimpleInvokeExp invoke     = new ASimpleInvokeExp(new TIdentifier(method.GetName().Text), new ArrayList());
                for (int i = 0; i < node.GetArgs().Count; i++)
                {
                    PExp arg = (PExp)node.GetArgs()[i];
                    invoke.GetArgs().Add(Util.MakeClone(arg, finalTrans.data));
                }
                //If we have a struct method, add the pointer from the delegate
                if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(method)))
                {
                    AStructDecl      targetStr        = finalTrans.data.StructMethods.First(str => str.Value.Contains(method)).Key;
                    AMethodDecl      getPointerDecl   = GetPointerMethod(targetStr.GetDimention() != null);
                    ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()
                    {
                        Util.MakeClone(node.GetReceiver(), data)
                    });
                    invoke.GetArgs().Add(getPointerInvoke);

                    finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl;
                    finalTrans.data.ExpTypes[getPointerInvoke]          = getPointerDecl.GetReturnType();
                }

                finalTrans.data.SimpleMethodLinks[invoke] = method;
                finalTrans.data.ExpTypes[invoke]          = method.GetReturnType();

                if (leftSide == null)
                {
                    innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke));
                }
                else
                {
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), Util.MakeClone(leftSide, finalTrans.data), invoke);
                    finalTrans.data.ExpTypes[assignment] = finalTrans.data.ExpTypes[invoke];
                    innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));
                }
                ALocalLvalue    methodPartLink    = new ALocalLvalue(new TIdentifier("methodPart"));
                ALvalueExp      methodPartLinkExp = new ALvalueExp(methodPartLink);
                AStringConstExp stringConst       = new AStringConstExp(new TStringLiteral("\"" + GetName(method) + "\""));
                finalTrans.data.LocalLinks[methodPartLink]      = methodPartDecl;
                finalTrans.data.LvalueTypes[methodPartLink]     =
                    finalTrans.data.ExpTypes[methodPartLinkExp] =
                        finalTrans.data.ExpTypes[stringConst]   = new ANamedType(new TIdentifier("string"), null);


                ABinopExp binop = new ABinopExp(methodPartLinkExp, new AEqBinop(new TEq("==")), stringConst);
                finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("bool"), null);

                AIfThenElseStm ifThenElse = new AIfThenElseStm(new TLParen("("), binop, new ABlockStm(new TLBrace("{"), innerBlock), elseBranch);

                elseBranch = new ABlockStm(new TLBrace("{"), new AABlock(new ArrayList()
                {
                    ifThenElse
                }, new TRBrace("}")));
            }

            block.GetStatements().Add(elseBranch);
        }
예제 #45
0
 public AIfThenElseStm(
         TLParen _token_,
         PExp _condition_,
         PStm _then_body_,
         PStm _else_body_
 )
 {
     SetToken(_token_);
     SetCondition(_condition_);
     SetThenBody(_then_body_);
     SetElseBody(_else_body_);
 }
예제 #46
0
        public void SetInit(PStm node)
        {
            if (_init_ != null)
            {
                _init_.Parent(null);
            }

            if (node != null)
            {
                if (node.Parent() != null)
                {
                    node.Parent().RemoveChild(node);
                }

                node.Parent(this);
            }

            _init_ = node;
        }
예제 #47
0
        public void SetBody(PStm node)
        {
            if (_body_ != null)
            {
                _body_.Parent(null);
            }

            if (node != null)
            {
                if (node.Parent() != null)
                {
                    node.Parent().RemoveChild(node);
                }

                node.Parent(this);
            }

            _body_ = node;
        }
예제 #48
0
 internal override void RemoveChild(Node child)
 {
     if (_token_ == child)
     {
         _token_ = null;
         return;
     }
     if (_init_ == child)
     {
         _init_ = null;
         return;
     }
     if (_cond_ == child)
     {
         _cond_ = null;
         return;
     }
     if (_update_ == child)
     {
         _update_ = null;
         return;
     }
     if (_body_ == child)
     {
         _body_ = null;
         return;
     }
 }
 private static PStm GetNext(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor<AABlock>(stm);
         if (pBlock == null)
             return null;
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index < pBlock.GetStatements().Count - 1)
         {
             stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]);
             if (stm != null)
                 return stm;
             index++;
         }
         stm = Util.GetAncestor<PStm>(pBlock);
         if (stm == null)
             return null;
     }
 }
예제 #50
0
 public AIfThenStm(
         TLParen _token_,
         PExp _condition_,
         PStm _body_
 )
 {
     SetToken(_token_);
     SetCondition(_condition_);
     SetBody(_body_);
 }
 public Node(PStm statement)
 {
     Statement = statement;
 }
예제 #52
0
 internal override void RemoveChild(Node child)
 {
     if (_token_ == child)
     {
         _token_ = null;
         return;
     }
     if (_condition_ == child)
     {
         _condition_ = null;
         return;
     }
     if (_body_ == child)
     {
         _body_ = null;
         return;
     }
 }
 private static List<PStm> GetLast(PStm stm)
 {
     List<PStm> returner = new List<PStm>();
     if (stm is ABlockStm)
     {
         AABlock block = (AABlock) ((ABlockStm) stm).GetBlock();
         stm = null;
         for (int i = block.GetStatements().Count - 1; i >= 0; i--)
         {
             returner.AddRange(GetLast((PStm) block.GetStatements()[i]));
             if (returner.Count > 0)
                 return returner;
         }
     }
     else if (stm is AIfThenElseStm)
     {
         List<PStm> stms = new List<PStm>();
         stms.AddRange(GetLast(((AIfThenElseStm)stm).GetThenBody()));
         bool zero = stms.Count == 0;
         returner.AddRange(stms);
         stms.Clear();
         stms.AddRange(GetLast(((AIfThenElseStm)stm).GetElseBody()));
         zero |= stms.Count == 0;
         returner.AddRange(stms);
         if (zero)
             returner.Add(stm);
     }
     else
         returner.Add(stm);
     return returner;
 }
 private static PStm GetLast(PStm stm)
 {
     if (stm is ABlockStm)
     {
         AABlock block = (AABlock)((ABlockStm)stm).GetBlock();
         stm = null;
         for (int i = block.GetStatements().Count - 1; i >= 0; i--)
         {
             stm = GetLast((PStm)block.GetStatements()[i]);
             if (stm != null)
                 return stm;
         }
     }
     return stm;
 }
        //if ur an if you got 2
        //if ur a while you got 2
        //if ur not an if else, and your the last element of a block, look up untill you encounter
        //  another block, keep searching in that
        //  a while, pick that
        //  a method decl, no successor
        private List<PStm> GetSuccessor(PStm stm)
        {
            List<PStm> list = new List<PStm>();
            AABlock block;
            ABlockStm blockStm;
            if (stm is AIfThenElseStm)
            {
                AIfThenElseStm aStm = (AIfThenElseStm)stm;
                bool fallthrough = false;
                //Then
                blockStm = (ABlockStm)aStm.GetThenBody();
                block = (AABlock)blockStm.GetBlock();
                GetNonBlockStm stmFinder = new GetNonBlockStm(true);
                block.Apply(stmFinder);
                if (stmFinder.Stm != null)
                    list.Add(stmFinder.Stm);
                else
                    fallthrough = true;
                //Else
                blockStm = (ABlockStm)aStm.GetElseBody();
                block = (AABlock)blockStm.GetBlock();
                stmFinder = new GetNonBlockStm(true);
                block.Apply(stmFinder);
                if (stmFinder.Stm != null)
                    list.Add(stmFinder.Stm);
                else
                    fallthrough = true;
                if (!fallthrough)
                    return list;
            }
            if (stm is AIfThenStm)
            {
                AIfThenStm aStm = (AIfThenStm)stm;
                //Then
                blockStm = (ABlockStm)aStm.GetBody();
                block = (AABlock)blockStm.GetBlock();
                GetNonBlockStm stmFinder = new GetNonBlockStm(true);
                block.Apply(stmFinder);
                if (stmFinder.Stm != null)
                {
                    list.Add(stmFinder.Stm);
                }
            }
            if (stm is AWhileStm)
            {
                AWhileStm aStm = (AWhileStm)stm;
                //Then
                blockStm = (ABlockStm)aStm.GetBody();
                block = (AABlock)blockStm.GetBlock();
                GetNonBlockStm stmFinder = new GetNonBlockStm(true);
                block.Apply(stmFinder);
                if (stmFinder.Stm != null)
                {
                    list.Add(stmFinder.Stm);
                }
            }
            if (stm is ABreakStm)
            {
                AWhileStm whileStm = Util.GetAncestor<AWhileStm>(stm);

                list = GetSuccessor(whileStm);
                list.RemoveAt(0);
                return list;
            }
            if (stm is AContinueStm)
            {
                AWhileStm whileStm = Util.GetAncestor<AWhileStm>(stm);
                list.Add(whileStm);
                return list;
            }

            //Get the next statement in block
            block = (AABlock)stm.Parent();
            int index = block.GetStatements().IndexOf(stm);
            if (index == block.GetStatements().Count - 1)
                list.AddRange(GetSuccessor(block));
            else
            {
                stm = (PStm)block.GetStatements()[index + 1];
                while (stm is ABlockStm)
                {
                    blockStm = (ABlockStm)stm;
                    block = (AABlock)blockStm.GetBlock();

                    if (block.GetStatements().Count == 0)
                    {
                        list.AddRange(GetSuccessor(block));
                        return list;
                    }
                    stm = (PStm)block.GetStatements()[0];
                }
                list.Add(stm);
            }
            return list;
        }
 private static PStm GetPrevious(PStm stm)
 {
     while (true)
     {
         AABlock pBlock = Util.GetAncestor<AABlock>(stm);
         if (pBlock == null)
             return null;
         int index = pBlock.GetStatements().IndexOf(stm);
         while (index > 0)
         {
             stm = GetLast((PStm)pBlock.GetStatements()[index - 1]);
             if (stm != null)
                 return stm;
             index--;
         }
         stm = Util.GetAncestor<PStm>(pBlock);
         if (stm == null)
             return null;
     }
 }
        private PStm RemoveVariableStatement(PStm stm, PExp rightSide, int line, int pos)
        {
            if (rightSide != null)
            {
                List<PStm> statements = MakeStatements(rightSide, line, pos);

                if (statements.Count == 0)
                    stm.Parent().RemoveChild(stm);
                else
                {
                    PStm statement;
                    if (statements.Count == 1)
                        statement = statements[0];
                    else
                        statement = new ABlockStm(new TLBrace("{"), new AABlock(statements, new TRBrace("}")));
                    stm.ReplaceBy(statement);
                    return statement;
                }
            }
            else
                stm.Parent().RemoveChild(stm);
            return null;
        }