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; }
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); }
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); }
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 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); }
private static PStm GetPrevious(PStm stm) { while (true) { AABlock pBlock = Util.GetAncestor <AABlock>(stm); if (pBlock == null) { return(null); } int index = pBlock.GetStatements().IndexOf(stm); while (index > 0) { stm = GetLast((PStm)pBlock.GetStatements()[index - 1]); if (stm != null) { return(stm); } index--; } stm = Util.GetAncestor <PStm>(pBlock); if (stm == null) { return(null); } } }
private 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); }
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); }
//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); }
//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]); } } }
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); } } }
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); }
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); }
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; }
public override void CaseAABlock(AABlock node) { Write("{\n"); foreach (PStm stm in node.GetStatements()) { stm.Apply(this); } Write("}\n"); }
//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); }
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(); }
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); }
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); }
private static List <PStm> GetLast(PStm stm) { List <PStm> returner = new List <PStm>(); if (stm is ABlockStm) { AABlock block = (AABlock)((ABlockStm)stm).GetBlock(); stm = null; for (int i = block.GetStatements().Count - 1; i >= 0; i--) { returner.AddRange(GetLast((PStm)block.GetStatements()[i])); if (returner.Count > 0) { return(returner); } } } else if (stm is AIfThenElseStm) { List <PStm> stms = new List <PStm>(); stms.AddRange(GetLast(((AIfThenElseStm)stm).GetThenBody())); bool zero = stms.Count == 0; returner.AddRange(stms); stms.Clear(); stms.AddRange(GetLast(((AIfThenElseStm)stm).GetElseBody())); zero |= stms.Count == 0; returner.AddRange(stms); if (zero) { returner.Add(stm); } } else { returner.Add(stm); } return(returner); }
private 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); } } }
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); } }
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()); }
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)); } }
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)); } }
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)); } } }
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); }
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 }); }