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;
        }
Ejemplo n.º 2
0
            public override void CaseAValueReturnStm(AValueReturnStm node)
            {
                /*
                 * return <exp>;
                 * ->
                 * methodReturnerVar = <exp>;
                 * hasMethodReturnedVar = true;
                 * break;
                 */
                ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text));

                data.LvalueTypes[lvalue] = methodReturnerVar.GetType();
                data.LocalLinks[lvalue]  = methodReturnerVar;
                AAssignmentExp exp = new AAssignmentExp(new TAssign("="), lvalue, node.GetExp());

                data.ExpTypes[exp] = methodReturnerVar.GetType();
                PStm    stm   = new AExpStm(new TSemicolon(";"), exp);
                AABlock block = new AABlock();

                block.GetStatements().Add(stm);

                block.GetStatements().Add(new AVoidReturnStm(node.GetToken()));

                node.ReplaceBy(new ABlockStm(new TLBrace("{"), block));
                block.Apply(this);
            }
Ejemplo n.º 3
0
            public override void CaseAWhileStm(AWhileStm node)
            {
                /*
                 * while(...){...}
                 * ->
                 * while(...){...}
                 * if (hasMethodReturnedVar)
                 * {
                 *      break;
                 * }
                 */
                if (neededWhile)
                {
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(hasMethodReturnedVar.GetName().Text));
                    data.LvalueTypes[lvalue] = hasMethodReturnedVar.GetType();
                    data.LocalLinks[lvalue]  = hasMethodReturnedVar;
                    ALvalueExp exp = new ALvalueExp(lvalue);
                    data.ExpTypes[exp] = hasMethodReturnedVar.GetType();

                    AABlock ifBlock = new AABlock();
                    ifBlock.GetStatements().Add(new ABreakStm(new TBreak("break")));
                    ABlockStm ifBlockStm = new ABlockStm(new TLBrace("{"), ifBlock);

                    AIfThenStm ifStm = new AIfThenStm(new TLParen("("), exp, ifBlockStm);

                    AABlock pBlock = (AABlock)node.Parent();
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node) + 1, ifStm);
                }
                node.GetBody().Apply(this);
            }
Ejemplo n.º 4
0
            public override void CaseAVoidReturnStm(AVoidReturnStm node)
            {
                if (!neededWhile)
                {
                    node.Parent().RemoveChild(node);
                    return;
                }

                /*
                 * return;
                 * ->
                 * hasMethodReturnedVar = true;
                 * break;
                 */
                ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(hasMethodReturnedVar.GetName().Text));

                data.LvalueTypes[lvalue] = hasMethodReturnedVar.GetType();
                data.LocalLinks[lvalue]  = hasMethodReturnedVar;
                PExp exp = new ABooleanConstExp(new ATrueBool());

                data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
                exp = new AAssignmentExp(new TAssign("="), lvalue, exp);
                data.ExpTypes[exp] = hasMethodReturnedVar.GetType();
                PStm    stm   = new AExpStm(new TSemicolon(";"), exp);
                AABlock block = new AABlock();

                block.GetStatements().Add(stm);

                block.GetStatements().Add(new ABreakStm(new TBreak("break")));

                node.ReplaceBy(new ABlockStm(new TLBrace("{"), block));
            }
Ejemplo n.º 5
0
        public override void CaseALocalDeclStm(ALocalDeclStm node)
        {
            AMethodDecl pMethod = Util.GetAncestor <AMethodDecl>(node);
            AALocalDecl decl    = (AALocalDecl)node.GetLocalDecl();

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

            AABlock block = (AABlock)pMethod.GetBlock();

            block.GetStatements().Insert(0, node);
        }
Ejemplo n.º 6
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);
         }
     }
 }
Ejemplo n.º 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);
         }
     }
 }
        public static bool Parse(ControlFlowGraph cfg, SharedData data, out bool redoLivenessAnalysis)
        {
            bool changed = false;

            redoLivenessAnalysis = false;
            Dictionary <ControlFlowGraph.Node, List <ASimpleInvokeExp> > Modifications = new Dictionary <ControlFlowGraph.Node, List <ASimpleInvokeExp> >();

            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                if (node.Expression is AAssignmentExp)
                {
                    AAssignmentExp exp = (AAssignmentExp)node.Expression;
                    if (exp.GetLvalue() is ALocalLvalue)
                    {
                        AALocalDecl decl = data.LocalLinks[(ALocalLvalue)exp.GetLvalue()];
                        //If the variable is not live at any successors, remove this assignment
                        bool inUse = false;
                        foreach (ControlFlowGraph.Node successor in node.Successors)
                        {
                            if (successor.LiveVariables.Contains(decl))
                            {
                                inUse = true;
                                break;
                            }
                        }
                        if (!inUse)
                        {
                            //Move method invokes out
                            GetMethodInvokes getter = new GetMethodInvokes();
                            exp.GetExp().Apply(getter);
                            //Might also have to redo because we removed a reference to a variable in the right side
                            //if (getter.Invokes.Count > 0)
                            redoLivenessAnalysis = true;
                            Modifications[node]  = getter.Invokes;
                            changed = true;
                        }
                    }
                }
            }
            foreach (KeyValuePair <ControlFlowGraph.Node, List <ASimpleInvokeExp> > pair in Modifications)
            {
                ControlFlowGraph.Node node = pair.Key;
                foreach (ASimpleInvokeExp invoke in pair.Value)
                {
                    AExpStm stm    = new AExpStm(new TSemicolon(";"), invoke);
                    AABlock pBlock = (AABlock)node.Statement.Parent();
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node.Statement), stm);
                    cfg.Insert(node, stm);
                }
                cfg.Remove(node);
                node.Statement.Parent().RemoveChild(node.Statement);
            }
            return(changed);
        }
Ejemplo n.º 9
0
            public override void CaseAContinueStm(AContinueStm node)
            {
                AABlock          pBlock        = (AABlock)node.Parent();
                ALocalLvalue     replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar"));
                ASimpleInvokeExp clone         = (ASimpleInvokeExp)Util.MakeClone(this.node, data);
                AAssignmentExp   assignment    = new AAssignmentExp(new TAssign("="), replaceVarRef, clone);

                data.LocalLinks[replaceVarRef] = replaceVarDecl;
                data.ExpTypes[assignment]      = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), assignment));
                replacementExpressions.Add(clone);
            }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
 //Remove unnessery blocks
 public override void OutABlockStm(ABlockStm node)
 {
     if (node.Parent() is AABlock)
     {
         AABlock pBlock = (AABlock)node.Parent();
         AABlock cBlock = (AABlock)node.GetBlock();
         int     index  = pBlock.GetStatements().IndexOf(node);
         pBlock.RemoveChild(node);
         for (int i = cBlock.GetStatements().Count - 1; i >= 0; i--)
         {
             pBlock.GetStatements().Insert(index, cBlock.GetStatements()[i]);
         }
     }
 }
Ejemplo n.º 12
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);
         }
     }
 }
Ejemplo n.º 13
0
        public override void CaseAThisArrayPropertyDecl(AThisArrayPropertyDecl node)
        {
            APropertyDecl replacer = new APropertyDecl(node.GetVisibilityModifier(), null, node.GetType(),
                                                       new TIdentifier("array property", node.GetToken().Line, node.GetToken().Pos),
                                                       node.GetGetter(), node.GetSetter());
            List <AALocalDecl> locals = new List <AALocalDecl>();

            if (replacer.GetGetter() != null)
            {
                AABlock     block = (AABlock)replacer.GetGetter();
                AALocalDecl local = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    (PType)node.GetArgType().Clone(),
                                                    (TIdentifier)node.GetArgName().Clone(), null);
                block.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), local));
                locals.Add(local);
            }
            if (replacer.GetSetter() != null)
            {
                AABlock     block = (AABlock)replacer.GetSetter();
                AALocalDecl local = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    (PType)node.GetArgType().Clone(),
                                                    (TIdentifier)node.GetArgName().Clone(), null);

                block.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), local));
                locals.Add(local);
            }
            node.ReplaceBy(replacer);
            replacer.Apply(this);
        }
Ejemplo n.º 14
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);
 }
Ejemplo n.º 15
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;
            }
Ejemplo n.º 16
0
 public override void CaseAABlock(AABlock node)
 {
     Write("{\n");
     foreach (PStm stm in node.GetStatements())
     {
         stm.Apply(this);
     }
     Write("}\n");
 }
Ejemplo n.º 17
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);
        }
Ejemplo n.º 18
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);
        }
            public override void CaseAVoidReturnStm(AVoidReturnStm node)
            {
                AMethodDecl baseDeconstructor = data.DeconstructorMap[data.StructDeconstructor[baseStruct]];


                ALocalLvalue     structFormalRef    = new ALocalLvalue(new TIdentifier("currentStruct"));
                ALvalueExp       structFormalRefExp = new ALvalueExp(structFormalRef);
                ASimpleInvokeExp invoke             = new ASimpleInvokeExp(new TIdentifier("baseDeconstructor"),
                                                                           new ArrayList()
                {
                    structFormalRefExp
                });
                AABlock block = (AABlock)node.Parent();

                block.GetStatements().Insert(block.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), invoke));

                data.LocalLinks[structFormalRef]  = structFormal;
                data.SimpleMethodLinks[invoke]    = baseDeconstructor;
                data.LvalueTypes[structFormalRef] = data.ExpTypes[structFormalRefExp] = structFormal.GetType();
                data.ExpTypes[invoke]             = baseDeconstructor.GetReturnType();
            }
Ejemplo n.º 20
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);
 }
Ejemplo n.º 21
0
        public override void CaseAForStm(AForStm node)
        {
            //Replace with while
            node.GetBody().Apply(new ReworkForContinues());

            AABlock innerBlock = new AABlock();

            innerBlock.SetToken(new TRBrace("{", node.GetToken().Line, node.GetToken().Pos));
            innerBlock.GetStatements().Add(node.GetBody());
            innerBlock.GetStatements().Add(node.GetUpdate());
            ABlockStm innerBlockStm = new ABlockStm(new TLBrace(";"), innerBlock);
            AWhileStm whileStm      = new AWhileStm(node.GetToken(), node.GetCond(), innerBlockStm);
            AABlock   block         = new AABlock();

            block.SetToken(new TRBrace("{", whileStm.GetToken().Line, whileStm.GetToken().Pos));
            block.GetStatements().Add(node.GetInit());
            block.GetStatements().Add(whileStm);
            ABlockStm blockStm = new ABlockStm(null, block);

            node.ReplaceBy(blockStm);
            blockStm.Apply(this);
        }
Ejemplo n.º 22
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);
            }
Ejemplo n.º 23
0
        private void MakeAssignments(AABlock block, PType type, PLvalue leftSide, bool onEnhritedFields)
        {
            if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type))
            {
                AStructDecl str = data.StructTypeLinks[(ANamedType)type];
                foreach (AALocalDecl field in str.GetLocals().OfType <AALocalDecl>())
                {
                    if (!onEnhritedFields && data.EnheritanceLocalMap.ContainsKey(field))
                    {
                        continue;
                    }

                    ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(leftSide, data));
                    data.ExpTypes[lvalueExp] = data.LvalueTypes[leftSide];
                    AStructLvalue newLeftSide = new AStructLvalue(lvalueExp, new ADotDotType(new TDot(".")), new TIdentifier(field.GetName().Text));
                    data.StructFieldLinks[newLeftSide] = field;
                    data.LvalueTypes[newLeftSide]      = field.GetType();

                    if (field.GetInit() != null)
                    {
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), newLeftSide,
                                                                       Util.MakeClone(field.GetInit(), data));
                        data.ExpTypes[assignment] = data.LvalueTypes[newLeftSide];

                        block.GetStatements().Add(new AExpStm(new TSemicolon(";"),
                                                              assignment));
                    }
                    else
                    {
                        MakeAssignments(block, field.GetType(), newLeftSide, onEnhritedFields);
                    }
                }
            }
            else if (type is AArrayTempType)
            {
                AArrayTempType aType = (AArrayTempType)type;
                for (int i = 0; i < int.Parse(aType.GetIntDim().Text); i++)
                {
                    AIntConstExp index = new AIntConstExp(new TIntegerLiteral(i.ToString()));
                    data.ExpTypes[index] = new ANamedType(new TIdentifier("int"), null);

                    ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(leftSide, data));
                    data.ExpTypes[lvalueExp] = data.LvalueTypes[leftSide];
                    AArrayLvalue newLeftSide = new AArrayLvalue(new TLBracket("["), lvalueExp, index);
                    data.LvalueTypes[newLeftSide] = aType.GetType();

                    MakeAssignments(block, aType.GetType(), newLeftSide, onEnhritedFields);
                }
            }
        }
Ejemplo n.º 24
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);
            }
        }
Ejemplo n.º 25
0
            public override void CaseAContinueStm(AContinueStm node)
            {
                AForStm forStm = Util.GetAncestor <AForStm>(node);
                AABlock pBlock;

                if (!(node.Parent() is AABlock))
                {
                    pBlock = new AABlock(new ArrayList(), new TRBrace("}", node.GetToken().Line, node.GetToken().Pos));
                    ABlockStm blockStm = new ABlockStm(new TLBrace("{", node.GetToken().Line, node.GetToken().Pos), pBlock);
                    node.ReplaceBy(blockStm);
                    pBlock.GetStatements().Add(node);
                }
                pBlock = (AABlock)node.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node), forStm.GetUpdate().Clone());
            }
Ejemplo n.º 26
0
        public override void OutAALocalDecl(AALocalDecl node)
        {
            if (!Util.HasAncestor <AABlock>(node) && !Util.HasAncestor <AMethodDecl>(node))
            {
                //OutStructFieldDecl(node);
                return;
            }

            if (node.GetInit() != null)
            {
                return;
            }

            AABlock pBlock;
            int     insertIndex;
            PLvalue lvalue;

            if (Util.HasAncestor <AABlock>(node))
            {
                //A local variable
                pBlock      = Util.GetAncestor <AABlock>(node);
                insertIndex = pBlock.GetStatements().IndexOf(Util.GetAncestor <PStm>(node)) + 1;
                lvalue      = new ALocalLvalue(new TIdentifier(node.GetName().Text));
                data.LocalLinks[(ALocalLvalue)lvalue] = node;
                data.LvalueTypes[lvalue] = node.GetType();
            }
            else
            {
                //Parameter

                //Parameters will be set from the caller
                return;

                pBlock      = (AABlock)Util.GetAncestor <AMethodDecl>(node).GetBlock();
                insertIndex = 0;
                lvalue      = new ALocalLvalue(new TIdentifier(node.GetName().Text));
                data.LocalLinks[(ALocalLvalue)lvalue] = node;
                data.LvalueTypes[lvalue] = node.GetType();
            }
            AABlock block = new AABlock(new ArrayList(), new TRBrace("}"));

            MakeAssignments(block, node.GetType(), lvalue, true);

            if (block.GetStatements().Count != 0)
            {
                pBlock.GetStatements().Insert(insertIndex, new ABlockStm(new TLBrace("{"), block));
            }
        }
Ejemplo n.º 27
0
        public override void OutAFieldDecl(AFieldDecl node)
        {
            if (node.GetInit() != null)
            {
                return;
            }

            //Field - init in main entry
            AABlock      pBlock      = (AABlock)finalTrans.mainEntryFieldInitBlock.GetBlock();
            int          insertIndex = 0;
            AFieldLvalue lvalue      = new AFieldLvalue(new TIdentifier(node.GetName().Text));

            data.FieldLinks[lvalue]  = node;
            data.LvalueTypes[lvalue] = node.GetType();
            AABlock block = new AABlock(new ArrayList(), new TRBrace("}"));

            MakeAssignments(block, node.GetType(), lvalue, true);

            if (block.GetStatements().Count != 0)
            {
                pBlock.GetStatements().Insert(insertIndex, new ABlockStm(new TLBrace("{"), block));
            }
        }
Ejemplo n.º 28
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));
                    }
                }
            }
Ejemplo n.º 29
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);
        }
Ejemplo n.º 30
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
            });
        }