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);
        }
 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;
 }
        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 Node Insert(Node node, AExpStm newStm)
 {
     //Node must be a node for an AExpStm
     Node newNode = new Node(newStm);
     foreach (Node successor in node.Successors)
     {
         newNode.AddSucc(successor);
     }
     foreach (Node successor in newNode.Successors)
     {
         node.RemoveSucc(successor);
     }
     node.AddSucc(newNode);
     Nodes.Insert(Nodes.IndexOf(node) + 1, newNode);
     return newNode;
 }
 public virtual void OutAExpStm(AExpStm node)
 {
     DefaultOut(node);
 }
 public virtual void InAExpStm(AExpStm node)
 {
     DefaultIn(node);
 }
 public virtual void CaseAExpStm(AExpStm node)
 {
     DefaultCase(node);
 }
 public override void CaseAExpStm(AExpStm node)
 {
     InAExpStm(node);
     if (node.GetExp() != null)
     {
         node.GetExp().Apply(this);
     }
     if (node.GetToken() != null)
     {
         node.GetToken().Apply(this);
     }
     OutAExpStm(node);
 }
 public override void CaseAExpStm(AExpStm node)
 {
 }
            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));
            }
 public override void CaseAExpStm(AExpStm node)
 {
     node.GetExp().Apply(this);
     Write(";\n");
 }
示例#12
0
 ArrayList New311()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TSemicolon tsemicolonNode2 = (TSemicolon)nodeArrayList1[0];
     PExp pexpNode3 = (PExp)nodeArrayList2[0];
     AExpStm pstmNode1 = new AExpStm (
       tsemicolonNode2,
       pexpNode3
     );
     nodeList.Add(pstmNode1);
     return nodeList;
 }
        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;
        }
            public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
            {
                PStm pStm = Util.GetAncestor<PStm>(node);
                AExpStm expStm = new AExpStm(new TSemicolon(";"), node);
                AABlock pBlock = (AABlock) pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), expStm);

                /*PExp expNode = (PExp)node;
                PType type = data.ExpTypes[expNode];
                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("bulkCopyVar", 0, 0), expNode);
                block.GetStatements().Insert(block.GetStatements().IndexOf(stm), new ALocalDeclStm(new TSemicolon(";"), localDecl));

                data.LvalueTypes[local] = type;
                data.ExpTypes[exp] = type;
                data.LocalLinks[local] = localDecl;
                //localDecl.Apply(this);
                exp.Apply(this);
                return;*/
            }
 public override void CaseAExpStm(AExpStm node)
 {
     //Create node
     GetNode(node);
 }
        public override void OutAIncDecExp(AIncDecExp node)
        {
            PIncDecOp op = node.GetIncDecOp();
            if (!Util.HasAncestor<AABlock>(node))
            {
                Token token = null;
                if (op is APostDecIncDecOp)
                    token = ((APostDecIncDecOp) op).GetToken();
                else if (op is APreDecIncDecOp)
                    token = ((APreDecIncDecOp)op).GetToken();
                else if (op is APostIncIncDecOp)
                    token = ((APostIncIncDecOp)op).GetToken();
                else if (op is APreIncIncDecOp)
                    token = ((APreIncIncDecOp)op).GetToken();
                errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText114")));
                throw new ParserException(token, "TypeChecking.OutAIncDecExp");
            }

            bool plus = op is APreIncIncDecOp || op is APostIncIncDecOp;
            if (op is APreIncIncDecOp || op is APreDecIncDecOp || node.Parent() is AExpStm)
            {//++i, --i, i++; or i--;
                //Replace with assignment
                //<exp>++ => <exp> + 1
                //(... foo = <exp> ...)++ => (... foo = <exp> ...) = (... foo ...) + 1
                //(... foo++ ...)++ => (... foo++ ...) = (... foo ...) + 1

                PLvalue clone = Util.MakeClone(node.GetLvalue(), data);
                clone.Apply(new AssignFixup(data));
                PBinop binop;
                if (plus)
                {
                    binop = new APlusBinop(new TPlus("+"));
                }
                else
                {
                    binop = new AMinusBinop(new TMinus("-"));
                }
                ABinopExp addExp = new ABinopExp(new ALvalueExp(clone), binop, new AIntConstExp(new TIntegerLiteral("1")));
                AAssignmentExp exp = new AAssignmentExp(new TAssign("="), node.GetLvalue(), addExp);
                node.ReplaceBy(exp);
                exp.Apply(this);
                return;
            }
            {//i++ or i--
                //Make a new local so
                //int newLocal = i;
                //++i;
                //...newLocal...;
                PLvalue lvalueClone = Util.MakeClone(node.GetLvalue(), data);
                PExp exp = new ALvalueExp(Util.MakeClone(node.GetLvalue(), data));
                data.ExpTypes[exp] = data.LvalueTypes[node.GetLvalue()];
                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.LvalueTypes[node.GetLvalue()], data), new TIdentifier("incDecVar"), exp);
                ALocalDeclStm localDeclStm = new ALocalDeclStm(new TSemicolon(";"), localDecl);

                node.SetIncDecOp(plus
                                     ? (PIncDecOp) new APreIncIncDecOp(new TPlusPlus("++"))
                                     : new APreDecIncDecOp(new TMinusMinus("--")));

                ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(localDecl.GetName().Text));
                exp = new ALvalueExp(lvalue);
                data.ExpTypes[exp] = data.LvalueTypes[lvalue] = data.LvalueTypes[node.GetLvalue()];
                data.LocalLinks[lvalue] = localDecl;

                PStm pStm = Util.GetAncestor<PStm>(node);
                node.ReplaceBy(exp);
                PStm nodeStm = new AExpStm(new TSemicolon(";"), node);

                AABlock block = (AABlock) pStm.Parent();

                block.GetStatements().Insert(block.GetStatements().IndexOf(pStm), localDeclStm);
                block.GetStatements().Insert(block.GetStatements().IndexOf(pStm), nodeStm);
                localDeclStm.Apply(this);
                nodeStm.Apply(this);
                exp.Apply(this);

                if (pStm is AWhileStm && Util.IsAncestor(exp, ((AWhileStm)pStm).GetCondition()))
                {
                    AWhileStm aStm = (AWhileStm)pStm;
                    //Insert
                    // newLocal = i
                    // ++i
                    //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)
                    {
                        PLvalue nodeLvalue1 = Util.MakeClone(lvalueClone, data);
                        PExp nodeLvalue1Exp = new ALvalueExp(nodeLvalue1);
                        PLvalue nodeLvalue2 = Util.MakeClone(lvalueClone, data);
                        ALocalLvalue newLocalLvalue = new ALocalLvalue(new TIdentifier("newLocal"));
                        data.LocalLinks[newLocalLvalue] = localDecl;
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), newLocalLvalue, nodeLvalue1Exp);
                        PStm assignmentStm = new AExpStm(new TSemicolon(";"), assignment);

                        AIncDecExp newIncDecExp = new AIncDecExp(nodeLvalue2, plus
                                                                                  ? (PIncDecOp)
                                                                                    new APreIncIncDecOp(
                                                                                        new TPlusPlus("++"))
                                                                                  : new APreDecIncDecOp(
                                                                                        new TMinusMinus("--")));
                        PStm newIncDecExpStm = new AExpStm(new TSemicolon(";"), newIncDecExp);

                        block = (AABlock)continueStm.Parent();
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), assignmentStm);
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), newIncDecExpStm);

                        assignment.Apply(this);
                        newIncDecExp.Apply(this);
                    }
                }
                return;
            }
        }
            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);
            }