/*public override void CaseAValueReturnStm(AValueReturnStm node) * { * GetNode(node); * PStm stm = GetNext(whileStm); * if (stm != null) * graphNode.AddSucc(GetNode(stm)); * }*/ public override void CaseAIfThenStm(AIfThenStm node) { //Create graph node Node graphNode = GetNode(node); //Process inner if node.GetBody().Apply(this); //Add successor and predessors PStm stm = GetFirst(node.GetBody()); if (stm != null) { graphNode.AddSucc(GetNode(stm)); } stm = GetNext(node); if (stm != null) { Node nextGraphNode = GetNode(stm); graphNode.AddSucc(nextGraphNode); List <PStm> stms = GetLast(node.GetBody()); foreach (PStm pStm in stms) { nextGraphNode.AddPred(GetNode(pStm)); } } }
private PStm RemoveVariableStatement(PStm stm, PExp rightSide, int line, int pos) { if (rightSide != null) { List <PStm> statements = MakeStatements(rightSide, line, pos); if (statements.Count == 0) { stm.Parent().RemoveChild(stm); } else { PStm statement; if (statements.Count == 1) { statement = statements[0]; } else { statement = new ABlockStm(new TLBrace("{"), new AABlock(statements, new TRBrace("}"))); } stm.ReplaceBy(statement); return(statement); } } else { stm.Parent().RemoveChild(stm); } return(null); }
public ScopeInfo(ABlockStm stm, Scope scope) { mBlock = stm; mFunction = null; mType = ScopeType.Block; mScope = scope; }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { PExp expNode = (PExp)node; PType type = data.ExpTypes[expNode]; if (type is APointerType) { type = new ANamedType(new TIdentifier("string"), null); } ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName", 0, 0)); ALvalueExp exp = new ALvalueExp(local); PStm stm = Util.GetAncestor <PStm>(node); AABlock block = (AABlock)stm.Parent(); node.ReplaceBy(exp); AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier(varName, 0, 0), expNode); ALocalDeclStm newStm = new ALocalDeclStm(new TSemicolon(";"), localDecl); block.GetStatements().Insert(block.GetStatements().IndexOf(stm), newStm); NewStatements.Add(newStm); data.LvalueTypes[local] = type; data.ExpTypes[exp] = type; data.LocalLinks[local] = localDecl; //localDecl.Apply(this); exp.Apply(this); return; }
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 ScopeInfo(Scope scope) { mBlock = null; mFunction = null; mType = ScopeType.Global; mScope = scope; }
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 override void DefaultIn(Node node) { if ((!first || Stm == null) && node is PStm && !(node is ABlockStm)) { Stm = (PStm)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); } } }
public ScopeInfo(AFuncDecl decl, Scope scope) { mFunction = decl; mBlock = null; mType = ScopeType.Function; mScope = scope; }
public static bool HasMoreThanOneUses(PStm statement, AALocalDecl decl, SharedData data, out ALocalLvalue lvalue) { GetUses uses = new GetUses(decl, data); statement.Apply(uses); lvalue = uses.lvalue; return(uses.count > 1); }
public override void CaseABreakStm(ABreakStm node) { Node graphNode = GetNode(node); AWhileStm whileStm = Util.GetAncestor <AWhileStm>(node); PStm stm = GetNext(whileStm); if (stm != null) { graphNode.AddSucc(GetNode(stm)); } }
private Node GetNode(PStm node) { if (StatementNodes.ContainsKey(node)) { return(StatementNodes[node]); } Node graphNode = new Node(node); Nodes.AddLast(graphNode); StatementNodes[node] = graphNode; return(graphNode); }
public 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); }
//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); }
public override void DefaultIn(Node node) { if (node is PStm) { safeVariables = new List <VariableDecl>(); PStm prev = GetPrevious((PStm)node); if (prev != null) { safeVariables.AddRange(safeVariablesAfterStatement[prev]); } unsafeVariables = new List <VariableDecl>(); } base.DefaultIn(node); }
private static PStm GetNext(PStm stm) { while (true) { AABlock pBlock = Util.GetAncestor <AABlock>(stm); if (pBlock == null) { return(null); } int index = pBlock.GetStatements().IndexOf(stm); while (index < pBlock.GetStatements().Count - 1) { stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]); if (stm != null) { return(stm); } index++; } ASTNode node = pBlock; stm = null; while (true) { if (node == null) { return(null); } node = Util.GetNearestAncestor(node.Parent(), typeof(AABlock), typeof(PStm)); if (node is PStm) { stm = (PStm)node; } else if (stm == null) { continue; } else { break; } } //stm = Util.GetAncestor<PStm>(pBlock); if (stm == null) { return(null); } } }
private 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; }
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); }
//Returns true if execution cannot continue after the stm private bool removeDeadCode(PStm stm) { if (stm is ABreakStm || stm is AContinueStm || stm is AVoidReturnStm || stm is AValueReturnStm) { return(true); } if (stm is AIfThenStm) { AIfThenStm aStm = (AIfThenStm)stm; bool stopped = removeDeadCode(aStm.GetBody()); if (IsBoolConst(aStm.GetCondition(), true)) { return(stopped); } return(false); } if (stm is AIfThenElseStm) { AIfThenElseStm aStm = (AIfThenElseStm)stm; bool stopped1 = removeDeadCode(aStm.GetThenBody()); if (IsBoolConst(aStm.GetCondition(), true)) { return(stopped1); } bool stopped2 = removeDeadCode(aStm.GetElseBody()); if (IsBoolConst(aStm.GetCondition(), false)) { return(stopped2); } return(stopped1 && stopped2); } if (stm is AWhileStm) { AWhileStm aStm = (AWhileStm)stm; removeDeadCode(aStm.GetBody()); return(false); } if (stm is ABlockStm) { ABlockStm aStm = (ABlockStm)stm; return(removeDeadCode((AABlock)aStm.GetBlock())); } return(false); }
//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 CaseAWhileStm(AWhileStm node) { //Create graph node Node graphNode = GetNode(node); //Processes inner while node.GetBody().Apply(this); //Add successor and predessors PStm stm = GetFirst(node.GetBody()); if (stm != null) { graphNode.AddSucc(GetNode(stm)); } List <PStm> stms = GetLast(node.GetBody()); foreach (PStm pStm in stms) { graphNode.AddPred(GetNode(pStm)); } }
public override void CaseAALocalDecl(AALocalDecl node) { if (node.GetType() is ANamedType) { ANamedType type = (ANamedType)node.GetType(); if (finalTrans.data.StructTypeLinks.ContainsKey(type)) { AStructDecl strDecl = finalTrans.data.StructTypeLinks[type]; if (strDecl.GetLocals().Cast <PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0) { MoveMethodDeclsOut mover = new MoveMethodDeclsOut("removedStructVar", finalTrans.data); node.Apply(mover); foreach (PStm stm in mover.NewStatements) { stm.Apply(this); } PStm pStm = Util.GetAncestor <PStm>(node); if (pStm == null) { strDecl = Util.GetAncestor <AStructDecl>(node); node.Parent().RemoveChild(node); if (strDecl != null && strDecl.GetLocals().Cast <PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0) { reqRerun = true; } } else { pStm.Parent().RemoveChild(pStm); } return; } } } base.CaseAALocalDecl(node); }
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); }
public override void CaseAMultiLocalDecl(AMultiLocalDecl node) { PStm pStm = Util.GetAncestor <PStm>(node); if (!(pStm.Parent() is AABlock)) { return; } AABlock pBlock = (AABlock)pStm.Parent(); List <AALocalDecl> newDecls = new List <AALocalDecl>(); foreach (AALocalDeclRight right in node.GetLocalDeclRight()) { if (right.GetName() == null) { continue; } if ((right.GetAssignop() == null) != (right.GetInit() == null)) { continue; } AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, node.GetConst() != null ? (TConst)node.GetConst().Clone() : null, (PType)node.GetType().Clone(), right.GetName(), right.GetInit()); newDecls.Add(localDecl); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl)); } pBlock.RemoveChild(pStm); foreach (AALocalDecl localDecl in newDecls) { localDecl.Apply(this); } }
//Returns true if execution cannot continue after the stm private bool removeDeadCode(PStm stm) { if (stm is ABreakStm || stm is AContinueStm || stm is AVoidReturnStm || stm is AValueReturnStm) return true; if (stm is AIfThenStm) { AIfThenStm aStm = (AIfThenStm) stm; bool stopped = removeDeadCode(aStm.GetBody()); if (IsBoolConst(aStm.GetCondition(), true)) return stopped; return false; } if (stm is AIfThenElseStm) { AIfThenElseStm aStm = (AIfThenElseStm)stm; bool stopped1 = removeDeadCode(aStm.GetThenBody()); if (IsBoolConst(aStm.GetCondition(), true)) return stopped1; bool stopped2 = removeDeadCode(aStm.GetElseBody()); if (IsBoolConst(aStm.GetCondition(), false)) return stopped2; return stopped1 && stopped2; } if (stm is AWhileStm) { AWhileStm aStm = (AWhileStm)stm; removeDeadCode(aStm.GetBody()); return false; } if (stm is ABlockStm) { ABlockStm aStm = (ABlockStm)stm; return removeDeadCode((AABlock) aStm.GetBlock()); } return false; }
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 static List <AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans) { /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel") * node = node;*/ SharedData data = finalTrans.data; //If this node is inside the condition of a while, replace it with a new local var, //make a clone before the while, one before each continue in the while, and one at the end of the while //(unless the end is a return or break) AABlock pBlock; if (Util.HasAncestor <AWhileStm>(node)) { AWhileStm whileStm = Util.GetAncestor <AWhileStm>(node); if (Util.IsAncestor(node, whileStm.GetCondition())) { List <ASimpleInvokeExp> toInline = new List <ASimpleInvokeExp>(); //Above while AALocalDecl replaceVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("whileVar"), null); ALocalLvalue replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar")); ALvalueExp replaceVarRefExp = new ALvalueExp(replaceVarRef); data.LocalLinks[replaceVarRef] = replaceVarDecl; data.ExpTypes[replaceVarRefExp] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType(); node.ReplaceBy(replaceVarRefExp); replaceVarDecl.SetInit(node); pBlock = (AABlock)whileStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(whileStm), new ALocalDeclStm(new TSemicolon(";"), replaceVarDecl)); toInline.Add(node); //In the end of the while PStm lastStm = whileStm.GetBody(); while (lastStm is ABlockStm) { AABlock block = (AABlock)((ABlockStm)lastStm).GetBlock(); if (block.GetStatements().Count == 0) { lastStm = null; break; } lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1]; } if (lastStm == null || !(lastStm is AValueReturnStm || lastStm is AVoidReturnStm || lastStm is ABreakStm)) { lastStm = whileStm.GetBody(); AABlock block; if (lastStm is ABlockStm) { block = (AABlock)((ABlockStm)lastStm).GetBlock(); } else { block = new AABlock(new ArrayList(), new TRBrace("}")); block.GetStatements().Add(lastStm); whileStm.SetBody(new ABlockStm(new TLBrace("{"), block)); } replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar")); ASimpleInvokeExp clone = (ASimpleInvokeExp)Util.MakeClone(node, data); toInline.Add(clone); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), replaceVarRef, clone); data.LocalLinks[replaceVarRef] = replaceVarDecl; data.ExpTypes[assignment] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType(); block.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment)); } //After each continue CloneBeforeContinue cloner = new CloneBeforeContinue(node, replaceVarDecl, data); whileStm.GetBody().Apply(cloner); toInline.AddRange(cloner.replacementExpressions); List <AABlock> visitBlocks = new List <AABlock>(); foreach (ASimpleInvokeExp invoke in toInline) { visitBlocks.AddRange(Inline(invoke, finalTrans)); } return(visitBlocks); } } AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node]; FindAssignedToFormals assignedToFormalsFinder = new FindAssignedToFormals(finalTrans.data); decl.Apply(assignedToFormalsFinder); List <AALocalDecl> assignedToFormals = assignedToFormalsFinder.AssignedFormals; /* * inline int foo(int a) * { * int b = 2; * int c; * ... * while(...) * { * ... * break; * ... * return c; * } * ... * return 2; * } * * bar(foo(<arg for a>)); * -> * * { * bool inlineMethodReturned = false; * int inlineReturner; * int a = <arg for a>; * while (!inlineMethodReturned) * { * int b = 2; * int c; * ... * while(...) * { * ... * break * ... * inlineReturner = c; * inlineMethodReturned = true; * break; * } * if (inlineMethodReturned) * { * break; * } * ... * inlineReturner = 2; * inlineMethodReturned = true; * break; * break; * } * bar(inlineReturner); * } * * */ AABlock outerBlock = new AABlock(); PExp exp = new ABooleanConstExp(new AFalseBool()); finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null); AALocalDecl hasMethodReturnedVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("hasInlineReturned"), exp); finalTrans.data.GeneratedVariables.Add(hasMethodReturnedVar); PStm stm = new ALocalDeclStm(new TSemicolon(";"), hasMethodReturnedVar); outerBlock.GetStatements().Add(stm); AALocalDecl methodReturnerVar = null; if (!(decl.GetReturnType() is AVoidType)) { methodReturnerVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(decl.GetReturnType(), finalTrans.data), new TIdentifier("inlineReturner"), null); stm = new ALocalDeclStm(new TSemicolon(";"), methodReturnerVar); outerBlock.GetStatements().Add(stm); } AABlock afterBlock = new AABlock(); //A dictionary from the formals of the inline method to a cloneable replacement lvalue Dictionary <AALocalDecl, PLvalue> Parameters = new Dictionary <AALocalDecl, PLvalue>(); Dictionary <AALocalDecl, PExp> ParameterExps = new Dictionary <AALocalDecl, PExp>(); for (int i = 0; i < decl.GetFormals().Count; i++) { AALocalDecl formal = (AALocalDecl)decl.GetFormals()[i]; PExp arg = (PExp)node.GetArgs()[0]; PLvalue lvalue; //if ref, dont make a new var if (formal.GetRef() != null && arg is ALvalueExp) { arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data)); arg.Parent().RemoveChild(arg); lvalue = ((ALvalueExp)arg).GetLvalue(); } else if (!assignedToFormals.Contains(formal) && Util.IsLocal(arg, finalTrans.data)) { lvalue = new ALocalLvalue(new TIdentifier("I hope I dont make it")); finalTrans.data.LvalueTypes[lvalue] = formal.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = formal; ParameterExps[formal] = arg; arg.Parent().RemoveChild(arg); } else { AAssignmentExp assExp = null; if (formal.GetOut() != null) { //Dont initialize with arg, but assign arg after arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data)); lvalue = ((ALvalueExp)arg).GetLvalue(); assExp = new AAssignmentExp(new TAssign("="), lvalue, null); finalTrans.data.ExpTypes[assExp] = finalTrans.data.LvalueTypes[lvalue]; arg.Parent().RemoveChild(arg); arg = null; } AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), arg); stm = new ALocalDeclStm(new TSemicolon(";"), parameter); outerBlock.GetStatements().Add(stm); lvalue = new ALocalLvalue(new TIdentifier(parameter.GetName().Text)); finalTrans.data.LvalueTypes[lvalue] = parameter.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = parameter; if (formal.GetOut() != null) { //Dont initialize with arg, but assign arg after ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(lvalue, finalTrans.data)); finalTrans.data.ExpTypes[lvalueExp] = finalTrans.data.LvalueTypes[lvalue]; assExp.SetExp(lvalueExp); afterBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assExp)); } } Parameters.Add(formal, lvalue); } AABlock innerBlock = (AABlock)decl.GetBlock().Clone(); exp = new ABooleanConstExp(new ATrueBool()); finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null); ABlockStm innerBlockStm = new ABlockStm(new TLBrace("{"), innerBlock); bool needWhile = CheckIfWhilesIsNeeded.IsWhileNeeded(decl.GetBlock()); if (needWhile) { stm = new AWhileStm(new TLParen("("), exp, innerBlockStm); } else { stm = innerBlockStm; } outerBlock.GetStatements().Add(stm); outerBlock.GetStatements().Add(new ABlockStm(new TLBrace("{"), afterBlock)); //Clone method contents to inner block. CloneMethod cloneFixer = new CloneMethod(finalTrans, Parameters, ParameterExps, innerBlockStm); decl.GetBlock().Apply(cloneFixer); foreach (KeyValuePair <PLvalue, PExp> pair in cloneFixer.ReplaceUsAfter) { PLvalue lvalue = pair.Key; PExp replacement = Util.MakeClone(pair.Value, finalTrans.data); ALvalueExp lvalueParent = (ALvalueExp)lvalue.Parent(); lvalueParent.ReplaceBy(replacement); } innerBlockStm.Apply(new FixTypes(finalTrans.data)); innerBlock.Apply(new FixReturnsAndWhiles(hasMethodReturnedVar, methodReturnerVar, finalTrans.data, needWhile)); GetNonBlockStm stmFinder = new GetNonBlockStm(false); innerBlock.Apply(stmFinder); if (needWhile && (stmFinder.Stm == null || !(stmFinder.Stm is ABreakStm))) { innerBlock.GetStatements().Add(new ABreakStm(new TBreak("break"))); } //Insert before current statement ABlockStm outerBlockStm = new ABlockStm(new TLBrace("{"), outerBlock); PStm pStm = Util.GetAncestor <PStm>(node); pBlock = (AABlock)pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), outerBlockStm); if (node.Parent() == pStm && pStm is AExpStm) { pBlock.RemoveChild(pStm); } else { PLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text)); finalTrans.data.LvalueTypes[lvalue] = methodReturnerVar.GetType(); finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = methodReturnerVar; exp = new ALvalueExp(lvalue); finalTrans.data.ExpTypes[exp] = methodReturnerVar.GetType(); node.ReplaceBy(exp); } return(new List <AABlock>() { outerBlock }); }
private static PStm GetNext(PStm stm) { while (true) { AABlock pBlock = Util.GetAncestor<AABlock>(stm); if (pBlock == null) return null; int index = pBlock.GetStatements().IndexOf(stm); while (index < pBlock.GetStatements().Count - 1) { stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]); if (stm != null) return stm; index++; } ASTNode node = pBlock; stm = null; while (true) { if (node == null) return null; node = Util.GetNearestAncestor(node.Parent(), typeof(AABlock), typeof(PStm)); if (node is PStm) stm = (PStm)node; else if (stm == null) continue; else break; } //stm = Util.GetAncestor<PStm>(pBlock); if (stm == null) return null; } }
private Node GetNode(PStm node) { if (StatementNodes.ContainsKey(node)) return StatementNodes[node]; Node graphNode = new Node(node); Nodes.AddLast(graphNode); StatementNodes[node] = graphNode; return graphNode; }
public StmEnum(PStm stm) { this.stm = stm; }
public bool MoveNext() { NextStm next = new NextStm(stm); stm.Apply(next); stm = next.nextStm; return stm != null; }
public AForStm( TLParen _token_, PStm _init_, PExp _cond_, PStm _update_, PStm _body_ ) { SetToken(_token_); SetInit(_init_); SetCond(_cond_); SetUpdate(_update_); SetBody(_body_); }
public void SetUpdate(PStm node) { if (_update_ != null) { _update_.Parent(null); } if (node != null) { if (node.Parent() != null) { node.Parent().RemoveChild(node); } node.Parent(this); } _update_ = node; }
public override void DefaultIn(Node node) { if (node is PStm) { if (node == oldStm) oldStm = null; else if (oldStm == null && nextStm == null) nextStm = (PStm)node; } base.DefaultIn(node); }
public override void DefaultIn(Node node) { if ((!first || Stm == null) && node is PStm && !(node is ABlockStm)) Stm = (PStm)node; }
public NextStm(PStm oldStm) { this.oldStm = oldStm; }
public override void OutATriggerDecl(ATriggerDecl node) { //If no actions, insert it if (node.GetActions() == null) { node.SetActions(new AABlock(new ArrayList(), new TRBrace("}", -1, -1))); node.SetActionsToken(new TActions("actions", -1, -1)); } //If return in events is missing, insert it. if (node.GetEvents() != null) { AABlock block = (AABlock)node.GetEvents(); bool insertReturn = false; while (true) { if (block.GetStatements().Count == 0) { insertReturn = true; break; } PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1]; if (lastStm is AVoidReturnStm) { break; } if (lastStm is ABlockStm) { block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock(); continue; } insertReturn = true; break; } if (insertReturn) { block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos))); } } //Also for actions //if (node.GetActions() != null) { AABlock block = (AABlock)node.GetActions(); bool insertReturn = false; while (true) { if (block.GetStatements().Count == 0) { insertReturn = true; break; } PStm lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1]; if (lastStm is AVoidReturnStm) { break; } if (lastStm is ABlockStm) { block = (AABlock)((ABlockStm)block.GetStatements()[block.GetStatements().Count - 1]).GetBlock(); continue; } insertReturn = true; break; } if (insertReturn) { block.GetStatements().Add(new AVoidReturnStm(new TReturn("return", block.GetToken().Line, block.GetToken().Pos))); } } }
public override void OutAIfExp(AIfExp node) { //Transform to /* * var expIfVar; * if (<cond>) * { * expIfVar = <then>; * } * else * { * expIfVar = <else>; * } * ... expIfVar ... */ AALocalDecl expIfVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("expIfVar"), null); ALocalLvalue thenExpIfVarLink = new ALocalLvalue(new TIdentifier("expIfVar")); ALocalLvalue elseExpIfVarLink = new ALocalLvalue(new TIdentifier("expIfVar")); ALocalLvalue usageExpIfVarLink = new ALocalLvalue(new TIdentifier("expIfVar")); ALvalueExp usageExpIfVarLinkExp = new ALvalueExp(usageExpIfVarLink); AAssignmentExp thenAssignment = new AAssignmentExp(new TAssign("="), thenExpIfVarLink, node.GetThen()); AAssignmentExp elseAssignment = new AAssignmentExp(new TAssign("="), elseExpIfVarLink, node.GetElse()); AIfThenElseStm ifStm = new AIfThenElseStm(new TLParen("("), node.GetCond(), new ABlockStm(new TLBrace("{"), new AABlock( new ArrayList() { new AExpStm(new TSemicolon(";"), thenAssignment) }, new TRBrace("}"))), new ABlockStm(new TLBrace("{"), new AABlock( new ArrayList() { new AExpStm(new TSemicolon(";"), elseAssignment) }, new TRBrace("}")))); data.LocalLinks[thenExpIfVarLink] = data.LocalLinks[elseExpIfVarLink] = data.LocalLinks[usageExpIfVarLink] = expIfVarDecl; data.LvalueTypes[thenExpIfVarLink] = data.LvalueTypes[elseExpIfVarLink] = data.LvalueTypes[usageExpIfVarLink] = data.ExpTypes[usageExpIfVarLinkExp] = data.ExpTypes[thenAssignment] = data.ExpTypes[elseAssignment] = expIfVarDecl.GetType(); PStm pStm = Util.GetAncestor <PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), expIfVarDecl)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), ifStm); node.ReplaceBy(usageExpIfVarLinkExp); base.OutAIfExp(node); }
private void TransformBreaks(PStm stm, SwitchCaseData switchCase, AALocalDecl continueDecl, AALocalDecl fallthroughDecl, ref int currI) { if (stm is ABreakStm) { AABlock pBlock = (AABlock) stm.Parent(); if (!switchCase.IsLast && (switchCase.RequiresContinue || switchCase.ContainsFallthrough)) { //Add continue = false; ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(continueDecl.GetName().Text)); ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool()); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment)); data.LocalLinks[lvalue] = continueDecl; data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = continueDecl.GetType(); currI++; } if (!switchCase.IsLast && switchCase.TargetForFallThrough) { //Add fallthrough = false; ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(fallthroughDecl.GetName().Text)); ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool()); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment)); data.LocalLinks[lvalue] = fallthroughDecl; data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = fallthroughDecl.GetType(); currI++; } if (!switchCase.RequiresWhile) {//Remove break stm.Parent().RemoveChild(stm); currI--; } } if (stm is ABlockStm) TransformBreaks((AABlock)((ABlockStm)stm).GetBlock(), switchCase, continueDecl, fallthroughDecl); if (stm is AIfThenStm) TransformBreaks(((AIfThenStm)stm).GetBody(), switchCase, continueDecl, fallthroughDecl, ref currI); if (stm is AIfThenElseStm) { TransformBreaks(((AIfThenElseStm)stm).GetThenBody(), switchCase, continueDecl, fallthroughDecl, ref currI); TransformBreaks(((AIfThenElseStm)stm).GetElseBody(), switchCase, continueDecl, fallthroughDecl, ref currI); } }
private bool CanFallthrough(PStm stm, out bool containsBreak, out bool requiresWhile) { containsBreak = stm is ABreakStm; requiresWhile = false; if (stm is ABreakStm || stm is AVoidReturnStm || stm is AValueReturnStm) return false; if (stm is ABlockStm) return CanFallthrough((AABlock)((ABlockStm)stm).GetBlock(), out containsBreak, out requiresWhile); if (stm is AIfThenStm) { CanFallthrough(((AIfThenStm) stm).GetBody(), out containsBreak, out requiresWhile); return true; } if (stm is AIfThenElseStm) { bool b1 = CanFallthrough(((AIfThenElseStm) stm).GetThenBody(), out containsBreak, out requiresWhile); bool hasBreak; bool reqWhile; bool b2 = CanFallthrough(((AIfThenElseStm)stm).GetElseBody(), out hasBreak, out reqWhile); containsBreak |= hasBreak; requiresWhile |= reqWhile; return b1 || b2; } return true; }
public static bool HasMoreThanOneUses(PStm statement, AALocalDecl decl, SharedData data, out ALocalLvalue lvalue) { GetUses uses = new GetUses(decl, data); statement.Apply(uses); lvalue = uses.lvalue; return uses.count > 1; }
public override void CaseAMethodDecl(AMethodDecl node) { if (firstMethodCall) StatementRemover.Parse(node); firstMethodCall = false; before.Clear(); after.Clear(); uses.Clear(); intersectingLocals.Clear(); definedLocals.Clear(); renamedLocals.Clear(); assigns.Clear(); changes = false; //Make uses setUses = true; base.CaseAMethodDecl(node); setUses = false; //Build a list of what's visible do { changes = false; base.CaseAMethodDecl(node); } while (changes); setSpans = true; base.CaseAMethodDecl(node); setSpans = false; //Join locals of same type, unless they are both parameters or they are listed as intersecting for (int i = 0; i < definedLocals.Count; i++) { for (int j = i + 1; j < definedLocals.Count; j++) { AALocalDecl decl1 = definedLocals[i]; AALocalDecl decl2 = definedLocals[j]; if (Util.TypeToString(decl1.GetType()) == Util.TypeToString(decl2.GetType()) && !intersectingLocals.Contains(new Pair(decl1, decl2))) { if (Util.GetAncestor<AABlock>(decl1) == null && Util.GetAncestor<AABlock>(decl2) == null) continue; AALocalDecl replacement = decl1; AALocalDecl replaced = decl2; //Dont replace the parameter if (Util.GetAncestor<AABlock>(replaced) == null) { replacement = decl2; replaced = decl1; i--; } j--; renamedLocals.Add(replaced, replacement); definedLocals.Remove(replaced); foreach (Pair pair in intersectingLocals) { if (pair.Local1 == replaced) pair.Local1 = replacement; if (pair.Local2 == replaced) pair.Local2 = replacement; } //Assign defaults if (replaced.GetInit() == null) { ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(replaced.GetName().Text)); finalTrans.data.LocalLinks[lvalue] = replaced; finalTrans.data.LvalueTypes[lvalue] = replaced.GetType(); List<PStm> statements = AssignDefault(lvalue); PStm pStm = Util.GetAncestor<PStm>(replaced); AABlock pBlock = (AABlock) pStm.Parent(); foreach (PStm statement in statements) { pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement); } pBlock.RemoveChild(pStm); } else { //Make an assignment expression instead ALocalDeclStm declStm = (ALocalDeclStm)replaced.Parent(); ALocalLvalue lvalue = new ALocalLvalue((TIdentifier)replaced.GetName().Clone()); finalTrans.data.LvalueTypes[lvalue] = replaced.GetType(); AAssignmentExp exp = new AAssignmentExp(new TAssign("=", lvalue.GetName().Line, lvalue.GetName().Pos), lvalue, replaced.GetInit()); AExpStm expStm = new AExpStm(declStm.GetToken(), exp); declStm.ReplaceBy(expStm); finalTrans.data.LvalueTypes[lvalue] = replacement.GetType(); finalTrans.data.ExpTypes[exp] = replacement.GetType(); finalTrans.data.LocalLinks[lvalue] = replacement; } } } } //Unique names List<string> names = new List<string>(); //Avoid clash with methods/fields/structs names.AddRange(finalTrans.data.Methods.Select(declItem => declItem.Decl.GetName().Text)); names.AddRange(finalTrans.data.Fields.Select(declItem => declItem.Decl.GetName().Text)); names.AddRange(finalTrans.data.Structs.Select(declItem => declItem.Decl.GetName().Text)); foreach (AALocalDecl local in definedLocals) { string name = local.GetName().Text; int version = 1; while (names.Contains(name)) { version++; name = local.GetName().Text + version; } local.GetName().Text = name; names.Add(name); } //Move defined locals to the start of the method foreach (AALocalDecl formal in node.GetFormals()) { definedLocals.Remove(formal); } AABlock block = (AABlock)node.GetBlock(); for (int i = 0; i < block.GetStatements().Count; i++) { ALocalDeclStm stm; if (block.GetStatements()[i] is ALocalDeclStm) { stm = (ALocalDeclStm)block.GetStatements()[i]; definedLocals.Remove((AALocalDecl)stm.GetLocalDecl()); continue; } //Add the rest at i if (definedLocals.Count == 0) break; AALocalDecl decl = definedLocals[0]; definedLocals.RemoveAt(0); if (decl.GetInit() == null) { ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text)); finalTrans.data.LocalLinks[lvalue] = decl; finalTrans.data.LvalueTypes[lvalue] = decl.GetType(); List<PStm> statements = AssignDefault(lvalue); PStm pStm = Util.GetAncestor<PStm>(decl); AABlock pBlock = (AABlock) pStm.Parent(); foreach (PStm statement in statements) { pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), statement); } pBlock.RemoveChild(pStm); } else { //Make an assignment expression before moving stm = (ALocalDeclStm)decl.Parent(); ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(decl.GetName().Text)); finalTrans.data.LvalueTypes[lvalue] = decl.GetType(); AAssignmentExp exp = new AAssignmentExp(new TAssign("="), lvalue, decl.GetInit()); AExpStm expStm = new AExpStm(new TSemicolon(";"), exp); stm.ReplaceBy(expStm); finalTrans.data.LvalueTypes[lvalue] = decl.GetType(); finalTrans.data.ExpTypes[exp] = decl.GetType(); finalTrans.data.LocalLinks[lvalue] = decl; } stm = new ALocalDeclStm(new TSemicolon(";"), decl); block.GetStatements().Insert(i, stm); } fixRefferences = true; base.CaseAMethodDecl(node); fixRefferences = false; //If we have an assignment to a local where the stored result is never used, remove the assignment //Since we changed some statements, rebuild stuff before.Clear(); after.Clear(); uses.Clear(); intersectingLocals.Clear(); definedLocals.Clear(); renamedLocals.Clear(); assigns.Clear(); changes = false; //Make uses setUses = true; base.CaseAMethodDecl(node); setUses = false; //Build a list of what's visible do { changes = false; base.CaseAMethodDecl(node); } while (changes); PStm[] stms = new PStm[before.Keys.Count]; before.Keys.CopyTo(stms, 0); foreach (PStm stm in stms) { if (assigns[stm] != null && //Assignment exp !after[stm].Contains(assigns[stm]) && //Assignment unused Util.GetAncestor<AMethodDecl>(assigns[stm]) != null && !(stm is ALocalDeclStm))//It is to a local { stm.Apply(new MoveMethodDeclsOut(finalTrans.data)); stm.Parent().RemoveChild(stm); } } //Remove foo = foo; RemoveStupidAssignments assignmentRemover = new RemoveStupidAssignments(finalTrans.data); node.Apply(assignmentRemover); //Remove unused local variables foreach (AALocalDecl local in definedLocals) { if (Util.GetAncestor<AAProgram>(local) != null && Util.GetAncestor<AABlock>(local) != null && !finalTrans.data.LocalLinks.Where(p => p.Value == local).Any(p => Util.GetAncestor<AAProgram>(p.Key) != null)) local.Parent().Parent().RemoveChild(local.Parent()); } if (assignmentRemover.RemovedOne) { CaseAMethodDecl(node); return; } //If an assignment to a variable is completely local, and that assignment is only used once, put the assignment where it is used //Since we changed some statements, rebuild stuff before.Clear(); after.Clear(); uses.Clear(); intersectingLocals.Clear(); definedLocals.Clear(); renamedLocals.Clear(); assigns.Clear(); changes = false; //Make uses setUses = true; base.CaseAMethodDecl(node); setUses = false; //Build a list of what's visible do { changes = false; base.CaseAMethodDecl(node); } while (changes); foreach (KeyValuePair<PStm, AALocalDecl> pair in assigns) { PStm assignStm = pair.Key; AALocalDecl assignVar = pair.Value; bool isLocal = Util.IsLocal(assignStm, finalTrans.data); bool containsInvokeInPrevStm = false; if (assignVar != null && after[assignStm].Contains(assignVar)) { bool dontMove = false; //First, if there are any conditional parrent statement, where the variable is in live before the stm, then we can't move it PStm condParent = (PStm) Util.GetNearestAncestor(assignStm, typeof (AIfThenStm), typeof (AIfThenElseStm), typeof (AWhileStm)); while (condParent != null) { if (before[condParent].Contains(assignVar)) { dontMove = true; break; } condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm), typeof(AWhileStm)); } PStm useStm = null; List<PStm> successors = GetSuccessor(assignStm); bool containsConditionalAssignments = false; while (successors.Count > 0) { if (successors.Count > 500) useStm = useStm; PStm successor = successors[0]; successors.RemoveAt(0); if (uses[successor].Contains(assignVar)) { if (useStm == null && !containsConditionalAssignments && !(successor is AWhileStm)) useStm = successor; else { dontMove = true; break; } } if (after[successor].Contains(assignVar) && !(assigns.ContainsKey(successor) && assigns[successor] == assignVar)) { List<PStm> newSuccessors = GetSuccessor(successor); foreach (PStm stm in newSuccessors) { if (!successors.Contains(stm)) successors.Add(stm); } } if (assigns.ContainsKey(successor) && uses[assignStm].Contains(assigns[successor])) { dontMove = true; break; } if (assigns.ContainsKey(successor) && assigns[successor] == assignVar) { condParent = (PStm)Util.GetNearestAncestor(successor, typeof(AIfThenStm), typeof(AIfThenElseStm), typeof(AWhileStm)); while (condParent != null) { if (!Util.IsAncestor(assignStm, condParent)) { containsConditionalAssignments = true; break; } condParent = (PStm)Util.GetNearestAncestor(condParent.Parent(), typeof(AIfThenStm), typeof(AIfThenElseStm), typeof(AWhileStm)); } //If we found a usage, and it is inside a while that the assignStm is not inside, but we are inside, don't move if (useStm != null) { AWhileStm whileParant = Util.GetAncestor<AWhileStm>(successor); while (whileParant != null) { if (Util.IsAncestor(useStm, whileParant) && !Util.IsAncestor(assignStm, whileParant)) { dontMove = true; break; } whileParant = Util.GetAncestor<AWhileStm>(whileParant.Parent()); } } } FindInvoke finder = new FindInvoke(); successor.Apply(finder); if (finder.ContainsInvoke && useStm == null) containsInvokeInPrevStm = true; } if (useStm != null && !dontMove) { //If assignStm is inside an if, and the use stm is not, and there is another assignment //to the same variable in an else block, then don't join AIfThenElseStm ifThenElse = Util.GetAncestor<AIfThenElseStm>(assignStm); while (ifThenElse != null) { if (!Util.IsAncestor(useStm, ifThenElse)) { ABlockStm otherBlock; if (Util.IsAncestor(assignStm, ifThenElse.GetThenBody())) otherBlock = (ABlockStm) ifThenElse.GetElseBody(); else otherBlock = (ABlockStm)ifThenElse.GetThenBody(); StmEnum enumerator = new StmEnum(otherBlock); while (enumerator.MoveNext()) { PStm stm = (PStm) enumerator.Current; if (assigns.ContainsKey(stm) && assigns[stm] == assignVar) { dontMove = true; break; } } if (dontMove) break; } ifThenElse = Util.GetAncestor<AIfThenElseStm>(ifThenElse.Parent()); } //If the assignStm or useStm is inside a while, it could get complicated //if (Util.HasAncestor<AWhileStm>(assignStm) || Util.HasAncestor<AWhileStm>(useStm)) // dontMove = true; } if (useStm != null && dontMove == false && (isLocal || !containsInvokeInPrevStm)) { //Ensure that it is not used twice in this stm FindLvalue finder = new FindLvalue(assignVar, finalTrans.data); useStm.Apply(finder); if (!finder.IsUsedTwice && (isLocal || !finder.HasPrevInvoke)) { PExp rightside; if (assignStm is ALocalDeclStm) { rightside = ((AALocalDecl)((ALocalDeclStm)assignStm).GetLocalDecl()).GetInit(); } else { rightside = ((AAssignmentExp)((AExpStm)assignStm).GetExp()).GetExp(); assignStm.Parent().RemoveChild(assignStm); } if (rightside != null) { finder.Lvalue.Parent().ReplaceBy(rightside); CaseAMethodDecl(node); return; } } } } } if (StatementRemover.Parse(node)) { CaseAMethodDecl(node); return; } firstMethodCall = true; }
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 AIfThenElseStm( TLParen _token_, PExp _condition_, PStm _then_body_, PStm _else_body_ ) { SetToken(_token_); SetCondition(_condition_); SetThenBody(_then_body_); SetElseBody(_else_body_); }
public void SetInit(PStm node) { if (_init_ != null) { _init_.Parent(null); } if (node != null) { if (node.Parent() != null) { node.Parent().RemoveChild(node); } node.Parent(this); } _init_ = node; }
public void SetBody(PStm node) { if (_body_ != null) { _body_.Parent(null); } if (node != null) { if (node.Parent() != null) { node.Parent().RemoveChild(node); } node.Parent(this); } _body_ = node; }
internal override void RemoveChild(Node child) { if (_token_ == child) { _token_ = null; return; } if (_init_ == child) { _init_ = null; return; } if (_cond_ == child) { _cond_ = null; return; } if (_update_ == child) { _update_ = null; return; } if (_body_ == child) { _body_ = null; return; } }
private static PStm GetNext(PStm stm) { while (true) { AABlock pBlock = Util.GetAncestor<AABlock>(stm); if (pBlock == null) return null; int index = pBlock.GetStatements().IndexOf(stm); while (index < pBlock.GetStatements().Count - 1) { stm = GetFirst((PStm)pBlock.GetStatements()[index + 1]); if (stm != null) return stm; index++; } stm = Util.GetAncestor<PStm>(pBlock); if (stm == null) return null; } }
public AIfThenStm( TLParen _token_, PExp _condition_, PStm _body_ ) { SetToken(_token_); SetCondition(_condition_); SetBody(_body_); }
public Node(PStm statement) { Statement = statement; }
internal override void RemoveChild(Node child) { if (_token_ == child) { _token_ = null; return; } if (_condition_ == child) { _condition_ = null; return; } if (_body_ == child) { _body_ = null; return; } }
private static List<PStm> GetLast(PStm stm) { List<PStm> returner = new List<PStm>(); if (stm is ABlockStm) { AABlock block = (AABlock) ((ABlockStm) stm).GetBlock(); stm = null; for (int i = block.GetStatements().Count - 1; i >= 0; i--) { returner.AddRange(GetLast((PStm) block.GetStatements()[i])); if (returner.Count > 0) return returner; } } else if (stm is AIfThenElseStm) { List<PStm> stms = new List<PStm>(); stms.AddRange(GetLast(((AIfThenElseStm)stm).GetThenBody())); bool zero = stms.Count == 0; returner.AddRange(stms); stms.Clear(); stms.AddRange(GetLast(((AIfThenElseStm)stm).GetElseBody())); zero |= stms.Count == 0; returner.AddRange(stms); if (zero) returner.Add(stm); } else returner.Add(stm); return returner; }
private static PStm GetLast(PStm stm) { if (stm is ABlockStm) { AABlock block = (AABlock)((ABlockStm)stm).GetBlock(); stm = null; for (int i = block.GetStatements().Count - 1; i >= 0; i--) { stm = GetLast((PStm)block.GetStatements()[i]); if (stm != null) return stm; } } return stm; }
//if ur an if you got 2 //if ur a while you got 2 //if ur not an if else, and your the last element of a block, look up untill you encounter // another block, keep searching in that // a while, pick that // a method decl, no successor private List<PStm> GetSuccessor(PStm stm) { List<PStm> list = new List<PStm>(); AABlock block; ABlockStm blockStm; if (stm is AIfThenElseStm) { AIfThenElseStm aStm = (AIfThenElseStm)stm; bool fallthrough = false; //Then blockStm = (ABlockStm)aStm.GetThenBody(); block = (AABlock)blockStm.GetBlock(); GetNonBlockStm stmFinder = new GetNonBlockStm(true); block.Apply(stmFinder); if (stmFinder.Stm != null) list.Add(stmFinder.Stm); else fallthrough = true; //Else blockStm = (ABlockStm)aStm.GetElseBody(); block = (AABlock)blockStm.GetBlock(); stmFinder = new GetNonBlockStm(true); block.Apply(stmFinder); if (stmFinder.Stm != null) list.Add(stmFinder.Stm); else fallthrough = true; if (!fallthrough) return list; } if (stm is AIfThenStm) { AIfThenStm aStm = (AIfThenStm)stm; //Then blockStm = (ABlockStm)aStm.GetBody(); block = (AABlock)blockStm.GetBlock(); GetNonBlockStm stmFinder = new GetNonBlockStm(true); block.Apply(stmFinder); if (stmFinder.Stm != null) { list.Add(stmFinder.Stm); } } if (stm is AWhileStm) { AWhileStm aStm = (AWhileStm)stm; //Then blockStm = (ABlockStm)aStm.GetBody(); block = (AABlock)blockStm.GetBlock(); GetNonBlockStm stmFinder = new GetNonBlockStm(true); block.Apply(stmFinder); if (stmFinder.Stm != null) { list.Add(stmFinder.Stm); } } if (stm is ABreakStm) { AWhileStm whileStm = Util.GetAncestor<AWhileStm>(stm); list = GetSuccessor(whileStm); list.RemoveAt(0); return list; } if (stm is AContinueStm) { AWhileStm whileStm = Util.GetAncestor<AWhileStm>(stm); list.Add(whileStm); return list; } //Get the next statement in block block = (AABlock)stm.Parent(); int index = block.GetStatements().IndexOf(stm); if (index == block.GetStatements().Count - 1) list.AddRange(GetSuccessor(block)); else { stm = (PStm)block.GetStatements()[index + 1]; while (stm is ABlockStm) { blockStm = (ABlockStm)stm; block = (AABlock)blockStm.GetBlock(); if (block.GetStatements().Count == 0) { list.AddRange(GetSuccessor(block)); return list; } stm = (PStm)block.GetStatements()[0]; } list.Add(stm); } return list; }
private static PStm GetPrevious(PStm stm) { while (true) { AABlock pBlock = Util.GetAncestor<AABlock>(stm); if (pBlock == null) return null; int index = pBlock.GetStatements().IndexOf(stm); while (index > 0) { stm = GetLast((PStm)pBlock.GetStatements()[index - 1]); if (stm != null) return stm; index--; } stm = Util.GetAncestor<PStm>(pBlock); if (stm == null) return null; } }
private PStm RemoveVariableStatement(PStm stm, PExp rightSide, int line, int pos) { if (rightSide != null) { List<PStm> statements = MakeStatements(rightSide, line, pos); if (statements.Count == 0) stm.Parent().RemoveChild(stm); else { PStm statement; if (statements.Count == 1) statement = statements[0]; else statement = new ABlockStm(new TLBrace("{"), new AABlock(statements, new TRBrace("}"))); stm.ReplaceBy(statement); return statement; } } else stm.Parent().RemoveChild(stm); return null; }