public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType)
            {
                ANamedType type = (ANamedType)node.GetType();
                if (finalTrans.data.StructTypeLinks.ContainsKey(type))
                {
                    AStructDecl strDecl = finalTrans.data.StructTypeLinks[type];
                    if (strDecl.GetLocals().Cast<PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                    {
                        MoveMethodDeclsOut mover = new MoveMethodDeclsOut("removedStructVar", finalTrans.data);
                        node.Apply(mover);
                        foreach (PStm stm in mover.NewStatements)
                        {
                            stm.Apply(this);
                        }
                        PStm pStm = Util.GetAncestor<PStm>(node);
                        if (pStm == null)
                        {
                            strDecl = Util.GetAncestor<AStructDecl>(node);

                            node.Parent().RemoveChild(node);

                            if (strDecl != null && strDecl.GetLocals().Cast<PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                                reqRerun = true;

                        }
                        else
                            pStm.Parent().RemoveChild(pStm);
                        return;
                    }
                }
            }
            base.CaseAALocalDecl(node);
        }
 public VariableDescription(AALocalDecl localDecl, VariableTypes type)
 {
     Name = localDecl.GetName().Text;
     Type = Util.TypeToString(localDecl.GetType());
     switch (type)
     {
         case VariableTypes.LocalVariable:
             PlacementPrefix = "Local";
             break;
         case VariableTypes.Parameter:
             PlacementPrefix = "Parameter";
             break;
         case VariableTypes.StructVariable:
             PlacementPrefix = "Struct field";
             break;
         default:
             PlacementPrefix = "";
             break;
     }
     VariableType = type;
     Const = localDecl.GetConst() != null;
     IsStatic = localDecl.GetStatic() != null;
     Visibility = localDecl.GetVisibilityModifier();
     realType = (PType) localDecl.GetType().Clone();
     init = localDecl.GetInit();
     Line = localDecl.GetName().Line;
     Position = TextPoint.FromCompilerCoords(localDecl.GetName());
 }
 public override void CaseAALocalDecl(AALocalDecl node)
 {
     //It wont enter methods
     //Repeated fields in structs are syntax errors
     AStructDecl str = Util.GetAncestor<AStructDecl>(node);
     StructFields[str].Add(node);
     node.Parent().RemoveChild(node);
 }
 public override void CaseAALocalDecl(AALocalDecl node)
 {
     if (!processFieldsOnly && !processMethodsOnly && !processStructs)
         if (!definedLocals.Contains(node))
         {
             definedLocals.Add(node);
             assignedToLocals[node] = new List<AAssignmentExp>();
         }
     base.CaseAALocalDecl(node);
 }
 public override void CaseAALocalDecl(AALocalDecl node)
 {
     if (node.GetConst() != null) Write("const ");
     node.GetType().Apply(this);
     Write(" " + node.GetName().Text);
     if (node.GetInit() != null)
     {
         Write(" = ");
         node.GetInit().Apply(this);
     }
 }
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (setUses)
            {
                if (!definedLocals.Contains(node))
                    definedLocals.Add(node);

                PStm parentStm = Util.GetAncestor<PStm>(node);
                if (parentStm != null)
                    assigns[parentStm] = node;

            }
            base.CaseAALocalDecl(node);
        }
        //Convert struct variables to a collection of local variables
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetType() is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) node.GetType()) && Util.HasAncestor<PStm>(node))
            {
                //Can not have init - it would be bulk copy
                AStructDecl str = data.StructTypeLinks[(ANamedType) node.GetType()];
                Dictionary<AALocalDecl, AALocalDecl> variableMap = new Dictionary<AALocalDecl, AALocalDecl>();
                PStm pStm = (PStm) node.Parent();
                AABlock pBlock = (AABlock) pStm.Parent();
                foreach (AALocalDecl structLocal in str.GetLocals())
                {

                    AALocalDecl replacementLocal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                   Util.MakeClone(structLocal.GetType(), data),
                                                                   new TIdentifier(node.GetName().Text + "_" +
                                                                                   structLocal.GetName().Text), null);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), replacementLocal));

                    AALocalDecl baseLocal = structLocal;
                    if (data.EnheritanceLocalMap.ContainsKey(baseLocal))
                        baseLocal = data.EnheritanceLocalMap[baseLocal];
                    List<AALocalDecl> localsToAdd = new List<AALocalDecl>();
                    localsToAdd.AddRange(data.EnheritanceLocalMap.Where(pair => pair.Value == baseLocal).Select(pair => pair.Key));
                    localsToAdd.Add(baseLocal);
                    foreach (AALocalDecl localDecl in localsToAdd)
                    {
                        variableMap[localDecl] = replacementLocal;
                    }
                }
                List<ALocalLvalue> uses = new List<ALocalLvalue>();
                uses.AddRange(data.LocalLinks.Where(k => k.Value == node && Util.GetAncestor<AAProgram>(k.Key) != null).Select(k => k.Key));
                foreach (ALocalLvalue lvalue in uses)
                {
                    AStructLvalue structLocalRef = (AStructLvalue) lvalue.Parent().Parent();

                    AALocalDecl replacementLocal = variableMap[data.StructFieldLinks[structLocalRef]];
                    ALocalLvalue replacementLvalue = new ALocalLvalue(new TIdentifier(replacementLocal.GetName().Text));
                    data.LocalLinks[replacementLvalue] = replacementLocal;
                    data.LvalueTypes[replacementLvalue] = replacementLocal.GetType();
                    structLocalRef.ReplaceBy(replacementLvalue);
                }
                foreach (AALocalDecl replacementLocal in variableMap.Select(k => k.Value))
                {
                    replacementLocal.Apply(this);
                }
            }
            base.CaseAALocalDecl(node);
        }
        public override void CaseAALocalDecl(AALocalDecl node)
        {
            if (node.GetConst() == null)
                return;

            initialLocalDecl = node;

            if (IsConstant(node.GetInit()))
            {
                {
                    List<ALocalLvalue> lvalues = new List<ALocalLvalue>();
                    lvalues.AddRange(data.LocalLinks.Where(link => link.Value == node).Select(link => link.Key));
                    foreach (ALocalLvalue lvalue in lvalues)
                    {
                        PExp parent = (PExp)lvalue.Parent();
                        parent.ReplaceBy(Util.MakeClone(node.GetInit(), data));
                    }
                }
                {
                    List<AStructLvalue> lvalues = new List<AStructLvalue>();
                    lvalues.AddRange(data.StructFieldLinks.Where(link => link.Value == node).Select(link => link.Key));
                    foreach (AStructLvalue lvalue in lvalues)
                    {
                        PExp parent = (PExp)lvalue.Parent();
                        parent.ReplaceBy(Util.MakeClone(node.GetInit(), data));
                    }
                }
                {
                    List<AStructFieldLvalue> lvalues = new List<AStructFieldLvalue>();
                    lvalues.AddRange(
                        data.StructMethodFieldLinks.Where(link => link.Value == node).Select(link => link.Key));
                    foreach (AStructFieldLvalue lvalue in lvalues)
                    {
                        PExp parent = (PExp) lvalue.Parent();
                        parent.ReplaceBy(Util.MakeClone(node.GetInit(), data));
                    }
                }
                if (node.Parent() is ALocalDeclStm)
                    node.Parent().Parent().RemoveChild(node.Parent());
                else
                    node.Parent().RemoveChild(node);
            }

            initialLocalDecl = null;
        }
        public override void OutAALocalDecl(AALocalDecl node)
        {
            if (!Util.HasAncestor<AABlock>(node) && !Util.HasAncestor<AMethodDecl>(node))
            {
                //OutStructFieldDecl(node);
                return;
            }

            if (node.GetInit() != null)
                return;

            AABlock pBlock;
            int insertIndex;
            PLvalue lvalue;
            if (Util.HasAncestor<AABlock>(node))
            {
                //A local variable
                pBlock = Util.GetAncestor<AABlock>(node);
                insertIndex = pBlock.GetStatements().IndexOf(Util.GetAncestor<PStm>(node)) + 1;
                lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text));
                data.LocalLinks[(ALocalLvalue) lvalue] = node;
                data.LvalueTypes[lvalue] = node.GetType();
            }
            else
            {
                //Parameter

                //Parameters will be set from the caller
                return;
                pBlock = (AABlock) Util.GetAncestor<AMethodDecl>(node).GetBlock();
                insertIndex = 0;
                lvalue = new ALocalLvalue(new TIdentifier(node.GetName().Text));
                data.LocalLinks[(ALocalLvalue)lvalue] = node;
                data.LvalueTypes[lvalue] = node.GetType();
            }
            AABlock block = new AABlock(new ArrayList(), new TRBrace("}"));

            MakeAssignments(block, node.GetType(), lvalue, true);

            if (block.GetStatements().Count != 0)
                pBlock.GetStatements().Insert(insertIndex, new ABlockStm(new TLBrace("{"), block));
        }
        public override void CaseASimpleInvokeExp(ASimpleInvokeExp node)
        {
            PExp expNode = (PExp)node;
            PType type = data.ExpTypes[expNode];
            if (type is APointerType) type = new ANamedType(new TIdentifier("string"), null);
            ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName", 0, 0));
            ALvalueExp exp = new ALvalueExp(local);
            PStm stm = Util.GetAncestor<PStm>(node);
            AABlock block = (AABlock)stm.Parent();
            node.ReplaceBy(exp);
            AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    Util.MakeClone(type, data),
                                                    new TIdentifier(varName, 0, 0), expNode);
            ALocalDeclStm newStm = new ALocalDeclStm(new TSemicolon(";"), localDecl);
            block.GetStatements().Insert(block.GetStatements().IndexOf(stm), newStm);
            NewStatements.Add(newStm);

            data.LvalueTypes[local] = type;
            data.ExpTypes[exp] = type;
            data.LocalLinks[local] = localDecl;
            //localDecl.Apply(this);
            exp.Apply(this);
            return;
        }
 public void Add(AALocalDecl local, bool read, bool written)
 {
     if (Locals.ContainsKey(local))
         Locals[local].Union(read, written);
     else
         Locals[local] = new Values(read, written);
 }
 public override void CaseAMultiLocalDecl(AMultiLocalDecl node)
 {
     PStm pStm = Util.GetAncestor<PStm>(node);
     if (!(pStm.Parent() is AABlock))
     {
         errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText203")));
         return;
     }
     AABlock pBlock = (AABlock) pStm.Parent();
     List<AALocalDecl> newDecls = new List<AALocalDecl>();
     foreach (AALocalDeclRight right in node.GetLocalDeclRight())
     {
         if (right.GetName() == null)
         {
             errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText204")));
             continue;
         }
         if ((right.GetAssignop() == null) != (right.GetInit() == null))
         {
             errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, LocRM.GetString("ErrorText205")));
             continue;
         }
         AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null,
                                                 node.GetConst() != null
                                                     ? (TConst) node.GetConst().Clone()
                                                     : null,
                                                 (PType) node.GetType().Clone(),
                                                 right.GetName(),
                                                 right.GetInit());
         newDecls.Add(localDecl);
         pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), localDecl));
     }
     pBlock.RemoveChild(pStm);
     foreach (AALocalDecl localDecl in newDecls)
     {
         localDecl.Apply(this);
     }
 }
            private void MoveOut(PExp exp, PType type)
            {
                PStm pStm = Util.GetAncestor<PStm>(exp);
                AABlock pBlock = (AABlock)pStm.Parent();

                ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier("gppVar"));
                ALvalueExp lvalueExp = new ALvalueExp(lvalue);
                exp.ReplaceBy(lvalueExp);
                AALocalDecl decl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(type, data), new TIdentifier("gppVar"), exp);
                pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(pStm), new ALocalDeclStm(new TSemicolon(";"), decl));

                data.LvalueTypes[lvalue] =
                    data.ExpTypes[lvalueExp] = decl.GetType();
                data.LocalLinks[lvalue] = decl;
            }
            public override void CaseAALocalDecl(AALocalDecl node)
            {
                //If parent is a methoddecl, we are a parameter
                if (node.Parent() is AMethodDecl)
                {
                    VariableDescription variable = new VariableDescription(node, VariableDescription.VariableTypes.Parameter);
                    Formals.Add(variable);
                }
                else
                {
                    VariableDescription variable = new VariableDescription(node, VariableDescription.VariableTypes.LocalVariable);
                    Locals.Add(variable);
                }

                base.CaseAALocalDecl(node);
            }
 public virtual void InAALocalDecl(AALocalDecl node)
 {
     DefaultIn(node);
 }
        private void TransformBreaks(PStm stm, SwitchCaseData switchCase, AALocalDecl continueDecl, AALocalDecl fallthroughDecl, ref int currI)
        {
            if (stm is ABreakStm)
            {
                AABlock pBlock = (AABlock) stm.Parent();
                if (!switchCase.IsLast && (switchCase.RequiresContinue || switchCase.ContainsFallthrough))
                {
                    //Add continue = false;
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(continueDecl.GetName().Text));
                    ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool());
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment));

                    data.LocalLinks[lvalue] = continueDecl;
                    data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = continueDecl.GetType();
                    currI++;
                }
                if (!switchCase.IsLast && switchCase.TargetForFallThrough)
                {
                    //Add fallthrough = false;
                    ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(fallthroughDecl.GetName().Text));
                    ABooleanConstExp rightSide = new ABooleanConstExp(new AFalseBool());
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide);
                    pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(stm), new AExpStm(new TSemicolon(";"), assignment));

                    data.LocalLinks[lvalue] = fallthroughDecl;
                    data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = fallthroughDecl.GetType();
                    currI++;
                }
                if (!switchCase.RequiresWhile)
                {//Remove break
                    stm.Parent().RemoveChild(stm);
                    currI--;
                }
            }
            if (stm is ABlockStm)
                TransformBreaks((AABlock)((ABlockStm)stm).GetBlock(), switchCase, continueDecl, fallthroughDecl);
            if (stm is AIfThenStm)
                TransformBreaks(((AIfThenStm)stm).GetBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
            if (stm is AIfThenElseStm)
            {
                TransformBreaks(((AIfThenElseStm)stm).GetThenBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
                TransformBreaks(((AIfThenElseStm)stm).GetElseBody(), switchCase, continueDecl, fallthroughDecl, ref currI);
            }
        }
 private void TransformBreaks(AABlock block, SwitchCaseData switchCase, AALocalDecl continueDecl, AALocalDecl fallthroughDecl)
 {
     for (int i = 0; i < block.GetStatements().Count; i++)
     {
         PStm stm = (PStm) block.GetStatements()[i];
         int stmCount = block.GetStatements().Count;
         TransformBreaks(stm, switchCase, continueDecl, fallthroughDecl, ref i);
         /*if (stmCount > block.GetStatements().Count)
             i--;*/
     }
 }
 public override void CaseAALocalDecl(AALocalDecl node)
 {
     InAALocalDecl(node);
     if (node.GetInit() != null)
     {
         node.GetInit().Apply(this);
     }
     if (node.GetName() != null)
     {
         node.GetName().Apply(this);
     }
     if (node.GetType() != null)
     {
         node.GetType().Apply(this);
     }
     if (node.GetConst() != null)
     {
         node.GetConst().Apply(this);
     }
     if (node.GetOut() != null)
     {
         node.GetOut().Apply(this);
     }
     if (node.GetRef() != null)
     {
         node.GetRef().Apply(this);
     }
     if (node.GetStatic() != null)
     {
         node.GetStatic().Apply(this);
     }
     if (node.GetVisibilityModifier() != null)
     {
         node.GetVisibilityModifier().Apply(this);
     }
     OutAALocalDecl(node);
 }
 public virtual void CaseAALocalDecl(AALocalDecl node)
 {
     DefaultCase(node);
 }
 public LocalVariable(AALocalDecl localDecl)
 {
     LocalDecl = localDecl;
 }
 public virtual void OutAALocalDecl(AALocalDecl node)
 {
     DefaultOut(node);
 }
        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);
                    }
                }
        }
 public StructField(AALocalDecl structFieldDecl, IVariable @base)
 {
     StructFieldDecl = structFieldDecl;
     Base = @base;
 }
 public override void CaseAALocalDecl(AALocalDecl node)
 {
     localDecls.AddLast(new LocalDecl(node, pMethod));
 }
 public LocalDecl(AALocalDecl decl, AMethodDecl parentMethod)
 {
     Decl = decl;
     ParentMethod = parentMethod;
     if (Name.StartsWith("_"))
         Name = "u" + Name;
 }
        public override void CaseAThisArrayPropertyDecl(AThisArrayPropertyDecl node)
        {
            if (!Util.HasAncestor<AStructDecl>(node))
            {
                /*if (node.GetVisibilityModifier() is AProtectedVisibilityModifier)
                    errors.Add(new ErrorCollection.Error(node.GetToken(),
                                                         "Only fields inside structs or classes can be marked as protected."));*/
                if (!Util.HasAncestor<AEnrichmentDecl>(node))
                    errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText185")));
            }

            APropertyDecl replacer = new APropertyDecl(node.GetVisibilityModifier(), null, node.GetType(),
                                                       new TIdentifier("", node.GetToken().Line, node.GetToken().Pos),
                                                       node.GetGetter(), node.GetSetter());
            List<AALocalDecl> locals = new List<AALocalDecl>();
            if (replacer.GetGetter() != null)
            {
                AABlock block = (AABlock) replacer.GetGetter();
                AALocalDecl local = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    (PType) node.GetArgType().Clone(),
                                                    (TIdentifier) node.GetArgName().Clone(), null);
                block.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), local));
                locals.Add(local);
            }
            if (replacer.GetSetter() != null)
            {
                AABlock block = (AABlock)replacer.GetSetter();
                AALocalDecl local = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                    (PType)node.GetArgType().Clone(),
                                                    (TIdentifier)node.GetArgName().Clone(), null);

                block.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), local));
                locals.Add(local);
            }
            data.ArrayPropertyLocals[replacer] = locals.ToArray();
            node.ReplaceBy(replacer);
            replacer.Apply(this);
        }
        private AMethodDecl CreateStringDeobfuscator()
        {
            AASourceFile file = (AASourceFile) finalTrans.mainEntry.Parent();

            //Create fields for the string constants
            AStringConstExp emptyStringConst = new AStringConstExp(new TStringLiteral("\"\""));
            AFieldDecl emptyStringField = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const"),
                                                         new ANamedType(new TIdentifier("string"), null),
                                                         new TIdentifier("fOobar"), emptyStringConst);
            file.GetDecl().Add(emptyStringField);
            data.Fields.Add(new SharedData.DeclItem<AFieldDecl>(file, emptyStringField));
            AFieldLvalue emptyStringRef1 = new AFieldLvalue(new TIdentifier(emptyStringField.GetName().Text));
            AFieldLvalue emptyStringRef2 = new AFieldLvalue(new TIdentifier(emptyStringField.GetName().Text));
            AFieldLvalue emptyStringRef3 = new AFieldLvalue(new TIdentifier(emptyStringField.GetName().Text));
            ALvalueExp emptyStringRef1Exp = new ALvalueExp(emptyStringRef1);
            ALvalueExp emptyStringRef2Exp = new ALvalueExp(emptyStringRef2);
            ALvalueExp emptyStringRef3Exp = new ALvalueExp(emptyStringRef3);

            AStringConstExp colonStringConst = new AStringConstExp(new TStringLiteral("\":\""));
            AFieldDecl colonStringField = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const"),
                                                         new ANamedType(new TIdentifier("string"), null),
                                                         new TIdentifier("foObar"), colonStringConst);
            file.GetDecl().Add(colonStringField);
            data.Fields.Add(new SharedData.DeclItem<AFieldDecl>(file, colonStringField));
            AFieldLvalue colonStringRef = new AFieldLvalue(new TIdentifier(colonStringField.GetName().Text));
            ALvalueExp colonStringRefExp = new ALvalueExp(colonStringRef);

            /*
                string output = "";
                string ch;
                int length = StringLength(s);
                int phase1 = (length - 1)%3;
                int phase2 = (length - 1)%2;
             */

            AALocalDecl stringParam = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                      new ANamedType(new TIdentifier("string"), null),
                                                      new TIdentifier("fo0bar"), emptyStringRef1Exp);
            ALocalLvalue stringParamRef1 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef2 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef3 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef4 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef5 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef6 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef7 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALocalLvalue stringParamRef8 = new ALocalLvalue(new TIdentifier(stringParam.GetName().Text));
            ALvalueExp stringParamRef1Exp = new ALvalueExp(stringParamRef1);
            ALvalueExp stringParamRef2Exp = new ALvalueExp(stringParamRef2);
            ALvalueExp stringParamRef4Exp = new ALvalueExp(stringParamRef4);
            ALvalueExp stringParamRef5Exp = new ALvalueExp(stringParamRef5);
            ALvalueExp stringParamRef7Exp = new ALvalueExp(stringParamRef7);
            ALvalueExp stringParamRef8Exp = new ALvalueExp(stringParamRef8);

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

            AALocalDecl outputDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                     new ANamedType(new TIdentifier("string"), null),
                                                     new TIdentifier("foobar"), emptyStringRef1Exp);
            methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), outputDecl));
            ALocalLvalue outputRef1 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef2 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef3 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef4 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef5 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef6 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef7 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef8 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef9 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef10 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef11 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef12 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALocalLvalue outputRef13 = new ALocalLvalue(new TIdentifier(outputDecl.GetName().Text));
            ALvalueExp outputRef2Exp = new ALvalueExp(outputRef2);
            ALvalueExp outputRef4Exp = new ALvalueExp(outputRef4);
            ALvalueExp outputRef5Exp = new ALvalueExp(outputRef5);
            ALvalueExp outputRef6Exp = new ALvalueExp(outputRef6);
            ALvalueExp outputRef7Exp = new ALvalueExp(outputRef7);
            ALvalueExp outputRef8Exp = new ALvalueExp(outputRef8);
            ALvalueExp outputRef10Exp = new ALvalueExp(outputRef10);
            ALvalueExp outputRef11Exp = new ALvalueExp(outputRef11);
            ALvalueExp outputRef12Exp = new ALvalueExp(outputRef12);
            ALvalueExp outputRef13Exp = new ALvalueExp(outputRef13);

            AALocalDecl chDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                     new ANamedType(new TIdentifier("string"), null),
                                                     new TIdentifier("f0obar"), null);
            methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), chDecl));
            ALocalLvalue chRef1 = new ALocalLvalue(new TIdentifier(chDecl.GetName().Text));
            ALocalLvalue chRef2 = new ALocalLvalue(new TIdentifier(chDecl.GetName().Text));
            ALocalLvalue chRef3 = new ALocalLvalue(new TIdentifier(chDecl.GetName().Text));
            ALocalLvalue chRef4 = new ALocalLvalue(new TIdentifier(chDecl.GetName().Text));
            ALocalLvalue chRef5 = new ALocalLvalue(new TIdentifier(chDecl.GetName().Text));
            ALvalueExp chRef3Exp = new ALvalueExp(chRef3);
            ALvalueExp chRef4Exp = new ALvalueExp(chRef4);
            ALvalueExp chRef5Exp = new ALvalueExp(chRef5);

            ASimpleInvokeExp stringLengthInvoke1 = new ASimpleInvokeExp(new TIdentifier("StringLength"),
                                                                        new ArrayList() { stringParamRef1Exp });
            AALocalDecl lengthDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                     new ANamedType(new TIdentifier("int"), null),
                                                     new TIdentifier("f0Obar"), stringLengthInvoke1);
            methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), lengthDecl));
            ALocalLvalue lengthRef1 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef2 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef3 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef4 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef5 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef6 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef7 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALocalLvalue lengthRef8 = new ALocalLvalue(new TIdentifier(lengthDecl.GetName().Text));
            ALvalueExp lengthRef1Exp = new ALvalueExp(lengthRef1);
            ALvalueExp lengthRef2Exp = new ALvalueExp(lengthRef2);
            ALvalueExp lengthRef3Exp = new ALvalueExp(lengthRef3);
            ALvalueExp lengthRef4Exp = new ALvalueExp(lengthRef4);
            ALvalueExp lengthRef5Exp = new ALvalueExp(lengthRef5);
            ALvalueExp lengthRef6Exp = new ALvalueExp(lengthRef6);
            ALvalueExp lengthRef7Exp = new ALvalueExp(lengthRef7);

            AIntConstExp intConstp1Init1 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConstp1Init2 = new AIntConstExp(new TIntegerLiteral("3"));
            ABinopExp binopExpP1InitMinus = new ABinopExp(lengthRef1Exp, new AMinusBinop(new TMinus("-")), intConstp1Init1);
            ABinopExp binopExpP1InitMod = new ABinopExp(binopExpP1InitMinus, new AModuloBinop(new TMod("%")), intConstp1Init2);

            AALocalDecl phase1Decl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                     new ANamedType(new TIdentifier("int"), null),
                                                     new TIdentifier("fO0bar"), binopExpP1InitMod);
            methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), phase1Decl));
            ALocalLvalue phase1Ref1 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref2 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref3 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref4 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref5 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref6 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref7 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref8 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref9 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref10 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALocalLvalue phase1Ref11 = new ALocalLvalue(new TIdentifier(phase1Decl.GetName().Text));
            ALvalueExp phase1Ref1Exp = new ALvalueExp(phase1Ref1);
            ALvalueExp phase1Ref2Exp = new ALvalueExp(phase1Ref2);
            ALvalueExp phase1Ref4Exp = new ALvalueExp(phase1Ref4);
            ALvalueExp phase1Ref5Exp = new ALvalueExp(phase1Ref5);
            ALvalueExp phase1Ref7Exp = new ALvalueExp(phase1Ref7);
            ALvalueExp phase1Ref9Exp = new ALvalueExp(phase1Ref9);
            ALvalueExp phase1Ref10Exp = new ALvalueExp(phase1Ref10);
            ALvalueExp phase1Ref11Exp = new ALvalueExp(phase1Ref11);

            AIntConstExp intConstp2Init1 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConstp2Init2 = new AIntConstExp(new TIntegerLiteral("2"));
            ABinopExp binopExpP2InitMinus = new ABinopExp(lengthRef2Exp, new AMinusBinop(new TMinus("-")), intConstp2Init1);
            ABinopExp binopExpP2InitMod = new ABinopExp(binopExpP2InitMinus, new AModuloBinop(new TMod("%")), intConstp2Init2);

            AALocalDecl phase2Decl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                     new ANamedType(new TIdentifier("int"), null),
                                                     new TIdentifier("carl"), binopExpP2InitMod);
            methodBlock.GetStatements().Add(new ALocalDeclStm(new TSemicolon(";"), phase2Decl));
            ALocalLvalue phase2Ref1 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref2 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref3 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref4 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref5 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref6 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref7 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref8 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALocalLvalue phase2Ref9 = new ALocalLvalue(new TIdentifier(phase2Decl.GetName().Text));
            ALvalueExp phase2Ref1Exp = new ALvalueExp(phase2Ref1);
            ALvalueExp phase2Ref2Exp = new ALvalueExp(phase2Ref2);
            ALvalueExp phase2Ref4Exp = new ALvalueExp(phase2Ref4);
            ALvalueExp phase2Ref5Exp = new ALvalueExp(phase2Ref5);
            ALvalueExp phase2Ref7Exp = new ALvalueExp(phase2Ref7);
            ALvalueExp phase2Ref9Exp = new ALvalueExp(phase2Ref9);

            /*
                while(length > 0)
                {
                    if(phase2 == 0)
                    {
                        ch = StringSub(s, 1, 1);
                        s = StringReplace(s, "", 1, 1);
                    }
                    else
                    {
                        if(phase2 == 1)
                        {
                            ch = StringSub(s, length, length);
                            s = StringReplace(s, "", length, length);
                        }
                    }

                    if(phase1 == 0)
                    {
                        output = ch + output;
                    }
                    else
                    {
                        if(phase1 == 1)
                        {
                            output = StringSub(output, 1, (StringLength(output) + 1)/2) + ch + StringSub(output, (StringLength(output) + 1)/2 + 1, StringLength(output));
                        }
                        else
                        {
                            output = output + ch;
                        }
                    }
                    phase1 = phase1 - 1;
                    if(phase1 < 0)
                    {
                        phase1 = phase1 + 3;
                    }
                    phase2 = phase2 - 1;
                    if(phase2 < 0)
                    {
                        phase2 = phase2 + 2;
                    }
                    length = StringLength(s);
                }
             */

            AABlock whileBlock = new AABlock(new ArrayList(), new TRBrace("}"));
            AIntConstExp intConstWhileCond = new AIntConstExp(new TIntegerLiteral("0"));
            ABinopExp binopWhileCond = new ABinopExp(lengthRef3Exp, new AGtBinop(new TGt(">")), intConstWhileCond);
            methodBlock.GetStatements().Add(new AWhileStm(new TLParen("("), binopWhileCond,
                                                          new ABlockStm(new TLBrace("{"), whileBlock)));

            /*
                    if(phase2 == 0)
                    {
                        ch = StringSub(s, 1, 1);
                        s = StringReplace(s, "", 1, 1);
                    }
                    else
                    {
                        if(phase2 == 1)
                        {
                            ch = StringSub(s, length, length);
                            s = StringReplace(s, "", length, length);
                        }
                    }
             */
            AIntConstExp intConstIf1Cond = new AIntConstExp(new TIntegerLiteral("0"));
            ABinopExp binopIf1Cond = new ABinopExp(phase2Ref1Exp, new AEqBinop(new TEq("==")), intConstIf1Cond);
            AABlock thenBlock = new AABlock();
            AABlock elseBlock = new AABlock();
            whileBlock.GetStatements().Add(new AIfThenElseStm(new TLParen("("), binopIf1Cond,
                                                              new ABlockStm(new TLBrace("{"), thenBlock),
                                                              new ABlockStm(new TLBrace("{"), elseBlock)));

            //ch = StringSub(s, 1, 1);
            AIntConstExp intConst1 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst2 = new AIntConstExp(new TIntegerLiteral("1"));
            ASimpleInvokeExp invokeStringSub1 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() {stringParamRef2Exp, intConst1, intConst2});
            AAssignmentExp assignment1 = new AAssignmentExp(new TAssign("="), chRef1, invokeStringSub1);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment1));

            //s = StringReplace(s, "", 1, 1);
            AIntConstExp intConst3 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst4 = new AIntConstExp(new TIntegerLiteral("1"));
            ASimpleInvokeExp invokeStringReplace1 = new ASimpleInvokeExp(new TIdentifier("StringReplace"),
                                                           new ArrayList() { stringParamRef4Exp, emptyStringRef2Exp, intConst3, intConst4 });
            AAssignmentExp assignment2 = new AAssignmentExp(new TAssign("="), stringParamRef3, invokeStringReplace1);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment2));

            //if(phase2 == 1)
            AIntConstExp intConst5 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop1 = new ABinopExp(phase2Ref2Exp, new AEqBinop(new TEq("==")), intConst5);
            thenBlock = new AABlock();
            elseBlock.GetStatements().Add(new AIfThenStm(new TLParen("("), binop1,
                                                         new ABlockStm(new TLBrace("{"), thenBlock)));

            //ch = StringSub(s, length, length);
            ASimpleInvokeExp invokeStringSub2 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() { stringParamRef5Exp, lengthRef3Exp, lengthRef4Exp });
            AAssignmentExp assignment3 = new AAssignmentExp(new TAssign("="), chRef2, invokeStringSub2);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment3));

            //s = StringReplace(s, "", length, length);
            ASimpleInvokeExp invokeStringReplace2 = new ASimpleInvokeExp(new TIdentifier("StringReplace"),
                                                           new ArrayList() { stringParamRef7Exp, emptyStringRef3Exp, lengthRef5Exp, lengthRef6Exp });
            AAssignmentExp assignment4 = new AAssignmentExp(new TAssign("="), stringParamRef6, invokeStringReplace2);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment4));

            //if(phase1 == 0)
            AIntConstExp intConst6 = new AIntConstExp(new TIntegerLiteral("0"));
            ABinopExp binop2 = new ABinopExp(phase1Ref1Exp, new AEqBinop(new TEq("==")), intConst6);
            thenBlock = new AABlock();
            elseBlock = new AABlock();
            whileBlock.GetStatements().Add(new AIfThenElseStm(new TLParen("("), binop2,
                                                              new ABlockStm(new TLBrace("{"), thenBlock),
                                                              new ABlockStm(new TLBrace("{"), elseBlock)));

            //output = ch + output;
            ABinopExp binop3 = new ABinopExp(chRef3Exp, new APlusBinop(new TPlus("+")), outputRef2Exp);
            AAssignmentExp assignment5 = new AAssignmentExp(new TAssign("="), outputRef1, binop3);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment5));

            //if(phase1 == 1)
            AABlock cBlock = elseBlock;
            AIntConstExp intConst7 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop4 = new ABinopExp(phase1Ref2Exp, new AEqBinop(new TEq("==")), intConst7);
            thenBlock = new AABlock();
            elseBlock = new AABlock();
            cBlock.GetStatements().Add(new AIfThenElseStm(new TLParen("("), binop4,
                                                              new ABlockStm(new TLBrace("{"), thenBlock),
                                                              new ABlockStm(new TLBrace("{"), elseBlock)));

            //output = StringSub(output, 1, (StringLength(output) + 1)/2) + ch + StringSub(output, (StringLength(output) + 1)/2 + 1, StringLength(output));
            AIntConstExp intConst8 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst9 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst10 = new AIntConstExp(new TIntegerLiteral("2"));
            AIntConstExp intConst11 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst12 = new AIntConstExp(new TIntegerLiteral("2"));
            AIntConstExp intConst13 = new AIntConstExp(new TIntegerLiteral("1"));

            ASimpleInvokeExp invokeStringLength1 = new ASimpleInvokeExp(new TIdentifier("StringLength"),
                                                                        new ArrayList() {outputRef5Exp});
            ABinopExp binop5 = new ABinopExp(invokeStringLength1, new APlusBinop(new TPlus("+")), intConst9);
            ABinopExp binop6 = new ABinopExp(binop5, new ADivideBinop(new TDiv("/")), intConst10);

            ASimpleInvokeExp invokeStringSub3 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() { outputRef4Exp, intConst8, binop6});

            ABinopExp binop7 = new ABinopExp(invokeStringSub3, new APlusBinop(new TPlus("+")), chRef4Exp);

            ASimpleInvokeExp invokeStringLength2 = new ASimpleInvokeExp(new TIdentifier("StringLength"),
                                                                        new ArrayList() { outputRef7Exp });
            ABinopExp binop8 = new ABinopExp(invokeStringLength2, new APlusBinop(new TPlus("+")), intConst11);
            ABinopExp binop9 = new ABinopExp(binop8, new ADivideBinop(new TDiv("/")), intConst12);
            ABinopExp binop10 = new ABinopExp(binop9, new APlusBinop(new TPlus("+")), intConst13);

            ASimpleInvokeExp invokeStringLength3 = new ASimpleInvokeExp(new TIdentifier("StringLength"),
                                                                        new ArrayList() { outputRef8Exp });

            ASimpleInvokeExp invokeStringSub4 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() { outputRef6Exp, binop10, invokeStringLength3 });

            ABinopExp binop11 = new ABinopExp(binop7, new APlusBinop(new TPlus("+")), invokeStringSub4);

            AAssignmentExp assignment6 = new AAssignmentExp(new TAssign("="), outputRef3, binop11);

            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment6));

            //output = output + ch;
            ABinopExp binop12 = new ABinopExp(outputRef10Exp, new APlusBinop(new TPlus("+")), chRef5Exp);
            AAssignmentExp assignment7 = new AAssignmentExp(new TAssign("="), outputRef9, binop12);
            elseBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment7));

            //phase1 = phase1 - 1;
            AIntConstExp intConst14 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop13 = new ABinopExp(phase1Ref4Exp, new AMinusBinop(new TMinus("-")), intConst14);
            AAssignmentExp assignment8 = new AAssignmentExp(new TAssign("="), phase1Ref3, binop13);
            whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment8));

            //if(phase1 < 0)
            AIntConstExp intConst15 = new AIntConstExp(new TIntegerLiteral("0"));
            ABinopExp binop14 = new ABinopExp(phase1Ref5Exp, new ALtBinop(new TLt("<")), intConst15);
            thenBlock = new AABlock();
            whileBlock.GetStatements().Add(new AIfThenStm(new TLParen("("), binop14,
                                                         new ABlockStm(new TLBrace("{"), thenBlock)));

            //phase1 = phase1 + 3;
            AIntConstExp intConst16 = new AIntConstExp(new TIntegerLiteral("3"));
            ABinopExp binop15 = new ABinopExp(phase1Ref7Exp, new APlusBinop(new TPlus("+")), intConst16);
            AAssignmentExp assignment9 = new AAssignmentExp(new TAssign("="), phase1Ref6, binop15);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment9));

            //phase2 = phase2 - 1;
            AIntConstExp intConst17 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop16 = new ABinopExp(phase2Ref4Exp, new AMinusBinop(new TMinus("-")), intConst17);
            AAssignmentExp assignment10 = new AAssignmentExp(new TAssign("="), phase2Ref3, binop16);
            whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment10));

            //if(phase2 < 0)
            AIntConstExp intConst18 = new AIntConstExp(new TIntegerLiteral("0"));
            ABinopExp binop17 = new ABinopExp(phase2Ref5Exp, new ALtBinop(new TLt("<")), intConst18);
            thenBlock = new AABlock();
            whileBlock.GetStatements().Add(new AIfThenStm(new TLParen("("), binop17,
                                                         new ABlockStm(new TLBrace("{"), thenBlock)));

            //phase2 = phase2 + 2;
            AIntConstExp intConst19 = new AIntConstExp(new TIntegerLiteral("2"));
            ABinopExp binop18 = new ABinopExp(phase2Ref7Exp, new APlusBinop(new TPlus("+")), intConst19);
            AAssignmentExp assignment11 = new AAssignmentExp(new TAssign("="), phase2Ref6, binop18);
            thenBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment11));

            //length = StringLength(s);
            ASimpleInvokeExp invokeStringLength4 = new ASimpleInvokeExp(new TIdentifier("StringLength"),
                                                                        new ArrayList() { stringParamRef8Exp });
            AAssignmentExp assignment12 = new AAssignmentExp(new TAssign("="), lengthRef8, invokeStringLength4);
            whileBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment12));

            /*
                phase1 = StringFind(output, ":", false);
                phase2 = StringToInt(StringSub(output, 1, phase1 - 1));
                return StringSub(output, phase1 + 1, phase2 + phase1);
             */

            ABooleanConstExp boolConst1 = new ABooleanConstExp(new AFalseBool());
            ASimpleInvokeExp invokeStringFind = new ASimpleInvokeExp(new TIdentifier("StringFind"),
                                                                     new ArrayList()
                                                                         {outputRef11Exp, colonStringRefExp, boolConst1});
            AAssignmentExp assignment13 = new AAssignmentExp(new TAssign("="), phase1Ref8, invokeStringFind);
            methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment13));

            //phase2 = StringToInt(StringSub(output, 1, phase1 - 1));
            AIntConstExp intConst20 = new AIntConstExp(new TIntegerLiteral("1"));
            AIntConstExp intConst21 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop19 = new ABinopExp(phase1Ref9Exp, new AMinusBinop(new TMinus("-")), intConst21);
            ASimpleInvokeExp invokeStringSub5 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() { outputRef12Exp, intConst20, binop19});
            ASimpleInvokeExp invokeStringToInt = new ASimpleInvokeExp(new TIdentifier("StringToInt"),
                                                                      new ArrayList() { invokeStringSub5 });
            AAssignmentExp assignment14 = new AAssignmentExp(new TAssign("="), phase2Ref8, invokeStringToInt);
            methodBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment14));

            //return StringSub(output, phase1 + 1, phase2 + phase1);
            AIntConstExp intConst22 = new AIntConstExp(new TIntegerLiteral("1"));
            ABinopExp binop20 = new ABinopExp(phase1Ref10Exp, new APlusBinop(new TPlus("+")), intConst22);
            ABinopExp binop21 = new ABinopExp(phase2Ref9Exp, new APlusBinop(new TPlus("+")), phase1Ref11Exp);
            ASimpleInvokeExp invokeStringSub6 = new ASimpleInvokeExp(new TIdentifier("StringSub"),
                                                           new ArrayList() { outputRef12Exp, binop20, binop21 });
            methodBlock.GetStatements().Add(new AValueReturnStm(new TReturn("return"), invokeStringSub6));

            AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                 new ANamedType(new TIdentifier("string"), null),
                                                 new TIdentifier("Galaxypp_Deobfuscate"), new ArrayList() {stringParam},
                                                 methodBlock);

            //Fix data refferences.. I got tired here.

            return method;
        }
        /*public override void CaseAShadyLocalDecl(AShadyLocalDecl node)
        {
            bool hasIdentifier = node. node.GetName() != null;
            if (hasIdentifier)
            {//Replace with a non shady local decl
                if (node.GetInit() != null)
                    errors.Add(new ErrorCollection.Error(node.GetName(), currentSourceFile, "Array declarations cannot be initialized", false));

                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, node.GetConst(), node.GetType(), node.GetName(), null);
                node.ReplaceBy(localDecl);
                localDecl.Apply(this);
            }
            else
            {
                //If it is not a declaration, it is an assignment exp, so we must have a right side
                if (node.GetInit() == null)
                {
                    errors.Add(new ErrorCollection.Error(GetToken(node.GetType()), currentSourceFile, "Expected assignment", false));
                    node.Parent().RemoveChild(node);
                    return;
                }
                //If it says const first, we got an error
                if (node.GetConst() != null)
                    errors.Add(new ErrorCollection.Error(node.GetConst(), currentSourceFile, "Unexpected const", false));

                ALocalDeclStm parent = (ALocalDeclStm)node.Parent();
                PLvalue lvalue = DetypeArray(node.GetType());
                ASAssignmentExp exp = new ASAssignmentExp(node.GetAssignop(), lvalue, node.GetInit());
                AExpStm stm = new AExpStm(parent.GetToken(), exp);
                parent.ReplaceBy(stm);
                stm.Apply(this);
            }
        }*/
        public override void OutAALocalDecl(AALocalDecl node)
        {
            if (Util.GetAncestor<AABlock>(node) != null)
            {//We are a local defined inside a method
                if (node.GetConst() != null && node.GetInit() == null)
                    errors.Add(new ErrorCollection.Error(node.GetConst(), currentSourceFile, LocRM.GetString("ErrorText190"), false));
            }
            else if (Util.HasAncestor<AMethodDecl>(node) || Util.HasAncestor<AConstructorDecl>(node))
            {//We are in a parameter
                if (node.GetConst() != null)
                    errors.Add(new ErrorCollection.Error(node.GetConst(), currentSourceFile, LocRM.GetString("ErrorText191"), false));
            }
            else
            {
                //Struct var
                if (node.GetConst() != null && node.GetInit() == null)
                    errors.Add(new ErrorCollection.Error(node.GetConst(), currentSourceFile, LocRM.GetString("ErrorText190"), false));
            }

            base.OutAALocalDecl(node);
        }
 public VariableDecl(AFieldDecl field, AALocalDecl local, VariableDecl @base)
 {
     Field = field;
     Local = local;
     Base = @base;
 }
        public override void OutAEnumDecl(AEnumDecl node)
        {
            AStructDecl replacer = new AStructDecl(node.GetVisibilityModifier(), null, null, null, node.GetEndToken(),
                                                   node.GetName(), new ArrayList(), null, new ArrayList());

            TIdentifier typeIdentifier = new TIdentifier("byte");
            ASwitchStm switchStm = new ASwitchStm(new TSwitch("switch"),
                                                  new ALvalueExp(
                                                      new AAmbiguousNameLvalue(new AAName(new ArrayList() {new TIdentifier("enum")}))),
                                                  new ArrayList());
                ;
            AMethodDecl toStringMethod = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                         new ANamedType(new TIdentifier("string"), null),
                                                         new TIdentifier("toString"),
                                                         new ArrayList()
                                                             {
                                                                 new AALocalDecl(new APublicVisibilityModifier(), null,
                                                                                 null, null, null,
                                                                                 new ANamedType(typeIdentifier, null),
                                                                                 new TIdentifier("enum"), null)
                                                             },
                                                         new AABlock(
                                                             new ArrayList()
                                                                 {
                                                                     switchStm,
                                                                     new AValueReturnStm(new TReturn("return"), new ANullExp())
                                                                 }, new TRBrace("}")));
            replacer.GetLocals().Add(new ADeclLocalDecl(toStringMethod));

            int intVal = 0;
            int min = int.MaxValue;
            int max = int.MinValue;
            List<TIdentifier> types = new List<TIdentifier>(){typeIdentifier};
            Dictionary<int, List<AALocalDecl>> usedValues = new Dictionary<int, List<AALocalDecl>>();
            foreach (AAEnumLocal value in node.GetValues())
            {
                AIntConstExp intConst;
                if (value.GetValue() != null)
                {
                    intConst = (AIntConstExp) value.GetValue();
                    intVal = int.Parse(intConst.GetIntegerLiteral().Text) + 1;
                }
                else
                {
                    intConst = new AIntConstExp(new TIntegerLiteral(intVal.ToString(), value.GetName().Line, value.GetName().Pos));
                    intVal++;
                }
                min = Math.Min(intVal - 1, min);
                max = Math.Max(intVal - 1, max);
                typeIdentifier = new TIdentifier("byte", value.GetName().Line, value.GetName().Pos);
                types.Add(typeIdentifier);
                switchStm.GetCases().Add(
                    new ASwitchCaseStm(new ACaseSwitchCaseType(new TCase("case"), (PExp) intConst.Clone()),
                                       new AABlock(
                                           new ArrayList()
                                               {
                                                   new AValueReturnStm(new TReturn("return"),
                                                                       new AStringConstExp(
                                                                           new TStringLiteral("\"" +
                                                                                              value.GetName().Text +
                                                                                              "\"")))
                                               }, new TRBrace("}"))));
                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(),
                                                        new TStatic("static", value.GetName().Line, value.GetName().Pos),
                                                        null, null,
                                                        new TConst("const", value.GetName().Line, value.GetName().Pos),
                                                        new ANamedType(typeIdentifier, null), value.GetName(), intConst);
                replacer.GetLocals().Add(localDecl);
                if (!usedValues.ContainsKey(intVal - 1))
                    usedValues[intVal - 1] = new List<AALocalDecl>();
                usedValues[intVal - 1].Add(localDecl);
            }
            if (min < 0 || max > 255)
                foreach (TIdentifier identifier in types)
                {
                    identifier.Text = "int";
                }
            node.ReplaceBy(replacer);
            foreach (KeyValuePair<int, List<AALocalDecl>> pair in usedValues)
            {
                if (pair.Value.Count <= 1)
                    continue;
                int value = pair.Key;
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (AALocalDecl decl in pair.Value)
                {
                    subErrors.Add(new ErrorCollection.Error(decl.GetName(), LocRM.GetString("ErrorText179")));
                }
                errors.Add(new ErrorCollection.Error(replacer.GetName(), LocRM.GetString("ErrorText180") + value + ".", false, subErrors.ToArray()));
            }
            replacer.Apply(this);
            data.Enums.Add(replacer, min < 0 || max > 255);
        }