示例#1
0
 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);
 }
示例#2
0
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            Write("\n");
            if (node.GetStatic() != null)
            {
                Write("static ");
            }
            if (node.GetNative() != null)
            {
                Write("native ");
            }
            node.GetReturnType().Apply(this);
            Write(" " + node.GetName().Text + "(");
            bool first = true;

            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (!first)
                {
                    Write(", ");
                }
                formal.Apply(this);
                first = false;
            }
            if (node.GetBlock() != null)
            {
                Write(")\n");
                node.GetBlock().Apply(this);
            }
            else
            {
                Write(");\n\n");
            }
        }
示例#3
0
            public override void OutASimpleInvokeExp(ASimpleInvokeExp node)
            {
                if (currentMethod == null)
                {
                    return;
                }

                AMethodDecl targetMethod = data.SimpleMethodLinks[node];

                if (node.Parent() is APointerLvalue || node.Parent() is AStructLvalue)
                {
                    //Move node out
                    MoveOut(node, targetMethod.GetReturnType());
                }


                //Only if it is not a library method
                if (Util.HasAncestor <AAProgram>(node))
                {
                    if (!dependancies[currentMethod].Contains(targetMethod))
                    {
                        dependancies[currentMethod].Add(targetMethod);
                    }
                }
            }
示例#4
0
            public override void CaseAMethodDecl(AMethodDecl node)
            {
                End        = Start = TextPoint.FromCompilerCoords(node.GetName().Line, node.GetName().Pos);
                ReturnType = Util.TypeToString(node.GetReturnType());
                Name       = node.GetName().Text;

                base.CaseAMethodDecl(node);
            }
示例#5
0
        public override void CaseAMethodDecl(AMethodDecl node)
        {
            if (node.GetNative() == null && node.GetBlock() == null)
            {
                return;
            }
            if (node.GetStatic() != null)
            {
                return;
            }

            string inputStr = "native " + TypeToString(node.GetReturnType()) + " " + node.GetName().Text +
                              "(";
            bool first = true;

            foreach (AALocalDecl formal in node.GetFormals())
            {
                if (!first)
                {
                    inputStr += ", ";
                }
                inputStr += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                first     = false;
            }
            inputStr += ");";

            writer.WriteLine(inputStr);

            AStructDecl        str = Util.GetAncestor <AStructDecl>(node);
            List <AMethodDecl> methodList;

            if (str != null)
            {
                methodList = StructMethods[str];
            }
            else
            {
                methodList = Methods;
            }
            string sig = Util.GetMethodSignature(node);

            if (methodList.Any(otherMethod => Util.GetMethodSignature(otherMethod) == sig))
            {
                return;
            }

            methodList.Add(node);
            node.SetBlock(null);
            node.Parent().RemoveChild(node);
        }
示例#6
0
        public static string ToString(AMethodDecl methodDecl)
        {
            string str = TypeToString(methodDecl.GetReturnType()) + " " + methodDecl.GetName().Text + "(";

            foreach (AALocalDecl formal in methodDecl.GetFormals())
            {
                if (str.EndsWith("("))
                {
                    str += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                }
                else
                {
                    str += ", " + TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                }
            }
            str += ")";
            return(str);
        }
            public override void CaseAVoidReturnStm(AVoidReturnStm node)
            {
                AMethodDecl baseDeconstructor = data.DeconstructorMap[data.StructDeconstructor[baseStruct]];


                ALocalLvalue     structFormalRef    = new ALocalLvalue(new TIdentifier("currentStruct"));
                ALvalueExp       structFormalRefExp = new ALvalueExp(structFormalRef);
                ASimpleInvokeExp invoke             = new ASimpleInvokeExp(new TIdentifier("baseDeconstructor"),
                                                                           new ArrayList()
                {
                    structFormalRefExp
                });
                AABlock block = (AABlock)node.Parent();

                block.GetStatements().Insert(block.GetStatements().IndexOf(node), new AExpStm(new TSemicolon(";"), invoke));

                data.LocalLinks[structFormalRef]  = structFormal;
                data.SimpleMethodLinks[invoke]    = baseDeconstructor;
                data.LvalueTypes[structFormalRef] = data.ExpTypes[structFormalRefExp] = structFormal.GetType();
                data.ExpTypes[invoke]             = baseDeconstructor.GetReturnType();
            }
示例#8
0
        public MethodDescription(AMethodDecl method)
        {
            Parser parser = new Parser(method);


            Start      = parser.Start;
            End        = parser.End;
            ReturnType = parser.ReturnType;
            Name       = parser.Name;
            Formals    = parser.Formals;
            Locals     = parser.Locals;
            if (method.Parent() != null)
            {
                method.Parent().RemoveChild(method);
            }
            IsDelegate = method.GetDelegate() != null;
            //if (!IsDelegate)
            Decl       = method;
            IsStatic   = method.GetStatic() != null;
            Visibility = method.GetVisibilityModifier();
            realType   = (PType)method.GetReturnType().Clone();
            Position   = TextPoint.FromCompilerCoords(method.GetName());
        }
示例#9
0
        public override void CaseADelegateInvokeExp(ADelegateInvokeExp node)
        {
            //Build a list of the possible methods
            AASourceFile       currentFile    = Util.GetAncestor <AASourceFile>(node);
            List <AMethodDecl> methods        = new List <AMethodDecl>();
            ANamedType         type           = (ANamedType)finalTrans.data.ExpTypes[node.GetReceiver()];
            AMethodDecl        delegateMethod = finalTrans.data.DelegateTypeLinks[type];

            foreach (KeyValuePair <ADelegateExp, AMethodDecl> delegateCreationPair in finalTrans.data.DelegateCreationMethod)
            {
                if (TypeChecking.Assignable(delegateCreationPair.Key.GetType(), type))
                {
                    if (!methods.Contains(delegateCreationPair.Value))
                    {
                        methods.Add(delegateCreationPair.Value);
                    }
                }
            }
            MoveMethodDeclsOut mover;

            if (methods.Count == 0)
            {
                //Can only remove it if the return value is unused
                if (!(node.Parent() is AExpStm))
                {
                    finalTrans.errors.Add(new ErrorCollection.Error(node.GetToken(),
                                                                    currentFile,
                                                                    "No possible methods found for delegate invoke."));
                    throw new ParserException(node.GetToken(), "Delegates.OutADelegateInvokeExp");
                }

                mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data);
                foreach (Node arg in node.GetArgs())
                {
                    arg.Apply(mover);
                }
                node.Parent().Parent().RemoveChild(node.Parent());
                foreach (PStm stm in mover.NewStatements)
                {
                    stm.Apply(this);
                }
                return;
            }
            if (methods.Count == 1)
            {
                ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList());
                while (node.GetArgs().Count > 0)
                {
                    invoke.GetArgs().Add(node.GetArgs()[0]);
                }

                //If we have a struct method, add the pointer from the delegate
                if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(methods[0])))
                {
                    AStructDecl      targetStr        = finalTrans.data.StructMethods.First(str => str.Value.Contains(methods[0])).Key;
                    AMethodDecl      getPointerDecl   = GetPointerMethod(targetStr.GetDimention() != null);
                    ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()
                    {
                        node.GetReceiver()
                    });
                    invoke.GetArgs().Add(getPointerInvoke);

                    finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl;
                    finalTrans.data.ExpTypes[getPointerInvoke]          = getPointerDecl.GetReturnType();
                }

                finalTrans.data.SimpleMethodLinks[invoke] = methods[0];
                finalTrans.data.ExpTypes[invoke]          = methods[0].GetReturnType();
                node.ReplaceBy(invoke);
                return;
            }
            //Multiple methods. Make

            /*
             * <Methods moved out from reciever>
             * string delegate = GetMethodPart(<reciever>);
             * if (delegate == "...")
             * {
             *    Foo(...);
             * }
             * else if (delegate == "...")
             * {
             *    Bar(..., GetPointerPart(<reciever>);
             * }
             * else if(...)
             * ...
             * else
             * {
             *     UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("[<file>:<line>]: No methods matched delegate."));
             *     int i = 1/0;
             *     return;
             * }
             *
             */
            AABlock block = new AABlock(new ArrayList(), new TRBrace("}"));

            mover = new MoveMethodDeclsOut("delegateVar", finalTrans.data);
            node.GetReceiver().Apply(mover);
            AMethodDecl      methodPartMethod = GetMethodMethod();
            ASimpleInvokeExp methodPartInvoke = new ASimpleInvokeExp(new TIdentifier("GetMethodPart"),
                                                                     new ArrayList()
            {
                Util.MakeClone(node.GetReceiver(),
                               finalTrans.data)
            });

            finalTrans.data.SimpleMethodLinks[methodPartInvoke] = methodPartMethod;
            finalTrans.data.ExpTypes[methodPartInvoke]          = methodPartMethod.GetReturnType();
            AALocalDecl methodPartDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                         new ANamedType(new TIdentifier("string"), null),
                                                         new TIdentifier("methodPart"), methodPartInvoke);

            block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), methodPartDecl));
            //If the invoke's return value is used, get the lvalue
            PLvalue leftSide;

            if (node.Parent() is AALocalDecl)
            {
                leftSide = new ALocalLvalue(new TIdentifier("renameMe"));
                finalTrans.data.LocalLinks[(ALocalLvalue)leftSide] = (AALocalDecl)node.Parent();
                finalTrans.data.LvalueTypes[leftSide] = new ANamedType(new TIdentifier("string"), null);
                PStm    pStm   = Util.GetAncestor <PStm>(node);
                AABlock pBlock = (AABlock)pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm) + 1, new ABlockStm(new TLBrace("{"), block));
                node.Parent().RemoveChild(node);
            }
            else if (node.Parent() is AAssignmentExp)
            {
                AAssignmentExp assignExp = (AAssignmentExp)node.Parent();
                leftSide = assignExp.GetLvalue();
                leftSide.Apply(mover);

                PStm pStm = Util.GetAncestor <PStm>(node);
                pStm.ReplaceBy(new ABlockStm(new TLBrace("{"), block));
            }
            else if (node.Parent() is AExpStm)
            {
                //No assignments needed
                leftSide = null;
                node.Parent().ReplaceBy(new ABlockStm(new TLBrace("{"), block));
            }
            else
            {
                //Create a new local
                AALocalDecl leftSideDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                           Util.MakeClone(delegateMethod.GetReturnType(),
                                                                          finalTrans.data),
                                                           new TIdentifier("delegateVar"), null);
                ALocalLvalue leftSideLink    = new ALocalLvalue(new TIdentifier("delegateVar"));
                ALvalueExp   leftSideLinkExp = new ALvalueExp(leftSideLink);


                PStm    pStm   = Util.GetAncestor <PStm>(node);
                AABlock pBlock = (AABlock)pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ABlockStm(new TLBrace("{"), block));

                node.ReplaceBy(leftSideLinkExp);

                finalTrans.data.LocalLinks[leftSideLink]      = leftSideDecl;
                finalTrans.data.LvalueTypes[leftSideLink]     =
                    finalTrans.data.ExpTypes[leftSideLinkExp] = leftSideDecl.GetType();

                leftSide = leftSideLink;
                block.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), leftSideDecl));
            }

            ABlockStm elseBranch;

            //Make final else branch

            /* {
             *     UIDisplayMessage(PlayerGroupAll(), c_messageAreaDebug, StringToText("<file>[<line>, <pos>]: No methods matched delegate."));
             *     IntToString(1/0);
             *     return;
             * }
             */
            {
                AABlock          innerBlock         = new AABlock(new ArrayList(), new TRBrace("}"));
                ASimpleInvokeExp playerGroupInvoke  = new ASimpleInvokeExp(new TIdentifier("PlayerGroupAll"), new ArrayList());
                AFieldLvalue     messageAreaLink    = new AFieldLvalue(new TIdentifier("c_messageAreaDebug"));
                ALvalueExp       messageAreaLinkExp = new ALvalueExp(messageAreaLink);
                AStringConstExp  stringConst        =
                    new AStringConstExp(
                        new TStringLiteral("\"" + currentFile.GetName().Text.Replace('\\', '/') + "[" +
                                           node.GetToken().Line + ", " + node.GetToken().Pos +
                                           "]: Got a null delegate.\""));
                ASimpleInvokeExp stringToTextInvoke = new ASimpleInvokeExp(new TIdentifier("StringToText"),
                                                                           new ArrayList()
                {
                    stringConst
                });
                ASimpleInvokeExp displayMessageInvoke = new ASimpleInvokeExp(new TIdentifier("UIDisplayMessage"),
                                                                             new ArrayList()
                {
                    playerGroupInvoke,
                    messageAreaLinkExp,
                    stringToTextInvoke
                });

                AIntConstExp     intConst1         = new AIntConstExp(new TIntegerLiteral("1"));
                AIntConstExp     intConst2         = new AIntConstExp(new TIntegerLiteral("0"));
                ABinopExp        binop             = new ABinopExp(intConst1, new ADivideBinop(new TDiv("/")), intConst2);
                ASimpleInvokeExp intToStringInvoke = new ASimpleInvokeExp(new TIdentifier("IntToString"),
                                                                          new ArrayList()
                {
                    binop
                });

                innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), displayMessageInvoke));
                innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), intToStringInvoke));
                //innerBlock.GetStatements().Add(new AVoidReturnStm(new TReturn("return")));

                elseBranch = new ABlockStm(new TLBrace("{"), innerBlock);


                finalTrans.data.SimpleMethodLinks[playerGroupInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == playerGroupInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[stringToTextInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == stringToTextInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[displayMessageInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == displayMessageInvoke.GetName().Text);
                finalTrans.data.SimpleMethodLinks[intToStringInvoke] =
                    finalTrans.data.Libraries.Methods.First(m => m.GetName().Text == intToStringInvoke.GetName().Text);
                finalTrans.data.FieldLinks[messageAreaLink] =
                    finalTrans.data.Libraries.Fields.First(m => m.GetName().Text == messageAreaLink.GetName().Text);

                finalTrans.data.ExpTypes[playerGroupInvoke] =
                    finalTrans.data.SimpleMethodLinks[playerGroupInvoke].GetReturnType();
                finalTrans.data.LvalueTypes[messageAreaLink]     =
                    finalTrans.data.ExpTypes[messageAreaLinkExp] =
                        finalTrans.data.FieldLinks[messageAreaLink].GetType();
                finalTrans.data.ExpTypes[stringToTextInvoke] =
                    finalTrans.data.SimpleMethodLinks[stringToTextInvoke].GetReturnType();
                finalTrans.data.ExpTypes[stringConst]           =
                    finalTrans.data.ExpTypes[intToStringInvoke] = new ANamedType(new TIdentifier("string"), null);
                finalTrans.data.ExpTypes[displayMessageInvoke]  = new AVoidType();

                finalTrans.data.ExpTypes[intConst1]     =
                    finalTrans.data.ExpTypes[intConst2] =
                        finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("int"), null);
            }

            foreach (AMethodDecl method in methods)
            {
                /*  * if (delegate == "...")
                 * {
                 *    Foo(...);
                 * }
                 * else if (delegate == "...")
                 * {
                 *    Bar(..., GetPointerPart(<reciever>);
                 * }
                 * else if(...)
                 * ...
                 */
                AABlock          innerBlock = new AABlock(new ArrayList(), new TRBrace("}"));
                ASimpleInvokeExp invoke     = new ASimpleInvokeExp(new TIdentifier(method.GetName().Text), new ArrayList());
                for (int i = 0; i < node.GetArgs().Count; i++)
                {
                    PExp arg = (PExp)node.GetArgs()[i];
                    invoke.GetArgs().Add(Util.MakeClone(arg, finalTrans.data));
                }
                //If we have a struct method, add the pointer from the delegate
                if (finalTrans.data.StructMethods.Any(str => str.Value.Contains(method)))
                {
                    AStructDecl      targetStr        = finalTrans.data.StructMethods.First(str => str.Value.Contains(method)).Key;
                    AMethodDecl      getPointerDecl   = GetPointerMethod(targetStr.GetDimention() != null);
                    ASimpleInvokeExp getPointerInvoke = new ASimpleInvokeExp(new TIdentifier("renameMe"), new ArrayList()
                    {
                        Util.MakeClone(node.GetReceiver(), data)
                    });
                    invoke.GetArgs().Add(getPointerInvoke);

                    finalTrans.data.SimpleMethodLinks[getPointerInvoke] = getPointerDecl;
                    finalTrans.data.ExpTypes[getPointerInvoke]          = getPointerDecl.GetReturnType();
                }

                finalTrans.data.SimpleMethodLinks[invoke] = method;
                finalTrans.data.ExpTypes[invoke]          = method.GetReturnType();

                if (leftSide == null)
                {
                    innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), invoke));
                }
                else
                {
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), Util.MakeClone(leftSide, finalTrans.data), invoke);
                    finalTrans.data.ExpTypes[assignment] = finalTrans.data.ExpTypes[invoke];
                    innerBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));
                }
                ALocalLvalue    methodPartLink    = new ALocalLvalue(new TIdentifier("methodPart"));
                ALvalueExp      methodPartLinkExp = new ALvalueExp(methodPartLink);
                AStringConstExp stringConst       = new AStringConstExp(new TStringLiteral("\"" + GetName(method) + "\""));
                finalTrans.data.LocalLinks[methodPartLink]      = methodPartDecl;
                finalTrans.data.LvalueTypes[methodPartLink]     =
                    finalTrans.data.ExpTypes[methodPartLinkExp] =
                        finalTrans.data.ExpTypes[stringConst]   = new ANamedType(new TIdentifier("string"), null);


                ABinopExp binop = new ABinopExp(methodPartLinkExp, new AEqBinop(new TEq("==")), stringConst);
                finalTrans.data.ExpTypes[binop] = new ANamedType(new TIdentifier("bool"), null);

                AIfThenElseStm ifThenElse = new AIfThenElseStm(new TLParen("("), binop, new ABlockStm(new TLBrace("{"), innerBlock), elseBranch);

                elseBranch = new ABlockStm(new TLBrace("{"), new AABlock(new ArrayList()
                {
                    ifThenElse
                }, new TRBrace("}")));
            }

            block.GetStatements().Add(elseBranch);
        }
        public static List <AABlock> Inline(ASimpleInvokeExp node, FinalTransformations finalTrans)
        {
            /*if (Util.GetAncestor<AMethodDecl>(node) != null && Util.GetAncestor<AMethodDecl>(node).GetName().Text == "UIChatFrame_LeaveChannel")
             *  node = node;*/

            SharedData data = finalTrans.data;
            //If this node is inside the condition of a while, replace it with a new local var,
            //make a clone before the while, one before each continue in the while, and one at the end of the while
            //(unless the end is a return or break)
            AABlock pBlock;

            if (Util.HasAncestor <AWhileStm>(node))
            {
                AWhileStm whileStm = Util.GetAncestor <AWhileStm>(node);
                if (Util.IsAncestor(node, whileStm.GetCondition()))
                {
                    List <ASimpleInvokeExp> toInline = new List <ASimpleInvokeExp>();
                    //Above while
                    AALocalDecl replaceVarDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                 Util.MakeClone(data.ExpTypes[node], data),
                                                                 new TIdentifier("whileVar"), null);
                    ALocalLvalue replaceVarRef    = new ALocalLvalue(new TIdentifier("whileVar"));
                    ALvalueExp   replaceVarRefExp = new ALvalueExp(replaceVarRef);
                    data.LocalLinks[replaceVarRef]  = replaceVarDecl;
                    data.ExpTypes[replaceVarRefExp] = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                    node.ReplaceBy(replaceVarRefExp);
                    replaceVarDecl.SetInit(node);
                    pBlock = (AABlock)whileStm.Parent();
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(whileStm), new ALocalDeclStm(new TSemicolon(";"), replaceVarDecl));
                    toInline.Add(node);


                    //In the end of the while
                    PStm lastStm = whileStm.GetBody();
                    while (lastStm is ABlockStm)
                    {
                        AABlock block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        if (block.GetStatements().Count == 0)
                        {
                            lastStm = null;
                            break;
                        }
                        lastStm = (PStm)block.GetStatements()[block.GetStatements().Count - 1];
                    }
                    if (lastStm == null || !(lastStm is AValueReturnStm || lastStm is AVoidReturnStm || lastStm is ABreakStm))
                    {
                        lastStm = whileStm.GetBody();
                        AABlock block;
                        if (lastStm is ABlockStm)
                        {
                            block = (AABlock)((ABlockStm)lastStm).GetBlock();
                        }
                        else
                        {
                            block = new AABlock(new ArrayList(), new TRBrace("}"));
                            block.GetStatements().Add(lastStm);
                            whileStm.SetBody(new ABlockStm(new TLBrace("{"), block));
                        }

                        replaceVarRef = new ALocalLvalue(new TIdentifier("whileVar"));
                        ASimpleInvokeExp clone = (ASimpleInvokeExp)Util.MakeClone(node, data);
                        toInline.Add(clone);
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), replaceVarRef, clone);
                        data.LocalLinks[replaceVarRef] = replaceVarDecl;
                        data.ExpTypes[assignment]      = data.LvalueTypes[replaceVarRef] = replaceVarDecl.GetType();
                        block.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));
                    }

                    //After each continue
                    CloneBeforeContinue cloner = new CloneBeforeContinue(node, replaceVarDecl, data);
                    whileStm.GetBody().Apply(cloner);
                    toInline.AddRange(cloner.replacementExpressions);
                    List <AABlock> visitBlocks = new List <AABlock>();
                    foreach (ASimpleInvokeExp invoke in toInline)
                    {
                        visitBlocks.AddRange(Inline(invoke, finalTrans));
                    }
                    return(visitBlocks);
                }
            }



            AMethodDecl           decl = finalTrans.data.SimpleMethodLinks[node];
            FindAssignedToFormals assignedToFormalsFinder = new FindAssignedToFormals(finalTrans.data);

            decl.Apply(assignedToFormalsFinder);
            List <AALocalDecl> assignedToFormals = assignedToFormalsFinder.AssignedFormals;


            /*
             * inline int foo(int a)
             * {
             *      int b = 2;
             *      int c;
             *      ...
             *      while(...)
             *      {
             *          ...
             *          break;
             *          ...
             *          return c;
             *      }
             *      ...
             *      return 2;
             * }
             *
             * bar(foo(<arg for a>));
             * ->
             *
             * {
             *      bool inlineMethodReturned = false;
             *      int inlineReturner;
             *      int a = <arg for a>;
             *      while (!inlineMethodReturned)
             *      {
             *          int b = 2;
             *          int c;
             *          ...
             *          while(...)
             *          {
             *              ...
             *              break
             *              ...
             *              inlineReturner = c;
             *              inlineMethodReturned = true;
             *              break;
             *          }
             *          if (inlineMethodReturned)
             *          {
             *              break;
             *          }
             *          ...
             *          inlineReturner = 2;
             *          inlineMethodReturned = true;
             *          break;
             *          break;
             *      }
             *      bar(inlineReturner);
             * }
             *
             *
             */


            AABlock outerBlock = new AABlock();
            PExp    exp        = new ABooleanConstExp(new AFalseBool());

            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            AALocalDecl hasMethodReturnedVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new ANamedType(new TIdentifier("bool"), null),
                                                               new TIdentifier("hasInlineReturned"), exp);

            finalTrans.data.GeneratedVariables.Add(hasMethodReturnedVar);
            PStm stm = new ALocalDeclStm(new TSemicolon(";"), hasMethodReturnedVar);

            outerBlock.GetStatements().Add(stm);

            AALocalDecl methodReturnerVar = null;

            if (!(decl.GetReturnType() is AVoidType))
            {
                methodReturnerVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(decl.GetReturnType(), finalTrans.data),
                                                    new TIdentifier("inlineReturner"), null);
                stm = new ALocalDeclStm(new TSemicolon(";"), methodReturnerVar);
                outerBlock.GetStatements().Add(stm);
            }

            AABlock afterBlock = new AABlock();

            //A dictionary from the formals of the inline method to a cloneable replacement lvalue
            Dictionary <AALocalDecl, PLvalue> Parameters    = new Dictionary <AALocalDecl, PLvalue>();
            Dictionary <AALocalDecl, PExp>    ParameterExps = new Dictionary <AALocalDecl, PExp>();

            for (int i = 0; i < decl.GetFormals().Count; i++)
            {
                AALocalDecl formal = (AALocalDecl)decl.GetFormals()[i];
                PExp        arg    = (PExp)node.GetArgs()[0];
                PLvalue     lvalue;
                //if ref, dont make a new var
                if (formal.GetRef() != null && arg is ALvalueExp)
                {
                    arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                    arg.Parent().RemoveChild(arg);
                    lvalue = ((ALvalueExp)arg).GetLvalue();
                }
                else if (!assignedToFormals.Contains(formal) && Util.IsLocal(arg, finalTrans.data))
                {
                    lvalue = new ALocalLvalue(new TIdentifier("I hope I dont make it"));
                    finalTrans.data.LvalueTypes[lvalue] = formal.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = formal;
                    ParameterExps[formal] = arg;
                    arg.Parent().RemoveChild(arg);
                }
                else
                {
                    AAssignmentExp assExp = null;
                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        arg.Apply(new MoveMethodDeclsOut("inlineVar", finalTrans.data));
                        lvalue = ((ALvalueExp)arg).GetLvalue();
                        assExp = new AAssignmentExp(new TAssign("="), lvalue, null);
                        finalTrans.data.ExpTypes[assExp] = finalTrans.data.LvalueTypes[lvalue];
                        arg.Parent().RemoveChild(arg);
                        arg = null;
                    }
                    AALocalDecl parameter = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data),
                                                            new TIdentifier(formal.GetName().Text),
                                                            arg);
                    stm = new ALocalDeclStm(new TSemicolon(";"), parameter);
                    outerBlock.GetStatements().Add(stm);

                    lvalue = new ALocalLvalue(new TIdentifier(parameter.GetName().Text));
                    finalTrans.data.LvalueTypes[lvalue] = parameter.GetType();
                    finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = parameter;


                    if (formal.GetOut() != null)
                    {
                        //Dont initialize with arg, but assign arg after
                        ALvalueExp lvalueExp = new ALvalueExp(Util.MakeClone(lvalue, finalTrans.data));
                        finalTrans.data.ExpTypes[lvalueExp] = finalTrans.data.LvalueTypes[lvalue];
                        assExp.SetExp(lvalueExp);
                        afterBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assExp));
                    }
                }
                Parameters.Add(formal, lvalue);
            }

            AABlock innerBlock = (AABlock)decl.GetBlock().Clone();

            exp = new ABooleanConstExp(new ATrueBool());
            finalTrans.data.ExpTypes[exp] = new ANamedType(new TIdentifier("bool"), null);
            ABlockStm innerBlockStm = new ABlockStm(new TLBrace("{"), innerBlock);

            bool needWhile = CheckIfWhilesIsNeeded.IsWhileNeeded(decl.GetBlock());

            if (needWhile)
            {
                stm = new AWhileStm(new TLParen("("), exp, innerBlockStm);
            }
            else
            {
                stm = innerBlockStm;
            }
            outerBlock.GetStatements().Add(stm);

            outerBlock.GetStatements().Add(new ABlockStm(new TLBrace("{"), afterBlock));

            //Clone method contents to inner block.
            CloneMethod cloneFixer = new CloneMethod(finalTrans, Parameters, ParameterExps, innerBlockStm);

            decl.GetBlock().Apply(cloneFixer);
            foreach (KeyValuePair <PLvalue, PExp> pair in cloneFixer.ReplaceUsAfter)
            {
                PLvalue    lvalue       = pair.Key;
                PExp       replacement  = Util.MakeClone(pair.Value, finalTrans.data);
                ALvalueExp lvalueParent = (ALvalueExp)lvalue.Parent();
                lvalueParent.ReplaceBy(replacement);
            }
            innerBlockStm.Apply(new FixTypes(finalTrans.data));

            innerBlock.Apply(new FixReturnsAndWhiles(hasMethodReturnedVar, methodReturnerVar, finalTrans.data, needWhile));

            GetNonBlockStm stmFinder = new GetNonBlockStm(false);

            innerBlock.Apply(stmFinder);
            if (needWhile && (stmFinder.Stm == null || !(stmFinder.Stm is ABreakStm)))
            {
                innerBlock.GetStatements().Add(new ABreakStm(new TBreak("break")));
            }

            //Insert before current statement
            ABlockStm outerBlockStm = new ABlockStm(new TLBrace("{"), outerBlock);

            PStm pStm = Util.GetAncestor <PStm>(node);

            pBlock = (AABlock)pStm.Parent();

            pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), outerBlockStm);

            if (node.Parent() == pStm && pStm is AExpStm)
            {
                pBlock.RemoveChild(pStm);
            }
            else
            {
                PLvalue lvalue = new ALocalLvalue(new TIdentifier(methodReturnerVar.GetName().Text));
                finalTrans.data.LvalueTypes[lvalue] = methodReturnerVar.GetType();
                finalTrans.data.LocalLinks[(ALocalLvalue)lvalue] = methodReturnerVar;
                exp = new ALvalueExp(lvalue);
                finalTrans.data.ExpTypes[exp] = methodReturnerVar.GetType();

                node.ReplaceBy(exp);
            }
            return(new List <AABlock>()
            {
                outerBlock
            });
        }
示例#11
0
        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);
        }
        public override void CaseANonstaticInvokeExp(ANonstaticInvokeExp node)
        {
            PExp  reciever = node.GetReceiver();
            PType type     = finalTrans.data.ExpTypes[reciever];

            //If the reciever is not a var, put it in a new var.
            if (!(reciever is ALvalueExp))
            {
                AALocalDecl  localDecl   = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier("nonstaticInvokeVar"), reciever);
                ALocalLvalue localRef    = new ALocalLvalue(new TIdentifier("nonstaticInvokeVar"));
                ALvalueExp   localRefExp = new ALvalueExp(localRef);
                node.SetReceiver(localRefExp);
                PStm    pStm   = Util.GetAncestor <PStm>(node);
                AABlock pBlock = (AABlock)pStm.Parent();
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl));
                reciever = localRefExp;

                data.LvalueTypes[localRef]     =
                    data.ExpTypes[localRefExp] = type;
                data.LocalLinks[localRef]      = localDecl;

                localDecl.Apply(this);
            }

            if (type is ANamedType && finalTrans.data.StructTypeLinks.ContainsKey((ANamedType)type))
            {
                //ANamedType type = (ANamedType) finalTrans.data.ExpTypes[reciever];
                if (finalTrans.data.StructTypeLinks[(ANamedType)type].GetClassToken() != null)
                {
                    //Pass the pointer
                    ALvalueExp     lvalueExp     = (ALvalueExp)reciever;
                    APointerLvalue pointerLvalue = (APointerLvalue)lvalueExp.GetLvalue();
                    reciever = pointerLvalue.GetBase();
                }

                AMethodDecl      method       = finalTrans.data.StructMethodLinks[node];
                ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp();
                simpleInvoke.SetName(node.GetName());
                PExp[] exps = new PExp[node.GetArgs().Count];
                node.GetArgs().CopyTo(exps, 0);
                foreach (PExp exp in exps)
                {
                    simpleInvoke.GetArgs().Add(exp);
                }
                simpleInvoke.GetArgs().Add(reciever);
                node.ReplaceBy(simpleInvoke);
                finalTrans.data.SimpleMethodLinks[simpleInvoke] = method;
                finalTrans.data.StructMethodLinks.Remove(node);
                finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType();
                finalTrans.data.ExpTypes.Remove(node);
                simpleInvoke.Apply(this);
            }
            else
            {//Enrichment
                /*AEnrichmentDecl enrichment = finalTrans.data.EnrichmentTypeLinks[type];
                 *
                 * foreach (AEnrichmentDecl enrichmentDecl in finalTrans.data.Enrichments)
                 * {
                 *  if (Util.IsVisible(node, enrichmentDecl) &&
                 *      Util.IsDeclVisible(enrichmentDecl, Util.GetAncestor<AASourceFile>(node)) &&
                 *      Util.TypesEqual(type, enrichmentDecl.GetType(), finalTrans.data))
                 *  {
                 *      enrichment = enrichmentDecl;
                 *      break;
                 *  }
                 * }
                 * if (enrichment == null)
                 * {
                 *  finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), "TransFormMethodDecls.NonStaticInvoke: Expected enrichment - this is a bug. It should have been caught earlier"));
                 *  throw new ParserException(node.GetName(), "");
                 * }*/
                AMethodDecl      method       = finalTrans.data.StructMethodLinks[node];
                ASimpleInvokeExp simpleInvoke = new ASimpleInvokeExp();
                simpleInvoke.SetName(node.GetName());
                PExp[] exps = new PExp[node.GetArgs().Count];
                node.GetArgs().CopyTo(exps, 0);
                foreach (PExp exp in exps)
                {
                    simpleInvoke.GetArgs().Add(exp);
                }
                simpleInvoke.GetArgs().Add(reciever);
                node.ReplaceBy(simpleInvoke);
                finalTrans.data.SimpleMethodLinks[simpleInvoke] = method;
                finalTrans.data.StructMethodLinks.Remove(node);
                finalTrans.data.ExpTypes[simpleInvoke] = method.GetReturnType();
                finalTrans.data.ExpTypes.Remove(node);
                simpleInvoke.Apply(this);
            }
        }