public static void Apply(AAProgram ast, FinalTransformations finalTrans)
        {
            //Build list of file dependacies
            Phase1 phase1 = new Phase1(finalTrans);
            ast.Apply(phase1);
            var dependancies = phase1.dependancies;
            if (dependancies.Keys.Count == 0) return;
            AASourceFile root = Util.GetAncestor<AASourceFile>(finalTrans.mainEntry) ??
                                dependancies.Keys.FirstOrDefault(file => !file.GetName().Text.Contains("\\")) ??
                                dependancies.Keys.First(file => true);

            //Remove files unreachable from root
            //On second thought, dont. there might be static refferences the other way which needs to be included
            /*{
                List<AASourceFile> reachable = GetReachable(root, dependancies);
                AASourceFile[] keys = new AASourceFile[dependancies.Count];
                dependancies.Keys.CopyTo(keys, 0);
                foreach (AASourceFile key in keys)
                {
                    if (!reachable.Contains(key))
                        dependancies.Remove(key);
                }
            }*/

            //Push common depancies up
            /*
             * root -> (item1 -> (item3), item2 -> (item4 -> (item3)))
             *
             * root -> (item3, item1, item2 -> (item4))
             */

            //Add unreachable to the root
            while (true)
            {
                List<AASourceFile> reachable = new List<AASourceFile>();
                GetReachable(root, dependancies, ref reachable);
                if (reachable.Count == dependancies.Count + (reachable.Contains(null) ? 1 : 0)) break;
                AASourceFile[] keys = new AASourceFile[dependancies.Count];
                dependancies.Keys.CopyTo(keys, 0);
                foreach (AASourceFile key in keys)
                {
                    if (!reachable.Contains(key))
                    {
                        AASourceFile k = key;
                        //See if you can find another unreachable file which need this file
                        Dictionary<AASourceFile, int> decendantCounts = new Dictionary<AASourceFile, int>();
                        decendantCounts.Add(k, CountDecendants(k, dependancies, new List<AASourceFile>()));
                        while (true)
                        {
                            AASourceFile file = null;
                            foreach (KeyValuePair<AASourceFile, List<AASourceFile>> dependancy in dependancies)
                            {
                                if (decendantCounts.ContainsKey(dependancy.Key))
                                    continue;
                                if (!dependancy.Value.Contains(k))
                                    continue;
                                file = dependancy.Key;
                                break;
                            }

                            //AASourceFile file = dependancies.FirstOrDefault(item => item.Value.Contains(k)).Key;
                            if (file == null) break;
                            decendantCounts.Add(file, CountDecendants(file, dependancies, new List<AASourceFile>()));
                            k = file;
                        }
                        foreach (KeyValuePair<AASourceFile, int> decendantItem in decendantCounts)
                        {
                            if (decendantItem.Value > decendantCounts[k])
                                k = decendantItem.Key;
                        }

                        dependancies[root].Add(k);
                        break;
                    }
                }
            }
            //It is moved down here because cycles are not removed in unreachable
            RemoveCycles(root, dependancies, new List<AASourceFile> { root });

            //Convert to tree to make it easier
            List<Item> allItems = new List<Item>();
            IncludeItem rootIncludeItem = MakeTree(root, dependancies, allItems, null);
            bool[] removed = new bool[allItems.Count];
            for (int i = 0; i < removed.Length; i++)
                removed[i] = false;
            int removedCount = 0;

            //Ensure that each include is only included one place
            for (int i = 0; i < allItems.Count; i++)
            {
                if (removed[i])
                    continue;

                IncludeItem item1 = (IncludeItem)allItems[i];
                for (int j = i + 1; j < allItems.Count; j++)
                {
                    if (removed[j])
                        continue;
                    IncludeItem item2 = (IncludeItem)allItems[j];

                    if (item1.Current == item2.Current)
                    {
                        List<Item> path1 = item1.Path;
                        List<Item> path2 = item2.Path;

                        for (int k = 0; k < Math.Min(path1.Count, path2.Count); k++)
                        {
                            if (path1[k] != path2[k])
                            {

                                int insertAt = Math.Min(path1[k - 1].Children.IndexOf(path1[k]),
                                                        path2[k - 1].Children.IndexOf(path2[k]));

                                item1.Parent.Children.Remove(item1);
                                LinkedList<IncludeItem> toRemove = new LinkedList<IncludeItem>();
                                toRemove.AddLast(item2);
                                while (toRemove.Count > 0)
                                {
                                    IncludeItem item = toRemove.First.Value;
                                    toRemove.RemoveFirst();
                                    item.Parent.Children.Remove(item);
                                    //allItems.Remove(item);
                                    removedCount++;
                                    removed[item.ListIndex] = true;
                                    foreach (IncludeItem child in item.Children)
                                    {
                                        toRemove.AddLast(child);
                                    }
                                }
                                //j--;

                                path1[k - 1].Children.Insert(insertAt, item1);
                                item1.Parent = path1[k - 1];

                                break;
                            }
                        }
                    }
                }
            }

            List<Item> newAllItems = new List<Item>(allItems.Count - removedCount);
            for (int i = 0; i < allItems.Count; i++)
                if (!removed[i])
                    newAllItems.Add(allItems[i]);
            allItems = newAllItems;

            //Move the null node to nr [0]
            foreach (IncludeItem item in allItems)
            {
                if (item.Current == null)
                {
                    int itemIndex = item.Parent.Children.IndexOf(item);
                    Item item0 = item.Parent.Children[0];
                    item.Parent.Children[0] = item;
                    item.Parent.Children[itemIndex] = item0;
                    break;
                }
            }

            //Insert method decls and move structs & fields up as needed
            ast.Apply(new Phase2(finalTrans, allItems));

            //Insert the headers in the files

            if (Options.Compiler.OneOutputFile)
            {
                //for (int i = 0; i < allItems.Count; i++)
                int i = 0;
                while (allItems.Count > 0)
                {
                    if (allItems[i] is IncludeItem)
                    {
                        IncludeItem includeItem = (IncludeItem) allItems[i];
                        //Dont want the standard lib
                        if (includeItem.Current == null)
                        {
                            i++;
                            continue;
                        }
                        //If it has children with children, then pick another first
                        if (includeItem.Children.Any(child => child.Children.Count > 0))
                        {
                            i++;
                            continue;
                        }
                        if (includeItem.Children.Count == 0)
                        {
                            if (includeItem.Parent == null)
                                break;
                            i++;
                            continue;
                        }
                        i = 0;
                        //Put all children into this
                        while (includeItem.Children.Count > 0)
                        {
                            int childNr = includeItem.Children.Count - 1;
                            allItems.Remove(includeItem.Children[childNr]);
                            if (includeItem.Children[childNr] is FieldItem)
                            {
                                FieldItem aItem = (FieldItem)includeItem.Children[childNr];
                                Node node = aItem.FieldDecl;
                                node.Parent().RemoveChild(node);
                                includeItem.Current.GetDecl().Insert(0, node);
                            }
                            else if (includeItem.Children[childNr] is StructItem)
                            {
                                StructItem aItem = (StructItem)includeItem.Children[childNr];
                                Node node = aItem.StructDecl;
                                node.Parent().RemoveChild(node);
                                includeItem.Current.GetDecl().Insert(0, node);
                            }
                            else if (includeItem.Children[childNr] is MethodDeclItem)
                            {
                                MethodDeclItem aItem = (MethodDeclItem)includeItem.Children[childNr];
                                AMethodDecl aNode = new AMethodDecl();
                                if (aItem.RealDecl.GetStatic() != null) aNode.SetStatic(new TStatic("static"));
                                aNode.SetReturnType(Util.MakeClone(aItem.RealDecl.GetReturnType(), finalTrans.data));
                                aNode.SetName(new TIdentifier(aItem.RealDecl.GetName().Text));
                                foreach (AALocalDecl formal in aItem.RealDecl.GetFormals())
                                {
                                    AALocalDecl clone = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), null);
                                    aNode.GetFormals().Add(clone);
                                }
                                includeItem.Current.GetDecl().Insert(0, aNode);
                            }
                            else if (includeItem.Children[childNr] is IncludeItem)
                            {
                                IncludeItem aChild = (IncludeItem)includeItem.Children[childNr];
                                if (aChild.Current == null)
                                {
                                    AIncludeDecl node = new AIncludeDecl(new TInclude("include"),
                                                        new TStringLiteral("\"TriggerLibs/NativeLib\""));
                                    includeItem.Current.GetDecl().Insert(0, node);
                                }
                                else
                                {
                                    PDecl[] decls = new PDecl[aChild.Current.GetDecl().Count];
                                    aChild.Current.GetDecl().CopyTo(decls, 0);
                                    for (int k = decls.Length - 1; k >= 0; k--)
                                    {
                                        includeItem.Current.GetDecl().Insert(0, decls[k]);
                                    }
                                    aChild.Current.Parent().RemoveChild(aChild.Current);
                                    //i = -1;
                                }
                            }
                            includeItem.Children.RemoveAt(childNr);
                        }
                    }
                }
            }
            else
                foreach (IncludeItem includeItem in allItems.OfType<IncludeItem>())
                {
                    for (int i = includeItem.Children.Count - 1; i >= 0; i--)
                    {
                        Node node;
                        if (includeItem.Children[i] is IncludeItem)
                        {
                            IncludeItem aItem = (IncludeItem) includeItem.Children[i];
                            node = new AIncludeDecl(new TInclude("include"),
                                                    new TStringLiteral("\"" + (aItem.Current == null ? "TriggerLibs/NativeLib" : aItem.Current.GetName().Text.Replace("\\", "/")) + "\""));
                            if (aItem.Current == null && finalTrans.mainEntry != null)
                            {
                                //Search for user defined initlib
                                bool foundInvoke = false;
                                foreach (ASimpleInvokeExp invokeExp in finalTrans.data.SimpleMethodLinks.Keys)
                                {
                                    if(invokeExp.GetName().Text == "libNtve_InitLib" && invokeExp.GetArgs().Count == 0)
                                    {
                                        /*finalTrans.errors.Add(new ErrorCollection.Error(invokeExp.GetName(),
                                                                                        Util.GetAncestor<AASourceFile>(
                                                                                            invokeExp),
                                                                                        "You are invoking libNtve_InitLib() yourself somewhere. It will not be auto inserted.",
                                                                                        true));*/
                                        foundInvoke = true;
                                        break;
                                    }
                                }

                                if (!foundInvoke)
                                {
                                    //Init the lib
                                    ASimpleInvokeExp initExp = new ASimpleInvokeExp();
                                    initExp.SetName(new TIdentifier("libNtve_InitLib"));
                                    finalTrans.data.ExpTypes[initExp] = new AVoidType(new TVoid("void"));
                                    foreach (AMethodDecl method in finalTrans.data.Libraries.Methods)
                                    {
                                        if (method.GetName().Text == "libNtve_InitLib" && method.GetFormals().Count == 0)
                                        {
                                            finalTrans.data.SimpleMethodLinks[initExp] = method;
                                        }
                                    }
                                    AABlock block = (AABlock) finalTrans.mainEntry.GetBlock();
                                    block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), initExp));
                                }
                            }
                        }
                        else if (includeItem.Children[i] is FieldItem)
                        {
                            FieldItem aItem = (FieldItem)includeItem.Children[i];
                            node = aItem.FieldDecl;
                            node.Parent().RemoveChild(node);
                        }
                        else if (includeItem.Children[i] is StructItem)
                        {
                            StructItem aItem = (StructItem)includeItem.Children[i];
                            node = aItem.StructDecl;
                            node.Parent().RemoveChild(node);
                        }
                        else if (includeItem.Children[i] is MethodDeclItem)
                        {
                            MethodDeclItem aItem = (MethodDeclItem)includeItem.Children[i];
                            AMethodDecl aNode = new AMethodDecl();
                            if (aItem.RealDecl.GetStatic() != null) aNode.SetStatic(new TStatic("static"));
                            aNode.SetReturnType(Util.MakeClone(aItem.RealDecl.GetReturnType(), finalTrans.data));
                            aNode.SetName(new TIdentifier(aItem.RealDecl.GetName().Text));
                            foreach (AALocalDecl formal in aItem.RealDecl.GetFormals())
                            {
                                AALocalDecl clone = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(formal.GetType(), finalTrans.data), new TIdentifier(formal.GetName().Text), null);
                                aNode.GetFormals().Add(clone);
                            }
                            node = aNode;
                        }
                        else
                            throw new Exception("FixIncludes.Apply: Unexpected item type");

                        includeItem.Current.GetDecl().Insert(0, node);
                    }
                }
        }
예제 #2
0
            public static AMethodDecl CreateResizeArrayMethod(Node node, PType baseType, SharedData data)
            {
                //Search already created stuff, and return that if present.
                //All non struct baseTypes get the simple version

                ANamedType aBaseType = null;
                AStructDecl structDecl = null;
                if (Util.IsBulkCopy(baseType))
                {
                    aBaseType = (ANamedType)baseType;
                    structDecl = data.StructTypeLinks[aBaseType];

                    if (resizeArrayMethods.ContainsKey(structDecl))
                        return resizeArrayMethods[structDecl];
                }
                else
                    if (simpleResizeArrayMethod != null)
                        return simpleResizeArrayMethod;

                //Create
                /*
                    void Resize(int newSize, string id)
                    {
                        int oldSize = DataTableGetInt(true, id + "\\Length");
                        while (oldSize > newSize)
                        {
                            //Delete everything up to now
                            oldSize = oldSize - 1;
                            DeleteStruct<name>(id + "[" + IntToString(oldSize) + "]");//If struct type
                            DataTableValueRemove(true, id + "[" + IntToString(oldSize) + "]");
                        }
                        DataTableSetInt(true, id + "\\Length", newSize);
                    }
                 */
                AALocalDecl newSizeFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                            new ANamedType(new TIdentifier("int"), null),
                                                            new TIdentifier("newSize"), null);
                AALocalDecl idFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                            new ANamedType(new TIdentifier("string"), null),
                                                            new TIdentifier("id"), null);

                AABlock methodBlock = new AABlock(new ArrayList(), new TRBrace("}"));

                //int oldSize = DataTableGetInt(true, id + "\\Length");
                ABooleanConstExp boolConstExp1 = new ABooleanConstExp(new ATrueBool());
                AStringConstExp stringConstExp1 = new AStringConstExp(new TStringLiteral("\"\\\\Length\""));
                ALocalLvalue idRef1 = new ALocalLvalue(new TIdentifier("id"));
                ALvalueExp idRef1Exp = new ALvalueExp(idRef1);
                ABinopExp binop1 = new ABinopExp(idRef1Exp, new APlusBinop(new TPlus("+")), stringConstExp1);
                ASimpleInvokeExp getSizeInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableGetInt"), new ArrayList(){boolConstExp1, binop1});
                AALocalDecl oldSizeDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                            new ANamedType(new TIdentifier("int"), null),
                                                            new TIdentifier("oldSize"), getSizeInvoke);
                methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), oldSizeDecl));

                //while (oldSize > newSize)
                ALocalLvalue oldSizeRef1 = new ALocalLvalue(new TIdentifier("oldSize"));
                ALvalueExp oldSizeRef1Exp = new ALvalueExp(oldSizeRef1);
                ALocalLvalue newSizeRef1 = new ALocalLvalue(new TIdentifier("newSize"));
                ALvalueExp newSizeRef1Exp = new ALvalueExp(newSizeRef1);
                ABinopExp binop2 = new ABinopExp(oldSizeRef1Exp, new AGtBinop(new TGt(">")), newSizeRef1Exp);
                AABlock whileBlock = new AABlock(new ArrayList(), new TRBrace("}"));
                methodBlock.GetStatements().Add(new AWhileStm(new TLParen("("), binop2,
                                                               new ABlockStm(new TLBrace("{"), whileBlock)));

                //oldSize = oldSize - 1;
                ALocalLvalue oldSizeRef2 = new ALocalLvalue(new TIdentifier("oldSize"));
                ALocalLvalue oldSizeRef3 = new ALocalLvalue(new TIdentifier("oldSize"));
                ALvalueExp oldSizeRef3Exp = new ALvalueExp(oldSizeRef3);
                AIntConstExp intConst1 = new AIntConstExp(new TIntegerLiteral("1"));
                ABinopExp binop3 = new ABinopExp(oldSizeRef3Exp, new AMinusBinop(new TMinus("-")), intConst1);
                AAssignmentExp assignment1 = new AAssignmentExp(new TAssign("="), oldSizeRef2, binop3);
                whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment1));

                //DeleteStruct<name>(id + "[" + IntToString(oldSize) + "]");//If struct type
                ALocalLvalue idRef2 = null;
                ALvalueExp idRef2Exp = null;
                AStringConstExp stringConstExp2 = null;
                AStringConstExp stringConstExp3 = null;
                ALocalLvalue oldSizeRef4 = null;
                ALvalueExp oldSizeRef4Exp = null;
                ASimpleInvokeExp intToString1 = null;
                ABinopExp binop4 = null;
                ABinopExp binop5 = null;
                ABinopExp binop6 = null;
                ASimpleInvokeExp deleteStructInvoke = null;
                if (aBaseType != null)
                {
                    idRef2 = new ALocalLvalue(new TIdentifier("id"));
                    idRef2Exp = new ALvalueExp(idRef2);
                    stringConstExp2 = new AStringConstExp(new TStringLiteral("\"[\""));
                    stringConstExp3 = new AStringConstExp(new TStringLiteral("\"]\""));
                    oldSizeRef4 = new ALocalLvalue(new TIdentifier("oldSize"));
                    oldSizeRef4Exp = new ALvalueExp(oldSizeRef4);
                    intToString1 = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList() { oldSizeRef4Exp });
                    binop4 = new ABinopExp(intToString1, new APlusBinop(new TPlus("+")), stringConstExp3);
                    binop5 = new ABinopExp(stringConstExp2, new APlusBinop(new TPlus("+")), binop4);
                    binop6 = new ABinopExp(idRef2Exp, new APlusBinop(new TPlus("+")), binop5);
                    deleteStructInvoke =
                        new ASimpleInvokeExp(new TIdentifier("DeleteStruct" + aBaseType.AsIdentifierString()),
                                             new ArrayList() { binop6 });
                    whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), deleteStructInvoke));
                }

                //DataTableValueRemove(true, id + "[" + IntToString(oldSize) + "]");
                ABooleanConstExp boolConstExp2 = new ABooleanConstExp(new ATrueBool());
                ALocalLvalue idRef3 = new ALocalLvalue(new TIdentifier("id"));
                ALvalueExp idRef3Exp = new ALvalueExp(idRef3);
                AStringConstExp stringConstExp4 = new AStringConstExp(new TStringLiteral("\"[\""));
                AStringConstExp stringConstExp5 = new AStringConstExp(new TStringLiteral("\"]\""));
                ALocalLvalue oldSizeRef5 = new ALocalLvalue(new TIdentifier("oldSize"));
                ALvalueExp oldSizeRef5Exp = new ALvalueExp(oldSizeRef5);
                ASimpleInvokeExp intToString2 = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList(){oldSizeRef5Exp});
                ABinopExp binop7 = new ABinopExp(intToString2, new APlusBinop(new TPlus("+")), stringConstExp5);
                ABinopExp binop8 = new ABinopExp(stringConstExp4, new APlusBinop(new TPlus("+")), binop7);
                ABinopExp binop9 = new ABinopExp(idRef3Exp, new APlusBinop(new TPlus("+")), binop8);
                ASimpleInvokeExp dataTableRemove = new ASimpleInvokeExp(new TIdentifier("DataTableValueRemove"),
                                                                        new ArrayList() {boolConstExp2, binop9});
                whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), dataTableRemove));

                //DataTableSetInt(true, id + "\\Length", newSize);
                ABooleanConstExp boolConstExp3 = new ABooleanConstExp(new ATrueBool());
                AStringConstExp stringConstExp6 = new AStringConstExp(new TStringLiteral("\"\\\\Length\""));
                ALocalLvalue idRef4 = new ALocalLvalue(new TIdentifier("id"));
                ALvalueExp idRef4Exp = new ALvalueExp(idRef4);
                ABinopExp binop10 = new ABinopExp(idRef4Exp, new APlusBinop(new TPlus("+")), stringConstExp6);
                ALocalLvalue newSizeRef2 = new ALocalLvalue(new TIdentifier("newSize"));
                ALvalueExp newSizeRef2Exp = new ALvalueExp(newSizeRef2);
                ASimpleInvokeExp setSizeInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSetInt"),
                                                                      new ArrayList()
                                                                          {boolConstExp3, binop10, newSizeRef2Exp});
                methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), setSizeInvoke));

                AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                         new AVoidType(new TVoid("void")),
                                                         new TIdentifier("ResizeArray"),
                                                         new ArrayList() { newSizeFormal, idFormal }, methodBlock);
                AASourceFile sourceFile = Util.GetAncestor<AASourceFile>(node);
                sourceFile.GetDecl().Add(method);
                data.Methods.Add(new SharedData.DeclItem<AMethodDecl>(sourceFile, method));

                data.LvalueTypes[oldSizeRef1] =
                    data.LvalueTypes[oldSizeRef2] =
                    data.LvalueTypes[oldSizeRef3] =
                    //data.LvalueTypes[oldSizeRef4] =
                    data.LvalueTypes[oldSizeRef5] =
                    data.ExpTypes[oldSizeRef1Exp] =
                    data.ExpTypes[oldSizeRef3Exp] =
                    //data.ExpTypes[oldSizeRef4Exp] =
                    data.ExpTypes[oldSizeRef5Exp] =
                    data.LvalueTypes[newSizeRef1] =
                    data.LvalueTypes[newSizeRef2] =
                    data.ExpTypes[newSizeRef1Exp] =
                    data.ExpTypes[newSizeRef2Exp] =
                    data.ExpTypes[binop3] =
                    data.ExpTypes[assignment1] =
                    data.ExpTypes[getSizeInvoke] = new ANamedType(new TIdentifier("int"), null);
                data.LvalueTypes[idRef1] =
                    //data.LvalueTypes[idRef2] =
                    data.LvalueTypes[idRef3] =
                    data.LvalueTypes[idRef4] =
                    data.ExpTypes[idRef1Exp] =
                    //data.ExpTypes[idRef2Exp] =
                    data.ExpTypes[idRef3Exp] =
                    data.ExpTypes[idRef4Exp] =
                    data.ExpTypes[stringConstExp1] =
                    //data.ExpTypes[stringConstExp2] =
                    //data.ExpTypes[stringConstExp3] =
                    data.ExpTypes[stringConstExp4] =
                    data.ExpTypes[stringConstExp5] =
                    data.ExpTypes[stringConstExp6] =
                    data.ExpTypes[binop1] =
                    //data.ExpTypes[binop4] =
                    //data.ExpTypes[binop5] =
                    //data.ExpTypes[binop6] =
                    data.ExpTypes[binop7] =
                    data.ExpTypes[binop8] =
                    data.ExpTypes[binop9] =
                    data.ExpTypes[binop10] =
                    //data.ExpTypes[intToString1] =
                    data.ExpTypes[intToString2] = new ANamedType(new TIdentifier("string"), null);
                data.ExpTypes[dataTableRemove] =
                    //data.ExpTypes[deleteStructInvoke] =
                    data.ExpTypes[setSizeInvoke] = new AVoidType(new TVoid("void"));
                data.ExpTypes[boolConstExp1] =
                    data.ExpTypes[boolConstExp2] =
                    data.ExpTypes[boolConstExp3] =
                    data.ExpTypes[binop2] = new ANamedType(new TIdentifier("bool"), null);

                data.LocalLinks[oldSizeRef1] =
                    data.LocalLinks[oldSizeRef2] =
                    data.LocalLinks[oldSizeRef3] =
                    data.LocalLinks[oldSizeRef5] = oldSizeDecl;
                data.LocalLinks[newSizeRef1] =
                    data.LocalLinks[newSizeRef2] = newSizeFormal;
                data.LocalLinks[idRef1] =
                    data.LocalLinks[idRef3] =
                    data.LocalLinks[idRef4] = idFormal;

                data.SimpleMethodLinks[getSizeInvoke] =
                    data.Libraries.Methods.First(m => m.GetName().Text == getSizeInvoke.GetName().Text);
                data.SimpleMethodLinks[setSizeInvoke] =
                    data.Libraries.Methods.First(m => m.GetName().Text == setSizeInvoke.GetName().Text);
                data.SimpleMethodLinks[dataTableRemove] =
                    data.Libraries.Methods.First(m => m.GetName().Text == dataTableRemove.GetName().Text);
                data.SimpleMethodLinks[intToString2] =
                    data.Libraries.Methods.First(m => m.GetName().Text == intToString2.GetName().Text);

                if (aBaseType == null)
                    return simpleResizeArrayMethod = method;

                data.LvalueTypes[oldSizeRef4] =
                    data.ExpTypes[oldSizeRef4Exp] = new ANamedType(new TIdentifier("int"), null);
                data.LvalueTypes[idRef2] =
                    data.ExpTypes[idRef2Exp] =
                    data.ExpTypes[stringConstExp2] =
                    data.ExpTypes[stringConstExp3] =
                    data.ExpTypes[binop4] =
                    data.ExpTypes[binop5] =
                    data.ExpTypes[binop6] =
                    data.ExpTypes[intToString1] = new ANamedType(new TIdentifier("string"), null);
                data.ExpTypes[deleteStructInvoke] = new AVoidType(new TVoid("void"));

                data.LocalLinks[oldSizeRef4] = oldSizeDecl;
                data.LocalLinks[idRef2] = idFormal;

                data.SimpleMethodLinks[deleteStructInvoke] = CreateDeleteStructMethod(node, structDecl, data);
                data.SimpleMethodLinks[intToString1] = data.SimpleMethodLinks[intToString2];
                method.SetName(new TIdentifier("Resize" + aBaseType.AsIdentifierString() + "Array"));
                resizeArrayMethods.Add(structDecl, method);
                return method;
            }
        public void LoadLibraries(List<DirectoryInfo> libraries)
        {
            LibraryData lib = new LibraryData();

            StreamWriter writer = new StreamWriter(new FileInfo("outputList.txt").Open(FileMode.Create, FileAccess.Write));
            foreach (DirectoryInfo library in libraries)
            {
            retry:
                FileInfo precompFile = new FileInfo(library.FullName + "\\Precompiled.LibraryData");
                /*if (!precompFile.Exists)*/
                CompileLibrary(library, writer);
                IFormatter formatter = new BinaryFormatter();
                Stream stream = precompFile.OpenRead();
                try
                {
                    lib.Join((LibraryData) formatter.Deserialize(stream));
                    stream.Close();
                }
                catch (Exception err)
                {
                    stream.Close();
                    precompFile.Delete();
                    goto retry;
                }
            }
            libraryData = lib;

            {
                List<AMethodDecl> newMethods = new List<AMethodDecl>();
                List<AFieldDecl> newFields = new List<AFieldDecl>();
                XmlTextReader reader = new XmlTextReader(new FileInfo("Galaxy.xml").Open(FileMode.Open, FileAccess.Read));

                while (reader.Read())
                {
                    if (reader.NodeType != XmlNodeType.Element)
                        continue;

                    if (reader.Name == "KeyWord")
                    {
                        if (reader.GetAttribute("func") == null)
                        {
                            AFieldDecl fieldDecl = new AFieldDecl(new APublicVisibilityModifier(), null, null, null, new TIdentifier(reader.GetAttribute("name")), null);
                            newFields.Add(fieldDecl);
                            continue;
                        }
                        AMethodDecl methodDecl = new AMethodDecl();
                        methodDecl.SetName(new TIdentifier(reader.GetAttribute("name")));
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.EndElement)
                            {
                                break;
                            }
                            if (reader.NodeType != XmlNodeType.Element)
                                continue;
                            if (reader.Name != "Param")
                                continue;
                            string type = reader.GetAttribute("name");
                            type = type.Substring(0, type.IndexOf(" "));
                            string name = reader.GetAttribute("name");
                            name = name.Substring(name.IndexOf(" ") + 1);

                            methodDecl.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                        new ANamedType(new TIdentifier(type), null),
                                                                        new TIdentifier(name), null));

                        }
                        if (reader.EOF)
                            break;
                        newMethods.Add(methodDecl);
                    }
                }

                reader.Close();

                List<AMethodDecl> oldMethods = new List<AMethodDecl>();
                oldMethods.AddRange(libraryData.Methods);
                List<AFieldDecl> oldFields = new List<AFieldDecl>();
                oldFields.AddRange(libraryData.Fields);

                //Remove dublicates in old
                for (int i = 0; i < oldMethods.Count; i++)
                {
                    for (int j = i + 1; j < oldMethods.Count; j++)
                    {
                        if (oldMethods[i].GetName().Text == oldMethods[j].GetName().Text)
                        {
                            oldMethods.RemoveAt(j);
                            j--;
                        }
                    }
                }

                for (int i = 0; i < oldFields.Count; i++)
                {
                    for (int j = i + 1; j < oldFields.Count; j++)
                    {
                        if (oldFields[i].GetName().Text == oldFields[j].GetName().Text)
                        {
                            oldFields.RemoveAt(j);
                            j--;
                        }
                    }
                }

                //Remove dublicates in new
                for (int i = 0; i < newMethods.Count; i++)
                {
                    for (int j = i + 1; j < newMethods.Count; j++)
                    {
                        if (newMethods[i].GetName().Text == newMethods[j].GetName().Text)
                        {
                            newMethods.RemoveAt(j);
                            j--;
                        }
                    }
                }

                for (int i = 0; i < newFields.Count; i++)
                {
                    for (int j = i + 1; j < newFields.Count; j++)
                    {
                        if (newFields[i].GetName().Text == newFields[j].GetName().Text)
                        {
                            newFields.RemoveAt(j);
                            j--;
                        }
                    }
                }

                //Remove stuff they agree on
                for (int i = 0; i < newFields.Count; i++)
                {
                    for (int j = 0; j < oldFields.Count; j++)
                    {
                        if (newFields[i].GetName().Text == oldFields[j].GetName().Text)
                        {
                            newFields.RemoveAt(i);
                            oldFields.RemoveAt(j);
                            i--;
                            break;
                        }
                    }
                }
                for (int j = 0; j < oldFields.Count; j++)
                {
                    if (oldFields[j].GetStatic() != null)
                    {
                        oldFields.RemoveAt(j);
                        j--;
                    }
                }
                for (int i = 0; i < newMethods.Count; i++)
                {
                    for (int j = 0; j < oldMethods.Count; j++)
                    {
                        if (newMethods[i].GetName().Text == oldMethods[j].GetName().Text)
                        {
                            newMethods.RemoveAt(i);
                            oldMethods.RemoveAt(j);
                            i--;
                            break;
                        }
                    }
                }
                for (int j = 0; j < oldMethods.Count; j++)
                {
                    if (oldMethods[j].GetStatic() != null ||
                        (oldMethods[j].GetNative() == null && oldMethods[j].GetBlock() == null))
                    {
                        oldMethods.RemoveAt(j);
                        j--;
                    }
                }

            }

            {
                /*StreamWriter writer = new StreamWriter(new FileInfo("outputList.txt").Open(FileMode.Create, FileAccess.Write));
                foreach (AMethodDecl method in libraryData.Methods)
                {
                    string str = "native " + TypeToString(method.GetReturnType()) + " " + method.GetName().Text +
                                 "(";
                    bool first = true;
                    foreach (AALocalDecl formal in method.GetFormals())
                    {
                        if (!first)
                            str += ", ";
                        str += TypeToString(formal.GetType()) + " " + formal.GetName().Text;
                        first = false;
                    }
                    str += ");";

                    writer.WriteLine(str);
                }

                foreach (AFieldDecl field in libraryData.Fields)
                {
                    if (field.GetName().Text == "libNtve_gv__GameUIVisible")
                        writer = writer;
                    writer.WriteLine(TypeToString(field.GetType()) + " " + field.GetName().Text + ";");
                }*/
                writer.Flush();
                writer.Close();
            }
        }
        /// <summary>
        /// Crawls the StarCraft 2 MPQs to grab the *.galaxy files inside. These files are parsed for (native) functions and constants.
        /// </summary>
        /// <returns>The functions and constants of StarCraft 2 in form of a LibraryData</returns>
        LibraryData loadLibraries()
        {
            // parse the files for functions and constants
            CrawlAndParseMpqs();

            // convert the functions and constants to a LibraryData format
            LibraryData lib = new LibraryData();

            // create the methods with from crawled info
            foreach (ParsedFunction function in functions)
            {
                AMethodDecl method = new AMethodDecl();
                if (function.IsNative)
                    method.SetNative(new TNative("native"));
                method.SetName(new TIdentifier(function.Name));
                method.SetReturnType(new ANamedType(new TIdentifier(function.ReturnType), null));

                // add function parameter
                foreach (var parameter in function.Parameters)
                {
                    method.GetFormals().Add(new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                new ANamedType(new TIdentifier(parameter.Item1), null),
                                                                new TIdentifier(parameter.Item2), null));
                }

                lib.Methods.Add(method);
            }

            // create the constants from the crawled info
            foreach (ParsedConstant constant in constants)
            {
                AFieldDecl field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const"),
                    new ANamedType(new TIdentifier(constant.Type), null),
                    new TIdentifier(constant.Name), new AStringConstExp(new TStringLiteral(constant.Value)));
                lib.Fields.Add(field);
            }

            functions.Clear();
            constants.Clear();

            return lib;
        }