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); }
//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]); } } }
public virtual void OutABlockStm(ABlockStm node) { DefaultOut(node); }
public virtual void InABlockStm(ABlockStm node) { DefaultIn(node); }
public virtual void CaseABlockStm(ABlockStm node) { DefaultCase(node); }
public override void CaseABlockStm(ABlockStm node) { InABlockStm(node); if (node.GetBlock() != null) { node.GetBlock().Apply(this); } if (node.GetToken() != null) { node.GetToken().Apply(this); } OutABlockStm(node); }
public override void CaseASwitchStm(ASwitchStm node) { node.GetTest().Apply(this); AALocalDecl fallThroughDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier(MakeUniqueLocalName(node, "switchFallThrough")), new ABooleanConstExp(new AFalseBool())); AALocalDecl continueDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier(MakeUniqueLocalName(node, "switchContinue")), new ABooleanConstExp(new ATrueBool())); AALocalDecl testVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node.GetTest()], data), new TIdentifier(MakeUniqueLocalName(node, "switchTestVar")), node.GetTest()); AABlock bigBlock = new AABlock(); //AABlock previousBlock = bigBlock; if (node.GetCases().Count > 0) { List<SwitchCaseData> switchCaseDatas = new List<SwitchCaseData>(); //Join cases without a body for (int i = node.GetCases().Count - 1; i >= 0; i--) { ASwitchCaseStm caseStm = (ASwitchCaseStm) node.GetCases()[i]; SwitchCaseData caseData = new SwitchCaseData(); caseData.Block = (AABlock) caseStm.GetBlock(); if (caseStm.GetType() is ACaseSwitchCaseType) caseData.Tests.Add(((ACaseSwitchCaseType)caseStm.GetType()).GetExp()); else caseData.ContainsDefault = true; caseData.IsLast = switchCaseDatas.Count == 0; if (switchCaseDatas.Count == 0 || caseData.Block.GetStatements().Count > 0) { switchCaseDatas.Insert(0, caseData); continue; } switchCaseDatas[0].Tests.AddRange(caseData.Tests); } for (int i = switchCaseDatas.Count - 1; i >= 0; i--) { switchCaseDatas[i].ContainsFallthrough = CanFallthrough(switchCaseDatas[i].Block, out switchCaseDatas[i].HasBreaks, out switchCaseDatas[i].RequiresWhile); if (i == switchCaseDatas.Count - 1) continue; switchCaseDatas[i + 1].TargetForFallThrough = switchCaseDatas[i].ContainsFallthrough; switchCaseDatas[i].RequiresContinue = !switchCaseDatas[i].ContainsFallthrough && (switchCaseDatas[i + 1].RequiresContinue || switchCaseDatas[i + 1].ContainsFallthrough); } AABlock previousBlock = bigBlock; //Make code for specific case foreach (SwitchCaseData switchCase in switchCaseDatas) { List<PExp> tests = new List<PExp>(); AABlock nextBlock; if (switchCase.TargetForFallThrough) {//Add if (continueSwitch) {} ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(continueDecl.GetName().Text)); ALvalueExp test = new ALvalueExp(lvalue); nextBlock = new AABlock(); AIfThenStm ifStm = new AIfThenStm(new TLParen("("), test, new ABlockStm(new TLBrace("{"), nextBlock)); previousBlock.GetStatements().Add(ifStm); previousBlock = nextBlock; data.LocalLinks[lvalue] = continueDecl; data.LvalueTypes[lvalue] = data.ExpTypes[test] = continueDecl.GetType(); //First test in next if: if (fallThrough || ... lvalue = new ALocalLvalue(new TIdentifier(fallThroughDecl.GetName().Text)); test = new ALvalueExp(lvalue); tests.Add(test); data.LocalLinks[lvalue] = fallThroughDecl; data.LvalueTypes[lvalue] = data.ExpTypes[test] = fallThroughDecl.GetType(); } //Make code for the test in the if foreach (PExp exp in switchCase.Tests) { ALocalLvalue leftSide = new ALocalLvalue(new TIdentifier(testVar.GetName().Text)); ALvalueExp lvalueExp = new ALvalueExp(leftSide); ABinopExp test = new ABinopExp(lvalueExp, new AEqBinop(new TEq("==")), exp); tests.Add(test); data.LocalLinks[leftSide] = testVar; data.LvalueTypes[leftSide] = data.ExpTypes[lvalueExp] = testVar.GetType(); data.ExpTypes[test] = new ANamedType(new TIdentifier("bool"), null); } if (switchCase.ContainsDefault) { ABooleanConstExp test = new ABooleanConstExp(new ATrueBool()); tests.Add(test); data.ExpTypes[test] = new ANamedType(new TIdentifier("bool"), null); } PExp finalTest = tests[0]; tests.RemoveAt(0); foreach (PExp exp in tests) { finalTest = new ABinopExp(finalTest, new ALazyOrBinop(new TOrOr("||")), exp); data.ExpTypes[finalTest] = new ANamedType(new TIdentifier("bool"), null); } //Transform breaks into assignments //If we can fallthrough, and there are breaks, encase in a while stm AABlock testBlock = switchCase.Block; if (switchCase.RequiresWhile) { AABlock newBlock = new AABlock(); PExp whileTest = new ABooleanConstExp(new ATrueBool()); AWhileStm whileStm = new AWhileStm(new TLParen("("), whileTest, new ABlockStm(new TLBrace("{"), switchCase.Block)); newBlock.GetStatements().Add(whileStm); switchCase.Block = newBlock; } TransformBreaks(testBlock, switchCase, continueDecl, fallThroughDecl); if (switchCase.ContainsFallthrough && !switchCase.TargetForFallThrough) {//Add fallthrough = true; ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(fallThroughDecl.GetName().Text)); ABooleanConstExp rightSide = new ABooleanConstExp(new ATrueBool()); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide); testBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); data.LocalLinks[lvalue] = fallThroughDecl; data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = fallThroughDecl.GetType(); } if (switchCase.RequiresWhile) {//Add break at the end of the while testBlock.GetStatements().Add(new ABreakStm(new TBreak("break"))); } //Make if PStm finalIfStm; if (finalTest is ABooleanConstExp) {//Final if is if(true). dont add it. finalIfStm = new ABlockStm(new TLBrace("{"), switchCase.Block); nextBlock = new AABlock(); } else if (switchCase.IsLast || switchCase.ContainsFallthrough) {//One armed if finalIfStm = new AIfThenStm(new TLParen("("), finalTest, new ABlockStm(new TLBrace("{"), switchCase.Block)); nextBlock = bigBlock; } else {//Two armed if nextBlock = new AABlock(); finalIfStm = new AIfThenElseStm(new TLParen("("), finalTest, new ABlockStm(new TLBrace("{"), switchCase.Block), new ABlockStm(new TLBrace("{"), nextBlock)); } previousBlock.GetStatements().Add(finalIfStm); previousBlock = nextBlock; } //If needed, add fallThroughDecl and continueDecl data.Locals.Add(bigBlock, new List<AALocalDecl>()); if (data.LocalLinks.Values.Contains(fallThroughDecl)) { bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), fallThroughDecl)); data.Locals[bigBlock].Add(fallThroughDecl); } if (data.LocalLinks.Values.Contains(continueDecl)) { bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), continueDecl)); data.Locals[bigBlock].Add(continueDecl); } bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), testVar)); data.Locals[bigBlock].Add(testVar); node.ReplaceBy(new ABlockStm(new TLBrace("{"), bigBlock)); bigBlock.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()); }
ArrayList New292() { ArrayList nodeList = new ArrayList(); ArrayList nodeArrayList1 = (ArrayList) Pop(); TLBrace tlbraceNode2 = (TLBrace)nodeArrayList1[1]; PBlock pblockNode3 = (PBlock)nodeArrayList1[0]; ABlockStm pstmNode1 = new ABlockStm ( tlbraceNode2, pblockNode3 ); nodeList.Add(pstmNode1); return nodeList; }
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, LocRM.GetString("Delegates_Text1"))); 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); }
private PStm RemoveVariableStatement(PStm stm, PExp rightSide, int line, int pos) { if (rightSide != null) { List<PStm> statements = MakeStatements(rightSide, line, pos); if (statements.Count == 0) stm.Parent().RemoveChild(stm); else { PStm statement; if (statements.Count == 1) statement = statements[0]; else statement = new ABlockStm(new TLBrace("{"), new AABlock(statements, new TRBrace("}"))); stm.ReplaceBy(statement); return statement; } } else stm.Parent().RemoveChild(stm); return null; }
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 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 }; }