Exemplo n.º 1
0
        public override void OutAFieldLvalue(AFieldLvalue node)
        {
            if (folding)
            {
                AFieldDecl field = data.FieldLinks[node];
                //Must be int and must be const
                if (!(field.GetType() is ANamedType && ((ANamedType)field.GetType()).IsPrimitive("int")))
                {
                    errors.Add(
                        new ErrorCollection.Error(node.GetName(),
                                                  LocRM.GetString("ErrorText59"),
                                                  false, new ErrorCollection.Error(field.GetName(), LocRM.GetString("ErrorText60"))), true);
                    throw new ParserException(node.GetName(), "TypeLinking.OutAFieldLvalue");
                }

                if (field.GetConst() == null)
                {
                    if (!isANewExp)
                    {
                        errors.Add(
                            new ErrorCollection.Error(node.GetName(),
                                                      LocRM.GetString("ErrorText61"),
                                                      false), true);
                        throw new ParserException(node.GetName(), "TypeLinking.OutAFieldLvalue");
                    }
                }
                if (field.GetInit() == null)//An error will be given earlier - constant fields must have an initializer
                {
                    throw new ParserException(node.GetName(), "TypeLinking.OutAFieldLvalue");
                }
                field.GetInit().Apply(this);
            }
            else
            {
                base.OutAFieldLvalue(node);
            }
        }
Exemplo n.º 2
0
 public override void OutAFieldLvalue(AFieldLvalue node)
 {
     node.GetName().Text = finalTrans.data.FieldLinks[node].GetName().Text;
 }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
            public override void CaseAFieldLvalue(AFieldLvalue node)
            {
                Item currentFile = GetIncludeItem(node);

                //If the field is in a moved field, refference that field instead
                if (Util.GetAncestor <AFieldDecl>(node) != null)
                {
                    Item i = allItems.OfType <FieldItem>().FirstOrDefault(item => item.FieldDecl == Util.GetAncestor <AFieldDecl>(node));
                    if (i != null)
                    {
                        currentFile = i;
                    }
                }

                AFieldDecl decl     = finalTrans.data.FieldLinks[node];
                Item       declItem = ((Item)allItems.OfType <FieldItem>().FirstOrDefault(item => item.FieldDecl == decl)) ??
                                      allItems.OfType <IncludeItem>().First(
                    item => item.Current == Util.GetAncestor <AASourceFile>(decl));
                List <Item> cPath = currentFile.Path;
                List <Item> dPath = declItem.Path;

                bool movedIt = false;

                for (int i = 0; i < Math.Min(cPath.Count, dPath.Count); i++)
                {
                    if (cPath[i] != dPath[i])
                    {
                        //We have a fork. make sure that the field is visible
                        int cI = cPath[i - 1].Children.IndexOf(cPath[i]);
                        int dI = dPath[i - 1].Children.IndexOf(dPath[i]);

                        if (dI < cI)
                        {//The decl is okay
                            break;
                        }

                        //Move the decl up
                        if (declItem is FieldItem)
                        {
                            declItem.Parent.Children.Remove(declItem);
                            declItem.Parent = cPath[i - 1];
                        }
                        else
                        {
                            declItem = new FieldItem(decl, cPath[i - 1], new List <Item>());
                            allItems.Add(declItem);
                        }
                        cPath[i - 1].Children.Insert(cI, declItem);
                        movedIt = true;
                        break;
                    }
                    if (i == cPath.Count - 1)
                    {
                        if (i == dPath.Count - 1)
                        {
                            //The decl and use is in same file. Ensure that the decl is before
                            if (Util.TokenLessThan(decl.GetName(), node.GetName()))
                            {
                                break;
                            }
                            //Add the decl item
                            declItem = new FieldItem(decl, cPath[i], new List <Item>());
                            allItems.Add(declItem);
                            cPath[i].Children.Add(declItem);
                            movedIt = true;
                            break;
                        }
                        else
                        {
                            //The decl is included here or somewhere deeper. But above the use
                            break;
                        }
                    }
                    else if (i == dPath.Count - 1)
                    {
                        //We have reached the file where the decl is, but the use is included deeper, so it is above. Insert decl
                        int cI = cPath[i].Children.IndexOf(cPath[i + 1]);
                        declItem = new FieldItem(decl, cPath[i], new List <Item>());
                        allItems.Add(declItem);
                        cPath[i].Children.Insert(cI, declItem);
                        movedIt = true;
                        break;
                    }
                }

                //In case we have a struct type field, we must make sure the struct is still on top
                if (movedIt)
                {
                    CaseAFieldDecl(decl);
                }
                base.CaseAFieldLvalue(node);
            }