public VariableDescription(AALocalDecl localDecl, VariableTypes type) { Name = localDecl.GetName().Text; Type = Util.TypeToString(localDecl.GetType()); switch (type) { case VariableTypes.LocalVariable: PlacementPrefix = "Local"; break; case VariableTypes.Parameter: PlacementPrefix = "Parameter"; break; case VariableTypes.StructVariable: PlacementPrefix = "Struct field"; break; default: PlacementPrefix = ""; break; } VariableType = type; Const = localDecl.GetConst() != null; IsStatic = localDecl.GetStatic() != null; Visibility = localDecl.GetVisibilityModifier(); realType = (PType) localDecl.GetType().Clone(); init = localDecl.GetInit(); Line = localDecl.GetName().Line; Position = TextPoint.FromCompilerCoords(localDecl.GetName()); }
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); }
//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 OutAALocalDecl(AALocalDecl node) { if (!Util.HasAncestor<AABlock>(node) && !Util.HasAncestor<AMethodDecl>(node)) { //OutStructFieldDecl(node); return; } if (node.GetInit() != null) return; AABlock pBlock; int insertIndex; PLvalue lvalue; if (Util.HasAncestor<AABlock>(node)) { //A local variable pBlock = Util.GetAncestor<AABlock>(node); insertIndex = pBlock.GetStatements().IndexOf(Util.GetAncestor<PStm>(node)) + 1; lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text)); data.LocalLinks[(ALocalLvalue) lvalue] = node; data.LvalueTypes[lvalue] = node.GetType(); } else { //Parameter //Parameters will be set from the caller return; pBlock = (AABlock) Util.GetAncestor<AMethodDecl>(node).GetBlock(); insertIndex = 0; lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text)); data.LocalLinks[(ALocalLvalue)lvalue] = node; data.LvalueTypes[lvalue] = node.GetType(); } AABlock block = new AABlock(new ArrayList(), new TRBrace("}")); MakeAssignments(block, node.GetType(), lvalue, true); if (block.GetStatements().Count != 0) pBlock.GetStatements().Insert(insertIndex, new ABlockStm(new TLBrace("{"), block)); }
public override void CaseAALocalDecl(AALocalDecl node) { if (node.GetConst() != null) Write("const "); node.GetType().Apply(this); Write(" " + node.GetName().Text); if (node.GetInit() != null) { Write(" = "); node.GetInit().Apply(this); } }
public override void CaseAALocalDecl(AALocalDecl node) { /*foreach (List<PointerType> pointerType in GetAllPointerTypes(node, node.GetType())) { MakePointer(pointerType); }*/ //Parameter if (Util.GetAncestor<AMethodDecl>(node) == null) return; { /*currentPointer.Clear(); node.GetLvalue().Apply(this); List<PointerType> leftSide = MakePointer(currentPointer);*/ if (node.GetInit() == null) { isSet = false; isExposed = false; } else { currentPointer.Clear(); node.GetInit().Apply(this); } //List<PointerType> rightSide = MakePointer(currentPointer); foreach (List<PointerType> prefix in GetAllPointerTypes(node, node.GetType())) { //if prefix is root - set to isSet / isExposed //if prefix is child - set isSet only if false, and isExposed only if true. bool isRoot = prefix.Count == 1; List<PointerType> aPrefix = MakePointer(prefix); if (isSet != Contains(setPointers, aPrefix)) { if (isSet) { if (isRoot) setPointers.Add(aPrefix); } else setPointers.Remove(aPrefix); } if (isExposed != Contains(exposedPointers, aPrefix)) { if (isSet) setPointers.Add(aPrefix); else if (isRoot) setPointers.Remove(aPrefix); } } } }
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); } }
public override void OutAALocalDecl(AALocalDecl node) { if (node.GetInit() != null) { PType from = data.ExpTypes[node.GetInit()]; PType to = node.GetType(); if (!Assignable(from, to)) { if (ImplicitAssignable(from, to)) { ANamedType namedTo = (ANamedType)to; ACastExp cast = new ACastExp(new TLParen("("), new ANamedType(new TIdentifier(((AAName)namedTo.GetName()).AsString()), null), node.GetInit()); node.SetInit(cast); OutACastExp(cast); to = from; } else errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, LocRM.GetString("ErrorText151") + Util.TypeToString(from) + LocRM.GetString("ErrorText152") + Util.TypeToString(to))); } } //If the return type or the type of any formals is a private struct, and the method is a public context, give an error if (node.Parent() is AStructDecl) { AStructDecl pStruct = Util.GetAncestor<AStructDecl>(node); //Is public context if ( pStruct.GetVisibilityModifier() is APublicVisibilityModifier && !(node.GetVisibilityModifier() is APrivateVisibilityModifier)) { PType type = node.GetType(); int i = 0; FindPrivateTypes finder = new FindPrivateTypes(data); type.Apply(finder); if (finder.PrivateTypes.Count > 0) { List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>(); List<PDecl> usedDecls = new List<PDecl>(); foreach (ANamedType namedType in finder.PrivateTypes) { if (data.StructTypeLinks.ContainsKey(namedType)) { AStructDecl decl = data.StructTypeLinks[namedType]; if (usedDecls.Contains(decl)) continue; usedDecls.Add(decl); subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText64"))); } else if (data.DelegateTypeLinks.ContainsKey(namedType)) { AMethodDecl decl = data.DelegateTypeLinks[namedType]; if (usedDecls.Contains(decl)) continue; usedDecls.Add(decl); subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText154"))); } } errors.Add(new ErrorCollection.Error(node.GetName(), LocRM.GetString("ErrorText155"), false, subErrors.ToArray())); } } } base.OutAALocalDecl(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 CaseAALocalDecl(AALocalDecl node) { //Convert a static struct field into a global variable. All refferences to it are structFieldLvalues. if (node.GetStatic() == null) return; AStructDecl str = (AStructDecl) node.Parent(); if (data.StructFields[str].Contains(node)) data.StructFields[str].Remove(node); AFieldDecl replacementField; //Don't enhrit static fields. if (data.EnheritanceLocalMap.ContainsKey(node)) { str.RemoveChild(node); AALocalDecl realVar = data.EnheritanceLocalMap[node]; if (convertionMap.ContainsKey(realVar)) { //Already converted to a field replacementField = convertionMap[realVar]; foreach (AStructFieldLvalue lvalue in data.StructMethodFieldLinks.Where(link => link.Value == node).Select(link => link.Key)) { AFieldLvalue newLvalue = new AFieldLvalue(new TIdentifier(replacementField.GetName().Text)); data.FieldLinks[newLvalue] = replacementField; data.LvalueTypes[newLvalue] = replacementField.GetType(); lvalue.ReplaceBy(newLvalue); } } else { List<AStructFieldLvalue> refferences = new List<AStructFieldLvalue>(); refferences.AddRange(data.StructMethodFieldLinks.Where(link => link.Value == node).Select(link => link.Key)); foreach (AStructFieldLvalue lvalue in refferences) { data.StructMethodFieldLinks[lvalue] = realVar; } } return; } replacementField = new AFieldDecl(new APublicVisibilityModifier(), null, node.GetConst(), node.GetType(), node.GetName(), node.GetInit()); replacementField.GetName().Text = str.GetName().Text + "_" + replacementField.GetName().Text; AASourceFile file = Util.GetAncestor<AASourceFile>(node); file.GetDecl().Insert(file.GetDecl().IndexOf(node.Parent()), replacementField); data.Fields.Add(new SharedData.DeclItem<AFieldDecl>(file, replacementField)); if (ContainsNewExp(replacementField.GetInit())) data.FieldsToInitInMapInit.Add(replacementField); foreach (AStructFieldLvalue lvalue in data.StructMethodFieldLinks.Where(link => link.Value == node).Select(link => link.Key)) { AFieldLvalue newLvalue = new AFieldLvalue(new TIdentifier(replacementField.GetName().Text)); data.FieldLinks[newLvalue] = replacementField; data.LvalueTypes[newLvalue] = replacementField.GetType(); lvalue.ReplaceBy(newLvalue); } convertionMap.Add(node, replacementField); node.Parent().RemoveChild(node); }
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); }
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 }; }
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); }
public override void CaseAALocalDecl(AALocalDecl node) { OldParameterTypes.Add(node, node.GetType()); base.CaseAALocalDecl(node); }
public override void CaseAALocalDecl(AALocalDecl node) { InAALocalDecl(node); if (node.GetInit() != null) { node.GetInit().Apply(this); } if (node.GetName() != null) { node.GetName().Apply(this); } if (node.GetType() != null) { node.GetType().Apply(this); } if (node.GetConst() != null) { node.GetConst().Apply(this); } if (node.GetOut() != null) { node.GetOut().Apply(this); } if (node.GetRef() != null) { node.GetRef().Apply(this); } if (node.GetStatic() != null) { node.GetStatic().Apply(this); } if (node.GetVisibilityModifier() != null) { node.GetVisibilityModifier().Apply(this); } OutAALocalDecl(node); }
public override void CaseANewExp(ANewExp node) { //Call new object or new array ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("invoke"), new ArrayList()); ANamedType pointerType = new ANamedType(new TIdentifier("string"), null); if (node.GetType() is AArrayTempType) { if (newArrayMethod == null) CreateNewArrayMethod(node, data); node.GetType().Apply(this); AArrayTempType type = (AArrayTempType) node.GetType(); invoke.GetArgs().Add(Util.MakeClone(type.GetDimention(), data)); data.SimpleMethodLinks[invoke] = newArrayMethod; } else if (Util.IsIntPointer(node, node.GetType(), data)) { if (node.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) node.GetType())) data.SimpleMethodLinks[invoke] = CreateNewObjectMethod(node, data.StructTypeLinks[(ANamedType) node.GetType()], data); else { data.SimpleMethodLinks[invoke] = CreateNewObjectMethod(node, data.EnrichmentTypeLinks[node.GetType()], data); } pointerType = new ANamedType(new TIdentifier("int"), null); } else { if (newObjectMethod == null) CreateNewObjectMethod(node, data); data.SimpleMethodLinks[invoke] = newObjectMethod; } node.ReplaceBy(invoke); data.ExpTypes[invoke] = pointerType; //Call initializer if (data.ConstructorLinks.ContainsKey(node)) { PStm pStm = Util.GetAncestor<PStm>(invoke); AABlock pblock = (AABlock) pStm.Parent(); PLvalue lvalue; ALvalueExp lvalueExp; PStm stm; AAssignmentExp assignment = null; AALocalDecl localDecl = null; if (invoke.Parent() is AAssignmentExp) { AAssignmentExp parent = (AAssignmentExp) invoke.Parent(); assignment = parent; /*lvalue = parent.GetLvalue(); lvalue.Apply(new MoveMethodDeclsOut("pointerVar", data)); lvalue = Util.MakeClone(lvalue, data);*/ } else if (invoke.Parent() is AALocalDecl) { AALocalDecl parent = (AALocalDecl) invoke.Parent(); localDecl = parent; /*lvalue = new ALocalLvalue(new TIdentifier(parent.GetName().Text)); data.LocalLinks[(ALocalLvalue) lvalue] = parent; data.LvalueTypes[lvalue] = parent.GetType();*/ } else { //Move the new invocation out into a local decl, and use that localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(pointerType, data), new TIdentifier("newVar"), null); ALocalLvalue localLvalue = new ALocalLvalue(new TIdentifier("newVar")); lvalueExp = new ALvalueExp(localLvalue); invoke.ReplaceBy(lvalueExp); localDecl.SetInit(invoke); stm = new ALocalDeclStm(new TSemicolon(";"), localDecl); pblock.GetStatements().Insert(pblock.GetStatements().IndexOf(pStm), stm); pStm = stm; //lvalue = new ALocalLvalue(new TIdentifier("newVar")); //data.LocalLinks[(ALocalLvalue) lvalue] = data.LocalLinks[localLvalue] = localDecl; //data.LvalueTypes[lvalue] = data.LvalueTypes[localLvalue] = data.ExpTypes[lvalueExp] = localDecl.GetType(); } ASimpleInvokeExp oldInvoke = invoke; invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()); while (node.GetArgs().Count > 0) { invoke.GetArgs().Add(node.GetArgs()[0]); } if (assignment != null) { assignment.SetExp(invoke); invoke.GetArgs().Add(oldInvoke); } else { localDecl.SetInit(invoke); invoke.GetArgs().Add(oldInvoke); } //lvalueExp = new ALvalueExp(lvalue); //invoke.GetArgs().Add(lvalueExp); //stm = new AExpStm(new TSemicolon(";"), invoke); //pblock.GetStatements().Insert(pblock.GetStatements().IndexOf(pStm) + 1, stm); //data.ExpTypes[lvalueExp] = data.LvalueTypes[lvalue]; data.SimpleMethodLinks[invoke] = data.ConstructorMap[data.ConstructorLinks[node]]; data.ExpTypes[invoke] = data.ConstructorMap[data.ConstructorLinks[node]].GetReturnType(); invoke.Apply(this); } }
public override void OutASimpleInvokeExp(ASimpleInvokeExp node) { if (data.BulkCopyProcessedInvokes.Contains(node)) { base.OutASimpleInvokeExp(node); return; } //If anything needs to be put after the invoke, move it to it's own local decl or exp statement AMethodDecl method = data.SimpleMethodLinks[node]; if (!processedMethods.Contains(method)) CaseAMethodDecl(method); bool moveOut = Util.IsBulkCopy(data.ExpTypes[node]); PType type; if (!moveOut) for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp)node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl)method.GetFormals()[i]; type = data.ExpTypes[arg]; if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { moveOut = true; break; } } if (moveOut && !(node.Parent() is AExpStm || node.Parent() is AALocalDecl)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock) pStm.Parent(); //Can not be a void type, since it is not in an expStm AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.ExpTypes[node], data), new TIdentifier("bulkCopyVar"), null); ALocalLvalue bulkCopyVarRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); ALvalueExp bulkCopyVarRefExp = new ALvalueExp(bulkCopyVarRef); node.ReplaceBy(bulkCopyVarRefExp); localDecl.SetInit(node); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl)); data.LocalLinks[bulkCopyVarRef] = localDecl; data.LvalueTypes[bulkCopyVarRef] = data.ExpTypes[bulkCopyVarRefExp] = localDecl.GetType(); } //Replace bulk copy arguments with a new pointer for (int i = 0; i < node.GetArgs().Count; i++) { PExp arg = (PExp) node.GetArgs()[i]; AALocalDecl formal = (AALocalDecl) method.GetFormals()[i]; if (oldParameterTypes.ContainsKey(formal)) type = oldParameterTypes[formal];// data.ExpTypes[arg]; else type = formal.GetType(); if (Util.IsBulkCopy(type) || formal.GetRef() != null || formal.GetOut() != null) { if (formal.GetRef() != null && arg is ALvalueExp) { ALvalueExp aArg = (ALvalueExp) arg; if (aArg.GetLvalue() is APointerLvalue) { APointerLvalue pointer = (APointerLvalue) aArg.GetLvalue(); if (Util.TypesEqual(formal.GetType(), data.ExpTypes[pointer.GetBase()], data)) {//Just send the arg aArg.ReplaceBy(pointer.GetBase()); continue; } } } TurnDynamic(arg, formal, oldParameterTypes.ContainsKey(formal) ? oldParameterTypes[formal] : formal.GetType(), formal.GetOut() == null, formal.GetRef() != null || formal.GetOut() != null); } } //Do return stm type = data.ExpTypes[node]; if (Util.IsBulkCopy(type)) { PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); bool isReturnUsed = !(node.Parent() is AExpStm); if (isReturnUsed) { //Make //var bulkCopyVar = <node>(...); //<usage>... *bulkCopyVar ... </usage> //delete bulkCopyVar; bool isArray = type is AArrayTempType; AALocalDecl newLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), isArray ? new ADynamicArrayType( new TLBracket("["), Util.MakeClone( ((AArrayTempType) type). GetType(), data)) : Util.MakeClone(type, data)), new TIdentifier("bulkCopyVar"), null); data.ExpTypes[node] = newLocal.GetType(); ALocalLvalue newLocalRef; ALvalueExp newLocalRefExp; newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); APointerLvalue newLocalPointer = new APointerLvalue(new TStar("*"), newLocalRefExp); ALvalueExp newLocalPointerExp = new ALvalueExp(newLocalPointer); node.ReplaceBy(newLocalPointerExp); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); data.LvalueTypes[newLocalPointer] = data.ExpTypes[newLocalPointerExp] = ((APointerType) newLocal.GetType()).GetType(); newLocal.SetInit(node); newLocalRef = new ALocalLvalue(new TIdentifier("bulkCopyVar")); newLocalRefExp = new ALvalueExp(newLocalRef); data.LocalLinks[newLocalRef] = newLocal; data.LvalueTypes[newLocalRef] = data.ExpTypes[newLocalRefExp] = newLocal.GetType(); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), newLocal)); pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ADeleteStm(new TDelete("delete"), newLocalRefExp)); } else { //Make delete <node>(...); pStm.ReplaceBy(new ADeleteStm(new TDelete("delete"), node)); } } base.OutASimpleInvokeExp(node); }
public override void OutAALocalDecl(AALocalDecl node) { if (node.GetInit() != null) { PType type = node.GetType(); if (Util.IsBulkCopy(type)) { node.Apply(mover); ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text)); data.LocalLinks[lvalue] = node; data.LvalueTypes[lvalue] = type; List<PStm> replacementStatements = MakeAssignments(lvalue, node.GetInit(), new List<AALocalDecl>() { null }); PStm pStm = Util.GetAncestor<PStm>(node); AABlock pBlock = (AABlock)pStm.Parent(); foreach (PStm stm in replacementStatements) { pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, stm); } node.SetInit(null); } } base.OutAALocalDecl(node); }
/*private List<List<PointerType>> GetAllVariables(AALocalDecl localDecl, PType type) { List<List<PointerType>> ret = new List<List<PointerType>>(); if (type is APointerType) { //This pointer can have a value ret.Add(new List<PointerType>(){new PointerPointer()}); foreach (List<PointerType> child in GetAllVariables(localDecl, ((APointerType)type).GetType())) { child.Insert(0, new PointerPointer()); ret.Add(child); } } else if (type is ANamedType && Util.IsBulkCopy(type)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType)type]; foreach (AALocalDecl local in structDecl.GetLocals()) { ret.AddRange(GetAllVariables(local)); } } else if (type is ADynamicArrayType) { } }*/ private List<List<PointerType>> GetAllVariables(AALocalDecl localDecl, PType type, bool wasPointer = false) { List<List<PointerType>> returner = new List<List<PointerType>>(); if (type is APointerType) { returner.Add(type == localDecl.GetType() && !wasPointer ? new List<PointerType>() { new LocalDeclPointer(localDecl) } : new List<PointerType>() { new PointerPointer() }); foreach (List<PointerType> pointer in GetAllVariables(localDecl, ((APointerType)type).GetType(), true)) { pointer.Insert(0, type == localDecl.GetType() && !wasPointer ? new LocalDeclPointer(localDecl) : (PointerType)new PointerPointer()); returner.Add(pointer); } } else if (type is ANamedType) { if (Util.IsBulkCopy(type)) { AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type]; foreach (AALocalDecl local in structDecl.GetLocals()) { List<List<PointerType>> returnedStuff = GetAllVariables(local, local.GetType()); foreach (List<PointerType> pointers in returnedStuff) { pointers.Insert(0, wasPointer ? (PointerType) new PointerPointer() : new LocalDeclPointer(localDecl)); returner.Add(pointers); } } } else { //returner.a } } return returner; }
//int* a => local a; local a, pointer //struct foo{int* bar; int[] foobar} foo* baz => local baz /* local baz * local baz -> pointer * local baz -> pointer -> local bar * local baz -> pointer -> local bar -> pointer * local baz -> pointer -> local foobar * local baz -> pointer -> local foobar -> arrayLength * local baz -> pointer -> local foobar -> arrayIndex i * * * * * */ private List<List<PointerType>> GetAllVariables(AALocalDecl localDecl) { //You always want to append a List<List<PointerType>> ret = GetAllVariables(localDecl, localDecl.GetType()); foreach (List<PointerType> value in ret) { value.Insert(0, new LocalDeclPointer(localDecl)); } ret.Add(new List<PointerType>(){new LocalDeclPointer(localDecl)}); return ret; }
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 void MakeInitializerInvokes() { AABlock block = (AABlock) mainEntry.GetBlock(); AASourceFile file = Util.GetAncestor<AASourceFile>(mainEntry); AMethodDecl invokeMethod; /* Add * void Invoke(string methodName) * { * trigger initTrigger = TriggerCreate(methodName); * TriggerExecute(initTrigger, false, true); * TriggerDestroy(initTrigger); * } */ { //void Invoke(string methodName) AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("string"), null), new TIdentifier("methodName"), null); AABlock methodBody = new AABlock(); invokeMethod = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), new TIdentifier("Invoke"), new ArrayList(){parameter}, methodBody); //trigger initTrigger = TriggerCreate(methodName); ALocalLvalue parameterLvalue = new ALocalLvalue(new TIdentifier("methodName")); data.LocalLinks[parameterLvalue] = parameter; ALvalueExp parameterLvalueExp = new ALvalueExp(parameterLvalue); data.LvalueTypes[parameterLvalue] = data.ExpTypes[parameterLvalueExp] = parameter.GetType(); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("TriggerCreate"), new ArrayList(){parameterLvalueExp}); data.ExpTypes[invoke] = new ANamedType(new TIdentifier("trigger"), null); foreach (AMethodDecl methodDecl in data.Libraries.Methods) { if (methodDecl.GetName().Text == "TriggerCreate") { data.SimpleMethodLinks[invoke] = methodDecl; break; } } AALocalDecl initTriggerDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("trigger"), null), new TIdentifier("initTrigger"), invoke); methodBody.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), initTriggerDecl)); //TriggerExecute(initTrigger, false, true); ALocalLvalue initTriggerLvalue = new ALocalLvalue(new TIdentifier("initTrigger")); data.LocalLinks[initTriggerLvalue] = initTriggerDecl; ALvalueExp initTriggerLvalueExp = new ALvalueExp(initTriggerLvalue); data.LvalueTypes[initTriggerLvalue] = data.ExpTypes[initTriggerLvalueExp] = initTriggerDecl.GetType(); ABooleanConstExp falseBool = new ABooleanConstExp(new AFalseBool()); ABooleanConstExp trueBool = new ABooleanConstExp(new ATrueBool()); data.ExpTypes[falseBool] = data.ExpTypes[trueBool] = new ANamedType(new TIdentifier("bool"), null); invoke = new ASimpleInvokeExp(new TIdentifier("TriggerExecute"), new ArrayList() { initTriggerLvalueExp, falseBool, trueBool }); data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); foreach (AMethodDecl methodDecl in data.Libraries.Methods) { if (methodDecl.GetName().Text == "TriggerExecute") { data.SimpleMethodLinks[invoke] = methodDecl; break; } } methodBody.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke)); //TriggerDestroy(initTrigger); initTriggerLvalue = new ALocalLvalue(new TIdentifier("initTrigger")); data.LocalLinks[initTriggerLvalue] = initTriggerDecl; initTriggerLvalueExp = new ALvalueExp(initTriggerLvalue); data.LvalueTypes[initTriggerLvalue] = data.ExpTypes[initTriggerLvalueExp] = initTriggerDecl.GetType(); invoke = new ASimpleInvokeExp(new TIdentifier("TriggerDestroy"), new ArrayList() { initTriggerLvalueExp }); data.ExpTypes[invoke] = new AVoidType(new TVoid("void")); foreach (AMethodDecl methodDecl in data.Libraries.Methods) { if (methodDecl.GetName().Text == "TriggerDestroy") { data.SimpleMethodLinks[invoke] = methodDecl; break; } } methodBody.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke)); file.GetDecl().Add(invokeMethod); } for (int i = data.InitializerMethods.Count - 1; i >= 0; i--) { AMethodDecl method = data.InitializerMethods[i]; //Turn method into a trigger method.SetReturnType(new ANamedType(new TIdentifier("bool"), null)); method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("testConds"), null)); method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("runActions"), null)); method.SetTrigger(new TTrigger("trigger")); ((AABlock) method.GetBlock()).GetStatements().Add(new AVoidReturnStm(new TReturn("return"))); TriggerConvertReturn returnConverter = new TriggerConvertReturn(data); method.Apply(returnConverter); data.TriggerDeclarations[method] = new List<TStringLiteral>(); //Add Invoke(<name>); to main entry TStringLiteral literal = new TStringLiteral(method.GetName().Text); data.TriggerDeclarations[method].Add(literal); AStringConstExp stringConst = new AStringConstExp(literal); data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("Invoke"), new ArrayList(){stringConst}); data.SimpleMethodLinks[invoke] = invokeMethod; data.ExpTypes[invoke] = invokeMethod.GetReturnType(); block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke)); //ASyncInvokeExp syncInvokeExp = new ASyncInvokeExp(new TSyncInvoke("Invoke"), new AAmbiguousNameLvalue(new ASimpleName(new TIdentifier(method.GetName().Text))), new ArrayList()); //data.Invokes.Add(method, new List<InvokeStm>(){new InvokeStm(syncInvokeExp)}); //data.ExpTypes[syncInvokeExp] = new AVoidType(new TVoid("void")); //block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), syncInvokeExp)); } for (int i = data.InvokeOnIniti.Count - 1; i >= 0; i--) { AMethodDecl method = data.InvokeOnIniti[i]; //Turn method into a trigger method.SetReturnType(new ANamedType(new TIdentifier("bool"), null)); method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("testConds"), null)); method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null), new TIdentifier("runActions"), null)); method.SetTrigger(new TTrigger("trigger")); ((AABlock)method.GetBlock()).GetStatements().Add(new AVoidReturnStm(new TReturn("return"))); TriggerConvertReturn returnConverter = new TriggerConvertReturn(data); method.Apply(returnConverter); data.TriggerDeclarations[method] = new List<TStringLiteral>(); //Add Invoke(<name>); to main entry TStringLiteral literal = new TStringLiteral(method.GetName().Text); data.TriggerDeclarations[method].Add(literal); AStringConstExp stringConst = new AStringConstExp(literal); data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null); ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("Invoke"), new ArrayList() { stringConst }); data.SimpleMethodLinks[invoke] = invokeMethod; data.ExpTypes[invoke] = invokeMethod.GetReturnType(); block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke)); /* ASyncInvokeExp syncInvokeExp = new ASyncInvokeExp(new TSyncInvoke("Invoke"), new AAmbiguousNameLvalue(new ASimpleName(new TIdentifier(method.GetName().Text))), new ArrayList()); data.Invokes.Add(method, new List<InvokeStm>() { new InvokeStm(syncInvokeExp) }); data.ExpTypes[syncInvokeExp] = new AVoidType(new TVoid("void")); block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), syncInvokeExp));*/ } for (int i = data.FieldsToInitInMapInit.Count - 1; i >= 0; i--) { AFieldDecl field = data.FieldsToInitInMapInit[i]; if (field.GetInit() == null) continue; AFieldLvalue lvalue = new AFieldLvalue(new TIdentifier(field.GetName().Text)); AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, field.GetInit()); data.ExpTypes[assignment] = data.LvalueTypes[lvalue] = field.GetType(); data.FieldLinks[lvalue] = field; block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), assignment)); } block.RemoveChild(mainEntryFieldInitBlock); block.GetStatements().Insert(0, mainEntryFieldInitBlock); }