public override void CaseAAssignmentExp(AAssignmentExp node)
        {
            if (!(node.Parent() is AExpStm))
            {
                PStm parentStm = Util.GetAncestor<PStm>(node);

                MoveMethodDeclsOut mover = new MoveMethodDeclsOut("multipleAssignmentsVar", finalTrans.data);
                node.GetLvalue().Apply(mover);
                PLvalue lvalue = Util.MakeClone(node.GetLvalue(), finalTrans.data);
                ALvalueExp exp = new ALvalueExp(lvalue);
                finalTrans.data.ExpTypes[exp] = finalTrans.data.LvalueTypes[lvalue];
                node.ReplaceBy(exp);

                AExpStm stm = new AExpStm(new TSemicolon(";"), node);

                AABlock block = (AABlock) parentStm.Parent();
                //block.GetStatements().Insert(block.GetStatements().IndexOf(parentStm), localDeclStm);
                block.GetStatements().Insert(block.GetStatements().IndexOf(parentStm), stm);

                //localDeclStm.Apply(this);
                stm.Apply(this);

                if (parentStm is AWhileStm && Util.IsAncestor(exp, ((AWhileStm)parentStm).GetCondition()))
                {
                    AWhileStm aStm = (AWhileStm)parentStm;
                    //Copy assignment before continues
                    //Before each continue in the while, and at the end.

                    //Add continue statement, if not present
                    block = (AABlock)((ABlockStm)aStm.GetBody()).GetBlock();
                    if (block.GetStatements().Count == 0 || !(block.GetStatements()[block.GetStatements().Count - 1] is AContinueStm))
                        block.GetStatements().Add(new AContinueStm(new TContinue("continue")));

                    //Get all continue statements in the while
                    ContinueFinder finder = new ContinueFinder();
                    block.Apply(finder);
                    foreach (AContinueStm continueStm in finder.Continues)
                    {
                        stm = new AExpStm(new TSemicolon(";"), Util.MakeClone(node, finalTrans.data));
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), stm);

                        stm.Apply(this);
                    }
                }
                return;
            }

            base.CaseAAssignmentExp(node);
        }
        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 override void OutAIncDecExp(AIncDecExp node)
        {
            PIncDecOp op = node.GetIncDecOp();
            if (!Util.HasAncestor<AABlock>(node))
            {
                Token token = null;
                if (op is APostDecIncDecOp)
                    token = ((APostDecIncDecOp) op).GetToken();
                else if (op is APreDecIncDecOp)
                    token = ((APreDecIncDecOp)op).GetToken();
                else if (op is APostIncIncDecOp)
                    token = ((APostIncIncDecOp)op).GetToken();
                else if (op is APreIncIncDecOp)
                    token = ((APreIncIncDecOp)op).GetToken();
                errors.Add(new ErrorCollection.Error(token, LocRM.GetString("ErrorText114")));
                throw new ParserException(token, "TypeChecking.OutAIncDecExp");
            }

            bool plus = op is APreIncIncDecOp || op is APostIncIncDecOp;
            if (op is APreIncIncDecOp || op is APreDecIncDecOp || node.Parent() is AExpStm)
            {//++i, --i, i++; or i--;
                //Replace with assignment
                //<exp>++ => <exp> + 1
                //(... foo = <exp> ...)++ => (... foo = <exp> ...) = (... foo ...) + 1
                //(... foo++ ...)++ => (... foo++ ...) = (... foo ...) + 1

                PLvalue clone = Util.MakeClone(node.GetLvalue(), data);
                clone.Apply(new AssignFixup(data));
                PBinop binop;
                if (plus)
                {
                    binop = new APlusBinop(new TPlus("+"));
                }
                else
                {
                    binop = new AMinusBinop(new TMinus("-"));
                }
                ABinopExp addExp = new ABinopExp(new ALvalueExp(clone), binop, new AIntConstExp(new TIntegerLiteral("1")));
                AAssignmentExp exp = new AAssignmentExp(new TAssign("="), node.GetLvalue(), addExp);
                node.ReplaceBy(exp);
                exp.Apply(this);
                return;
            }
            {//i++ or i--
                //Make a new local so
                //int newLocal = i;
                //++i;
                //...newLocal...;
                PLvalue lvalueClone = Util.MakeClone(node.GetLvalue(), data);
                PExp exp = new ALvalueExp(Util.MakeClone(node.GetLvalue(), data));
                data.ExpTypes[exp] = data.LvalueTypes[node.GetLvalue()];
                AALocalDecl localDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, Util.MakeClone(data.LvalueTypes[node.GetLvalue()], data), new TIdentifier("incDecVar"), exp);
                ALocalDeclStm localDeclStm = new ALocalDeclStm(new TSemicolon(";"), localDecl);

                node.SetIncDecOp(plus
                                     ? (PIncDecOp) new APreIncIncDecOp(new TPlusPlus("++"))
                                     : new APreDecIncDecOp(new TMinusMinus("--")));

                ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(localDecl.GetName().Text));
                exp = new ALvalueExp(lvalue);
                data.ExpTypes[exp] = data.LvalueTypes[lvalue] = data.LvalueTypes[node.GetLvalue()];
                data.LocalLinks[lvalue] = localDecl;

                PStm pStm = Util.GetAncestor<PStm>(node);
                node.ReplaceBy(exp);
                PStm nodeStm = new AExpStm(new TSemicolon(";"), node);

                AABlock block = (AABlock) pStm.Parent();

                block.GetStatements().Insert(block.GetStatements().IndexOf(pStm), localDeclStm);
                block.GetStatements().Insert(block.GetStatements().IndexOf(pStm), nodeStm);
                localDeclStm.Apply(this);
                nodeStm.Apply(this);
                exp.Apply(this);

                if (pStm is AWhileStm && Util.IsAncestor(exp, ((AWhileStm)pStm).GetCondition()))
                {
                    AWhileStm aStm = (AWhileStm)pStm;
                    //Insert
                    // newLocal = i
                    // ++i
                    //Before each continue in the while, and at the end.

                    //Add continue statement, if not present
                    block = (AABlock)((ABlockStm)aStm.GetBody()).GetBlock();
                    if (block.GetStatements().Count == 0 || !(block.GetStatements()[block.GetStatements().Count - 1] is AContinueStm))
                        block.GetStatements().Add(new AContinueStm(new TContinue("continue")));

                    //Get all continue statements in the while
                    ContinueFinder finder = new ContinueFinder();
                    block.Apply(finder);
                    foreach (AContinueStm continueStm in finder.Continues)
                    {
                        PLvalue nodeLvalue1 = Util.MakeClone(lvalueClone, data);
                        PExp nodeLvalue1Exp = new ALvalueExp(nodeLvalue1);
                        PLvalue nodeLvalue2 = Util.MakeClone(lvalueClone, data);
                        ALocalLvalue newLocalLvalue = new ALocalLvalue(new TIdentifier("newLocal"));
                        data.LocalLinks[newLocalLvalue] = localDecl;
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), newLocalLvalue, nodeLvalue1Exp);
                        PStm assignmentStm = new AExpStm(new TSemicolon(";"), assignment);

                        AIncDecExp newIncDecExp = new AIncDecExp(nodeLvalue2, plus
                                                                                  ? (PIncDecOp)
                                                                                    new APreIncIncDecOp(
                                                                                        new TPlusPlus("++"))
                                                                                  : new APreDecIncDecOp(
                                                                                        new TMinusMinus("--")));
                        PStm newIncDecExpStm = new AExpStm(new TSemicolon(";"), newIncDecExp);

                        block = (AABlock)continueStm.Parent();
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), assignmentStm);
                        block.GetStatements().Insert(block.GetStatements().IndexOf(continueStm), newIncDecExpStm);

                        assignment.Apply(this);
                        newIncDecExp.Apply(this);
                    }
                }
                return;
            }
        }
Example #4
0
 ArrayList New388()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList6 = (ArrayList) Pop();
     ArrayList nodeArrayList5 = (ArrayList) Pop();
     ArrayList nodeArrayList4 = (ArrayList) Pop();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TypedList listNode8 = new TypedList();
     PLvalue plvalueNode3 = (PLvalue)nodeArrayList1[0];
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TDot tdotNode5 = (TDot)nodeArrayList2[0];
     ADotDotType pdottypeNode4 = new ADotDotType (
       tdotNode5
     );
     TIdentifier tidentifierNode6 = (TIdentifier)nodeArrayList3[0];
     TypedList listNode7 = (TypedList)nodeArrayList5[0];
     if ( listNode7 != null )
     {
     listNode8.AddAll(listNode7);
     }
     ANonstaticInvokeExp pexpNode1 = new ANonstaticInvokeExp (
       pexpNode2,
       pdottypeNode4,
       tidentifierNode6,
       listNode8
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
        public override void OutACastExp(ACastExp node)
        {
            string toType = ((AAName)((ANamedType) node.GetType()).GetName()).AsString();
            string fromType;
            PType fromPType = data.ExpTypes[node.GetExp()];
            AStructDecl toEnum = null;
            AStructDecl fromEnum = null;

            if (data.StructTypeLinks.ContainsKey((ANamedType)node.GetType()))
            {
                AStructDecl str = data.StructTypeLinks[(ANamedType)node.GetType()];
                if (data.Enums.ContainsKey(str))
                    toEnum = str;
            }
            if (fromPType is ANamedType)
            {
                fromType = ((AAName)((ANamedType)fromPType).GetName()).AsString();
                //Namespace ignored
                if (data.StructTypeLinks.ContainsKey((ANamedType) fromPType))
                {
                    AStructDecl str = data.StructTypeLinks[(ANamedType) fromPType];
                    if (data.Enums.ContainsKey(str))
                        fromEnum = str;
                }
            }
            else
            {
                errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText121")));
                throw new ParserException(node.GetToken(), "Invalid cast");
            }

            if (toEnum != null && (fromType == "int" || fromType == "byte"))
            {
                ANamedType type = new ANamedType(new TIdentifier(toEnum.GetName().Text), null);
                data.StructTypeLinks[type] = toEnum;
                data.ExpTypes[node.GetExp()] = type;
                node.ReplaceBy(node.GetExp());
                return;
            }

            if (fromEnum != null && (toType == "int" || toType == "byte"))
            {
                int enumDefinitions = 0;
                foreach (PLocalDecl local in fromEnum.GetLocals())
                {
                    if (local is AALocalDecl)
                        enumDefinitions++;
                }
                string typeName = enumDefinitions > 255 ? "int" : "byte";
                ANamedType type = new ANamedType(new TIdentifier(typeName), null);
                data.ExpTypes[node.GetExp()] = new ANamedType(new TIdentifier(typeName), null);
                node.ReplaceBy(node.GetExp());
                return;
            }

            if (fromEnum != null && toType == "string")
            {
                AMethodDecl targetMethod = data.StructMethods[fromEnum][0];
                ASimpleInvokeExp invokeExp = new ASimpleInvokeExp(new TIdentifier("toString"), new ArrayList(){node.GetExp()});
                data.SimpleMethodLinks[invokeExp] = targetMethod;
                data.ExpTypes[invokeExp] = targetMethod.GetReturnType();
                node.ReplaceBy(invokeExp);
                return;
            }

            ASimpleInvokeExp replacementMethod = null;
            switch (toType)
            {
                case "string":
                    switch (fromType)
                    {
                        case "wave":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToString"), new ArrayList{node.GetExp()});
                            break;
                        case "fixed"://Implicit
                            AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny"));
                            ALvalueExp exp = new ALvalueExp(precisionArg);
                            data.FieldLinks[precisionArg] =
                                data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text);
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToString"), new ArrayList { node.GetExp(), exp});
                            break;
                        case "int"://Implicit
                        case "byte"://Implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToString"), new ArrayList { node.GetExp()});
                            break;
                        case "bool"://Implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToString"), new ArrayList { node.GetExp() });
                            break;
                        case "color"://Implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertColorToString"), new ArrayList { node.GetExp() });
                            break;
                    }
                    break;
                case "text":
                    switch (fromType)
                    {
                        case "wave":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("AIWaveToText"), new ArrayList { node.GetExp() });
                            break;
                        case "fixed"://Implicit
                            AFieldLvalue precisionArg = new AFieldLvalue(new TIdentifier("c_fixedPrecisionAny"));
                            ALvalueExp exp = new ALvalueExp(precisionArg);
                            data.FieldLinks[precisionArg] =
                                data.Libraries.Fields.First(field => field.GetName().Text == precisionArg.GetName().Text);
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToText"), new ArrayList { node.GetExp(), exp });
                            break;
                        case "int"://Implicit
                        case "byte":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToText"), new ArrayList { node.GetExp() });
                            break;
                        case "bool"://Implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("libNtve_gf_ConvertBooleanToText"), new ArrayList { node.GetExp() });
                            break;
                        case "string"://Implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToText"), new ArrayList { node.GetExp() });
                            break;
                    }
                    break;
                case "int":
                    switch (fromType)
                    {
                        case "bool":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("BoolToInt"), new ArrayList {node.GetExp()});
                            break;
                        case "fixed":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("FixedToInt"), new ArrayList { node.GetExp() });
                            break;
                        case "string":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToInt"), new ArrayList { node.GetExp() });
                            break;
                    }
                    break;
                case "fixed":
                    switch (fromType)
                    {
                        case "int"://Already implicit
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("IntToFixed"), new ArrayList { node.GetExp() });
                            break;
                        case "string":
                            replacementMethod = new ASimpleInvokeExp(new TIdentifier("StringToFixed"), new ArrayList { node.GetExp() });
                            break;
                    }
                    break;
                case "bool":
                    switch (fromType)
                    {
                        case "int":
                        case "byte":
                        case "fixed":
                            //Replace by
                            //exp != 0
                            AIntConstExp zero = new AIntConstExp(new TIntegerLiteral("0"));
                            ABinopExp binop = new ABinopExp(node.GetExp(), new ANeBinop(new TNeq("!=")), zero);
                            node.ReplaceBy(binop);

                            binop.Apply(this);
                            return;
                    }
                    break;
            }

            if (replacementMethod == null)
            {
                errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText122") + fromType + LocRM.GetString("ErrorText123") + toType));
                throw new ParserException(node.GetToken(), LocRM.GetString("ErrorText121"));
            }

            data.SimpleMethodLinks[replacementMethod] =
                data.Libraries.Methods.First(method => method.GetName().Text == replacementMethod.GetName().Text);
            data.ExpTypes[replacementMethod] = data.SimpleMethodLinks[replacementMethod].GetReturnType();
            node.ReplaceBy(replacementMethod);
            for (int i = 1; i < replacementMethod.GetArgs().Count; i++)
            {
                ((Node)replacementMethod.GetArgs()[i]).Apply(this);
            }
        }
 public virtual void InALvalueExp(ALvalueExp node)
 {
     DefaultIn(node);
 }
Example #7
0
 ArrayList New393()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList6 = (ArrayList) Pop();
     ArrayList nodeArrayList5 = (ArrayList) Pop();
     ArrayList nodeArrayList4 = (ArrayList) Pop();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TypedList listNode9 = new TypedList();
     TValue tvalueNode4 = (TValue)nodeArrayList1[0];
     AValueLvalue plvalueNode3 = new AValueLvalue (
       tvalueNode4
     );
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TArrow tarrowNode6 = (TArrow)nodeArrayList2[0];
     AArrowDotType pdottypeNode5 = new AArrowDotType (
       tarrowNode6
     );
     TIdentifier tidentifierNode7 = (TIdentifier)nodeArrayList3[0];
     TypedList listNode8 = (TypedList)nodeArrayList5[0];
     if ( listNode8 != null )
     {
     listNode9.AddAll(listNode8);
     }
     ANonstaticInvokeExp pexpNode1 = new ANonstaticInvokeExp (
       pexpNode2,
       pdottypeNode5,
       tidentifierNode7,
       listNode9
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
 public override void CaseAAssignmentExp(AAssignmentExp node)
 {
     ALvalueExp replacer = new ALvalueExp(node.GetLvalue());
     data.ExpTypes[replacer] = data.LvalueTypes[replacer.GetLvalue()];
     node.ReplaceBy(replacer);
     replacer.Apply(this);
 }
        public override void OutAPointerMultiLvalue(APointerMultiLvalue node)
        {
            ALvalueExp lvalueExp;
            APointerLvalue pointerLvalue = new APointerLvalue((TStar) node.GetTokens()[0], node.GetBase());

            while (node.GetTokens().Count > 0)
            {
                lvalueExp = new ALvalueExp(pointerLvalue);
                pointerLvalue = new APointerLvalue((TStar) node.GetTokens()[0], lvalueExp);
            }

            node.ReplaceBy(pointerLvalue);
            pointerLvalue.Apply(this);
        }
Example #10
0
 ArrayList New575()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     PLvalue plvalueNode3 = (PLvalue)nodeArrayList1[0];
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TDot tdotNode5 = (TDot)nodeArrayList2[0];
     ADotDotType pdottypeNode4 = new ADotDotType (
       tdotNode5
     );
     TIdentifier tidentifierNode6 = (TIdentifier)nodeArrayList3[0];
     AStructLvalue plvalueNode1 = new AStructLvalue (
       pexpNode2,
       pdottypeNode4,
       tidentifierNode6
     );
     nodeList.Add(plvalueNode1);
     return nodeList;
 }
Example #11
0
 ArrayList New576()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TThis tthisNode4 = (TThis)nodeArrayList1[0];
     AThisLvalue plvalueNode3 = new AThisLvalue (
       tthisNode4
     );
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TDot tdotNode6 = (TDot)nodeArrayList2[0];
     ADotDotType pdottypeNode5 = new ADotDotType (
       tdotNode6
     );
     TIdentifier tidentifierNode7 = (TIdentifier)nodeArrayList3[0];
     AStructLvalue plvalueNode1 = new AStructLvalue (
       pexpNode2,
       pdottypeNode5,
       tidentifierNode7
     );
     nodeList.Add(plvalueNode1);
     return nodeList;
 }
Example #12
0
 ArrayList New427()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TThis tthisNode3 = (TThis)nodeArrayList1[0];
     AThisLvalue plvalueNode2 = new AThisLvalue (
       tthisNode3
     );
     ALvalueExp pexpNode1 = new ALvalueExp (
       plvalueNode2
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
Example #13
0
 ArrayList New428()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TValue tvalueNode3 = (TValue)nodeArrayList1[0];
     AValueLvalue plvalueNode2 = new AValueLvalue (
       tvalueNode3
     );
     ALvalueExp pexpNode1 = new ALvalueExp (
       plvalueNode2
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
Example #14
0
 ArrayList New426()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     PLvalue plvalueNode2 = (PLvalue)nodeArrayList1[0];
     ALvalueExp pexpNode1 = new ALvalueExp (
       plvalueNode2
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
Example #15
0
 ArrayList New425()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TIdentifier tidentifierNode3 = (TIdentifier)nodeArrayList3[0];
     AStructFieldLvalue plvalueNode2 = new AStructFieldLvalue (
       tidentifierNode3
     );
     ALvalueExp pexpNode1 = new ALvalueExp (
       plvalueNode2
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
Example #16
0
 ArrayList New422()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TypedList listNode5 = new TypedList();
     TypedList listNode4 = (TypedList)nodeArrayList1[0];
     if ( listNode4 != null )
     {
     listNode5.AddAll(listNode4);
     }
     AAName pnameNode3 = new AAName (
       listNode5
     );
     AAmbiguousNameLvalue plvalueNode2 = new AAmbiguousNameLvalue (
       pnameNode3
     );
     ALvalueExp pexpNode1 = new ALvalueExp (
       plvalueNode2
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
        public static void GetTargets(string name,
            Token node,
            Node reciever, //Either null, AAName, or PExp
            PType returnType, //Either null, or Some type the method return type must be assignable to
            List<PType> argTypes,
            List<AMethodDecl> candidates,
            out bool matchArrayResize,
            List<AMethodDecl> implicitCandidates,
            List<AMethodDecl> matchingNames,
            out PExp baseExp,
            List<AMethodDecl> matchingDelegates,
            SharedData data,
            ErrorCollection errors
            )
        {
            baseExp = null;
            matchArrayResize = false;
            if (reciever == null)
            {//A simple invoke
                //Look in current struct
                //Look in all visible namespaces
                //Look in library methods
                AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node);
                if (currentStruct != null)
                {
                    foreach (AMethodDecl methodDecl in data.StructMethods[currentStruct])
                    {
                        if (methodDecl.GetName().Text == name &&
                            methodDecl.GetFormals().Count == argTypes.Count &&
                            methodDecl.GetDelegate() == null)
                        {
                            matchingNames.Add(methodDecl);

                            //Visibility
                            if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct)
                                continue;
                            if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier &&
                                !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data))
                                continue;
                            if (methodDecl.GetStatic() == null &&
                                Util.IsStaticContext(node))
                                continue;

                            //Check return type
                            if (returnType != null && !(returnType is AVoidType) &&
                                !Assignable(methodDecl.GetReturnType(), returnType))
                                continue;

                            //Check that parameters are assignable
                            bool add = true;
                            bool matchImplicit = false;
                            for (int i = 0; i < argTypes.Count; i++)
                            {
                                PType argType = argTypes[i];
                                AALocalDecl formal = (AALocalDecl) methodDecl.GetFormals()[i];
                                PType formalType = formal.GetType();
                                if (formal.GetOut() != null && !Assignable(formalType, argType)
                                    ||
                                    formal.GetRef() != null &&
                                    !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                    ||
                                    formal.GetOut() == null && formal.GetRef() == null &&
                                    !Assignable(argType, formalType))
                                {
                                    add = false;
                                    if (formal.GetOut() == null && formal.GetRef() == null &&
                                        ImplicitAssignable(argType, formalType))
                                    {
                                        matchImplicit = true;
                                    }
                                    else
                                    {
                                        matchImplicit = false;
                                        break;
                                    }
                                }
                            }
                            if (!add && !matchImplicit)
                                continue;
                            if (candidates.Count == 0)
                            {//Set base exp
                                if (methodDecl.GetStatic() != null)
                                {
                                    //Calling static method
                                    baseExp = null;
                                }
                                else if (currentStruct.GetClassToken() != null || Util.HasAncestor<AConstructorDecl>(node) || Util.HasAncestor<ADeconstructorDecl>(node))
                                {//Dynamic context
                                    baseExp = new ALvalueExp(new APointerLvalue(new TStar("*"),
                                                                 new ALvalueExp(new AThisLvalue(new TThis("this")))));
                                }
                                else
                                {//Struct method to struct method
                                    baseExp = null;
                                }
                            }
                            if (add)
                                candidates.Add(methodDecl);
                            if (matchImplicit)
                                implicitCandidates.Add(methodDecl);
                        }
                    }
                }
                if (candidates.Count + implicitCandidates.Count == 0)
                {
                    //Global methods
                    List<IList> visibleDecls = Util.GetVisibleDecls(node, true);
                    AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node);
                    List<string> currentNamespace = Util.GetFullNamespace(node);
                    foreach (IList declList in visibleDecls)
                    {
                        bool isSameFile = false;
                        bool isSameNamespace = false;
                        if (declList.Count > 0)
                        {
                            isSameFile = currentFile == Util.GetAncestor<AASourceFile>((PDecl) declList[0]);
                            isSameNamespace = Util.NamespacesEquals(currentNamespace,
                                                                    Util.GetFullNamespace((PDecl) declList[0]));
                        }
                        foreach (PDecl decl in declList)
                        {
                            if (decl is AMethodDecl)
                            {
                                AMethodDecl methodDecl = (AMethodDecl) decl;
                                if (methodDecl.GetName().Text == name &&
                                    methodDecl.GetFormals().Count == argTypes.Count &&
                                    methodDecl.GetDelegate() == null)
                                {
                                    matchingNames.Add(methodDecl);

                                    //Visibility
                                    if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                        !isSameNamespace)
                                        continue;
                                    if (methodDecl.GetStatic() != null &&
                                        !isSameFile)
                                        continue;
                                    //Check return type
                                    if (returnType != null && !(returnType is AVoidType) &&
                                        !Assignable(methodDecl.GetReturnType(), returnType))
                                        continue;

                                    //Check that parameters are assignable
                                    bool add = true;
                                    bool matchImplicit = false;
                                    for (int i = 0; i < argTypes.Count; i++)
                                    {
                                        PType argType = argTypes[i];
                                        AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[i];
                                        PType formalType = formal.GetType();
                                        if (formal.GetOut() != null && !Assignable(formalType, argType)
                                            ||
                                            formal.GetRef() != null &&
                                            !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                            ||
                                            formal.GetOut() == null && formal.GetRef() == null &&
                                            !Assignable(argType, formalType))
                                        {
                                            add = false;
                                            if (formal.GetOut() == null && formal.GetRef() == null &&
                                                ImplicitAssignable(argType, formalType))
                                            {
                                                matchImplicit = true;
                                            }
                                            else
                                            {
                                                matchImplicit = false;
                                                break;
                                            }
                                        }
                                    }
                                    if (!add && !matchImplicit)
                                        continue;
                                    if (add)
                                        candidates.Add(methodDecl);
                                    if (matchImplicit)
                                        implicitCandidates.Add(methodDecl);
                                }
                            }
                        }
                    }
                    //Library methods
                    foreach (AMethodDecl methodDecl in data.Libraries.Methods)
                    {
                        if (methodDecl.GetName().Text == name &&
                            methodDecl.GetFormals().Count == argTypes.Count &&
                            methodDecl.GetDelegate() == null)
                        {
                            matchingNames.Add(methodDecl);

                            //Visibility
                            //Okay, the library doesn't have any private methods. But hey.
                            if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                currentNamespace.Count > 0)
                                continue;
                            if (methodDecl.GetStatic() != null)
                                continue;
                            //Check return type
                            if (returnType != null && !(returnType is AVoidType) &&
                                !Assignable(methodDecl.GetReturnType(), returnType))
                                continue;

                            //Check that parameters are assignable
                            bool add = true;
                            bool matchImplicit = false;
                            for (int i = 0; i < argTypes.Count; i++)
                            {
                                PType argType = argTypes[i];
                                AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[i];
                                PType formalType = formal.GetType();
                                if (formal.GetOut() != null && !Assignable(formalType, argType)
                                    ||
                                    formal.GetRef() != null &&
                                    !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                    ||
                                    formal.GetOut() == null && formal.GetRef() == null &&
                                    !Assignable(argType, formalType))
                                {
                                    add = false;
                                    if (formal.GetOut() == null && formal.GetRef() == null &&
                                        ImplicitAssignable(argType, formalType))
                                    {
                                        matchImplicit = true;
                                    }
                                    else
                                    {
                                        matchImplicit = false;
                                        break;
                                    }
                                }
                            }
                            if (!add && !matchImplicit)
                                continue;
                            if (add)
                                candidates.Add(methodDecl);
                            if (matchImplicit)
                                implicitCandidates.Add(methodDecl);
                        }
                    }
                }
            }
            else if (reciever is AAName)
            {//Lookup possibilities for reciever
                List<List<Node>>[] targets;
                List<ANamespaceDecl> namespaces = new List<ANamespaceDecl>();
                bool reportedError;

                TypeLinking.GetTargets((AAName)reciever, out targets, namespaces, data, errors, out reportedError);

                if (reportedError)
                    throw new ParserException(node, "TypeChecking.GetTargets");

                AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node);
                int iteration;
                for (iteration = 0; iteration < targets.Length; iteration++)
                {
                    List<Node> matchingList = null;
                    foreach (List<Node> list in targets[iteration])
                    {
                        Node last = list[list.Count - 1];
                        PType type = null;
                        if (last is AALocalDecl)
                        {
                            type = ((AALocalDecl) last).GetType();
                        }
                        else if (last is APropertyDecl)
                        {
                            type = ((APropertyDecl) last).GetType();
                        }
                        else if (last is AFieldDecl)
                        {
                            type = ((AFieldDecl) last).GetType();
                        }
                        else if (last is TIdentifier)
                        {
                            type = new ANamedType(new TIdentifier("int"), null);
                        }
                        if (last is AStructDecl)
                        {
                            //Special. Static only
                            AStructDecl structDecl = ((AStructDecl)last);
                            foreach (AMethodDecl methodDecl in data.StructMethods[structDecl])
                            {
                                if (methodDecl.GetName().Text == name &&
                                    methodDecl.GetFormals().Count == argTypes.Count &&
                                    methodDecl.GetDelegate() == null)
                                {
                                    matchingNames.Add(methodDecl);

                                    //Visibility
                                    if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                        Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct)
                                        continue;
                                    if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier &&
                                        !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data))
                                        continue;
                                    if (methodDecl.GetStatic() == null)
                                        continue;
                                    //Check return type
                                    if (returnType != null && !(returnType is AVoidType) &&
                                        !Assignable(methodDecl.GetReturnType(), returnType))
                                        continue;
                                    //Check that parameters are assignable
                                    bool add = true;
                                    bool matchImplicit = false;
                                    for (int j = 0; j < argTypes.Count; j++)
                                    {
                                        PType argType = argTypes[j];
                                        AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j];
                                        PType formalType = formal.GetType();
                                        if (formal.GetOut() != null && !Assignable(formalType, argType)
                                            ||
                                            formal.GetRef() != null &&
                                            !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                            ||
                                            formal.GetOut() == null && formal.GetRef() == null &&
                                            !Assignable(argType, formalType))
                                        {
                                            add = false;
                                            if (formal.GetOut() == null && formal.GetRef() == null &&
                                                ImplicitAssignable(argType, formalType))
                                            {
                                                matchImplicit = true;
                                            }
                                            else
                                            {
                                                matchImplicit = false;
                                                break;
                                            }
                                        }
                                    }
                                    if (!add && !matchImplicit)
                                        continue;
                                    if (candidates.Count == 0)
                                    {//Set base exp
                                        //Calling static method
                                        baseExp = null;
                                    }
                                    if (add)
                                        candidates.Add(methodDecl);
                                    if (matchImplicit)
                                        implicitCandidates.Add(methodDecl);

                                }
                            }
                        }
                        else
                        {
                            //Find methods based on baseType
                            if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType) type) && !(data.Enums.ContainsKey(data.StructTypeLinks[(ANamedType) type])))
                            {
                                //Non static only
                                AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type];
                                foreach (AMethodDecl methodDecl in data.StructMethods[structDecl])
                                {
                                    if (methodDecl.GetName().Text == name &&
                                        methodDecl.GetFormals().Count == argTypes.Count &&
                                        methodDecl.GetDelegate() == null)
                                    {
                                        matchingNames.Add(methodDecl);

                                        //Visibility
                                        if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                            Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct)
                                            continue;
                                        if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier &&
                                            !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data))
                                            continue;
                                        if (methodDecl.GetStatic() != null)
                                            continue;
                                        //Check return type
                                        if (returnType != null && !(returnType is AVoidType) &&
                                            !Assignable(methodDecl.GetReturnType(), returnType))
                                            continue;
                                        //Check that parameters are assignable
                                        bool add = true;
                                        bool matchImplicit = false;
                                        for (int j = 0; j < argTypes.Count; j++)
                                        {
                                            PType argType = argTypes[j];
                                            AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j];
                                            PType formalType = formal.GetType();
                                            if (formal.GetOut() != null && !Assignable(formalType, argType)
                                                ||
                                                formal.GetRef() != null &&
                                                !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                                ||
                                                formal.GetOut() == null && formal.GetRef() == null &&
                                                !Assignable(argType, formalType))
                                            {
                                                add = false;
                                                if (formal.GetOut() == null && formal.GetRef() == null &&
                                                    ImplicitAssignable(argType, formalType))
                                                {
                                                    matchImplicit = true;
                                                }
                                                else
                                                {
                                                    matchImplicit = false;
                                                    break;
                                                }
                                            }
                                        }
                                        if (!add && !matchImplicit)
                                            continue;
                                        if (candidates.Count == 0 && implicitCandidates.Count == 0)
                                        {//Set base exp
                                            baseExp = new ALvalueExp(TypeLinking.Link((AAName) reciever, node, list, data));
                                        }
                                        if (add)
                                            candidates.Add(methodDecl);
                                        if (matchImplicit)
                                            implicitCandidates.Add(methodDecl);
                                    }
                                }
                            }
                            else if (type is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType)type))
                            {
                                if (matchingDelegates != null && name == "Invoke")
                                {
                                    AMethodDecl delegateDecl = data.DelegateTypeLinks[(ANamedType) type];
                                    if (delegateDecl.GetFormals().Count == argTypes.Count)
                                    {
                                        matchingNames.Add(delegateDecl);

                                        //Check return type
                                        if (returnType != null && !(returnType is AVoidType) &&
                                            !Assignable(delegateDecl.GetReturnType(), returnType))
                                            continue;
                                        //Check that parameters are assignable
                                        bool add = true;
                                        bool matchImplicit = false;
                                        for (int j = 0; j < argTypes.Count; j++)
                                        {
                                            PType argType = argTypes[j];
                                            AALocalDecl formal = (AALocalDecl)delegateDecl.GetFormals()[j];
                                            PType formalType = formal.GetType();
                                            if (formal.GetOut() != null && !Assignable(formalType, argType)
                                                ||
                                                formal.GetRef() != null &&
                                                !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                                ||
                                                formal.GetOut() == null && formal.GetRef() == null &&
                                                !Assignable(argType, formalType))
                                            {
                                                add = false;
                                                if (formal.GetOut() == null && formal.GetRef() == null &&
                                                    ImplicitAssignable(argType, formalType))
                                                {
                                                    matchImplicit = true;
                                                }
                                                else
                                                {
                                                    matchImplicit = false;
                                                    break;
                                                }
                                            }
                                        }
                                        if (!add && !matchImplicit)
                                            continue;
                                        matchingDelegates.Add(delegateDecl);
                                        if (candidates.Count == 0 && implicitCandidates.Count == 0)
                                        {//Set base exp
                                            baseExp = new ALvalueExp(TypeLinking.Link((AAName)reciever, node, list, data));
                                        }
                                        if (add)
                                            candidates.Add(delegateDecl);
                                        if (matchImplicit)
                                            implicitCandidates.Add(delegateDecl);

                                    }
                                }
                            }
                            else
                            {
                                //Look for enrichments
                                List<IList> visibleDecls = Util.GetVisibleDecls(node, true);
                                AEnrichmentDecl currentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node);
                                foreach (IList declList in visibleDecls)
                                {
                                    foreach (PDecl decl in declList)
                                    {
                                        if (decl is AEnrichmentDecl)
                                        {
                                            AEnrichmentDecl enrichment = (AEnrichmentDecl) decl;
                                            if (!Util.TypesEqual(type, enrichment.GetType(), data))
                                                continue;
                                            foreach (PDecl enrichmentDecl in enrichment.GetDecl())
                                            {
                                                if (enrichmentDecl is AMethodDecl)
                                                {
                                                    AMethodDecl methodDecl = (AMethodDecl) enrichmentDecl;

                                                    if (methodDecl.GetName().Text == name &&
                                                        methodDecl.GetFormals().Count == argTypes.Count &&
                                                        methodDecl.GetDelegate() == null)
                                                    {
                                                        matchingNames.Add(methodDecl);

                                                        //Visibility
                                                        if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                                            enrichment != currentEnrichment)
                                                            continue;
                                                        if (methodDecl.GetStatic() != null)
                                                            continue;
                                                        //Check return type
                                                        if (returnType != null && !(returnType is AVoidType) &&
                                                            !Assignable(methodDecl.GetReturnType(), returnType))
                                                            continue;
                                                        //Check that parameters are assignable
                                                        bool add = true;
                                                        bool matchImplicit = false;
                                                        for (int j = 0; j < argTypes.Count; j++)
                                                        {
                                                            PType argType = argTypes[j];
                                                            AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j];
                                                            PType formalType = formal.GetType();
                                                            if (formal.GetOut() != null && !Assignable(formalType, argType)
                                                                ||
                                                                formal.GetRef() != null &&
                                                                !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                                                ||
                                                                formal.GetOut() == null && formal.GetRef() == null &&
                                                                !Assignable(argType, formalType))
                                                            {
                                                                add = false;
                                                                if (formal.GetOut() == null && formal.GetRef() == null &&
                                                                    ImplicitAssignable(argType, formalType))
                                                                {
                                                                    matchImplicit = true;
                                                                }
                                                                else
                                                                {
                                                                    matchImplicit = false;
                                                                    break;
                                                                }
                                                            }
                                                        }
                                                        if (!add && !matchImplicit)
                                                            continue;
                                                        if (candidates.Count == 0 && implicitCandidates.Count == 0)
                                                        {//Set base exp
                                                            baseExp = new ALvalueExp(TypeLinking.Link((AAName)reciever, node, list, data));
                                                        }
                                                        if (add)
                                                            candidates.Add(methodDecl);
                                                        if (matchImplicit)
                                                            implicitCandidates.Add(methodDecl);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (candidates.Count + implicitCandidates.Count > 0)
                        break;
                }
                if (iteration >= 2)
                {//The search continued to global variables. Look in namespaces as well
                    AASourceFile currentFile = Util.GetAncestor<AASourceFile>(node);
                    List<string> currentNamespace = Util.GetFullNamespace(node);
                    foreach (ANamespaceDecl namespaceDecl in namespaces)
                    {
                        bool isSameFile = Util.GetAncestor<AASourceFile>(namespaceDecl) == currentFile;
                        bool isSameNamespace = Util.NamespacesEquals(currentNamespace,
                                                                     Util.GetFullNamespace(namespaceDecl));
                        foreach (PDecl decl in namespaceDecl.GetDecl())
                        {
                            if (decl is AMethodDecl)
                            {
                                AMethodDecl methodDecl = (AMethodDecl) decl;
                                if (methodDecl.GetName().Text == name &&
                                    methodDecl.GetFormals().Count == argTypes.Count &&
                                    methodDecl.GetDelegate() == null)
                                {
                                    matchingNames.Add(methodDecl);

                                    //Visibility
                                    if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                        !isSameNamespace)
                                        continue;
                                    if (methodDecl.GetStatic() != null &&
                                        !isSameFile)
                                        continue;
                                    //Check return type
                                    if (returnType != null && !(returnType is AVoidType) &&
                                        !Assignable(methodDecl.GetReturnType(), returnType))
                                        continue;

                                    //Check that parameters are assignable
                                    bool add = true;
                                    bool matchImplicit = false;
                                    for (int i = 0; i < argTypes.Count; i++)
                                    {
                                        PType argType = argTypes[i];
                                        AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[i];
                                        PType formalType = formal.GetType();
                                        if (formal.GetOut() != null && !Assignable(formalType, argType)
                                            ||
                                            formal.GetRef() != null &&
                                            !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                            ||
                                            formal.GetOut() == null && formal.GetRef() == null &&
                                            !Assignable(argType, formalType))
                                        {
                                            add = false;
                                            if (formal.GetOut() == null && formal.GetRef() == null &&
                                                ImplicitAssignable(argType, formalType))
                                            {
                                                matchImplicit = true;
                                            }
                                            else
                                            {
                                                matchImplicit = false;
                                                break;
                                            }
                                        }
                                    }
                                    if (!add && !matchImplicit)
                                        continue;
                                    if (add)
                                        candidates.Add(methodDecl);
                                    if (matchImplicit)
                                        implicitCandidates.Add(methodDecl);
                                }
                            }
                        }
                    }
                }
            }
            else
            {//Get base type from exp, and find matching enrichment/struct
                PType type = data.ExpTypes[(PExp) reciever];

                if (type is ADynamicArrayType && name == "Resize" && argTypes.Count == 1 && Assignable(argTypes[0], new ANamedType(new TIdentifier("int"), null)))
                {
                    matchArrayResize = true;
                    baseExp = (PExp) reciever;
                }

                AStructDecl currentStruct = Util.GetAncestor<AStructDecl>(node);
                if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type))
                {
                    //Non static only
                    AStructDecl structDecl = data.StructTypeLinks[(ANamedType)type];
                    foreach (AMethodDecl methodDecl in data.StructMethods[structDecl])
                    {
                        if (methodDecl.GetName().Text == name &&
                            methodDecl.GetFormals().Count == argTypes.Count &&
                            methodDecl.GetDelegate() == null)
                        {
                            matchingNames.Add(methodDecl);

                            //Visibility
                            if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                Util.GetAncestor<AStructDecl>(methodDecl) != currentStruct)
                                continue;
                            if (methodDecl.GetVisibilityModifier() is AProtectedVisibilityModifier &&
                                !Util.Extends(Util.GetAncestor<AStructDecl>(methodDecl), currentStruct, data))
                                continue;
                            if (methodDecl.GetStatic() != null)
                                continue;
                            //Check return type
                            if (returnType != null && !(returnType is AVoidType) &&
                                !Assignable(methodDecl.GetReturnType(), returnType))
                                continue;
                            //Check that parameters are assignable
                            bool add = true;
                            bool matchImplicit = false;
                            for (int j = 0; j < argTypes.Count; j++)
                            {
                                PType argType = argTypes[j];
                                AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j];
                                PType formalType = formal.GetType();
                                if (formal.GetOut() != null && !Assignable(formalType, argType)
                                    ||
                                    formal.GetRef() != null &&
                                    !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                    ||
                                    formal.GetOut() == null && formal.GetRef() == null &&
                                    !Assignable(argType, formalType))
                                {
                                    add = false;
                                    if (formal.GetOut() == null && formal.GetRef() == null &&
                                        ImplicitAssignable(argType, formalType))
                                    {
                                        matchImplicit = true;
                                    }
                                    else
                                    {
                                        matchImplicit = false;
                                        break;
                                    }
                                }
                            }
                            if (!add && !matchImplicit)
                                continue;
                            if (candidates.Count == 0 && implicitCandidates.Count == 0)
                            {//Set base exp
                                baseExp = (PExp)reciever;
                            }
                            if (add)
                                candidates.Add(methodDecl);
                            if (matchImplicit)
                                implicitCandidates.Add(methodDecl);
                        }
                    }
                }

                else if (type is ANamedType && data.DelegateTypeLinks.ContainsKey((ANamedType)type))
                {
                    if (matchingDelegates != null && name == "Invoke")
                    {
                        AMethodDecl delegateDecl = data.DelegateTypeLinks[(ANamedType)type];
                        if (delegateDecl.GetFormals().Count == argTypes.Count)
                        {
                            matchingNames.Add(delegateDecl);

                            //Check return type
                            if (!(returnType != null && !(returnType is AVoidType) &&
                                !Assignable(delegateDecl.GetReturnType(), returnType)))
                            {
                                //Check that parameters are assignable
                                bool add = true;
                                bool matchImplicit = false;
                                for (int j = 0; j < argTypes.Count; j++)
                                {
                                    PType argType = argTypes[j];
                                    AALocalDecl formal = (AALocalDecl) delegateDecl.GetFormals()[j];
                                    PType formalType = formal.GetType();
                                    if (formal.GetOut() != null && !Assignable(formalType, argType)
                                        ||
                                        formal.GetRef() != null &&
                                        !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                        ||
                                        formal.GetOut() == null && formal.GetRef() == null &&
                                        !Assignable(argType, formalType))
                                    {
                                        add = false;
                                        if (formal.GetOut() == null && formal.GetRef() == null &&
                                            ImplicitAssignable(argType, formalType))
                                        {
                                            matchImplicit = true;
                                        }
                                        else
                                        {
                                            matchImplicit = false;
                                            break;
                                        }
                                    }
                                }
                                if (add || matchImplicit)
                                {
                                    matchingDelegates.Add(delegateDecl);
                                    if (candidates.Count == 0 && implicitCandidates.Count == 0)
                                    {
                                        //Set base exp
                                        baseExp = (PExp)reciever;
                                    }
                                    if (add)
                                        candidates.Add(delegateDecl);
                                    if (matchImplicit)
                                        implicitCandidates.Add(delegateDecl);
                                }
                            }
                        }
                    }
                }
                else
                {
                    //Look for enrichments
                    List<IList> visibleDecls = Util.GetVisibleDecls(node, true);
                    AEnrichmentDecl currentEnrichment = Util.GetAncestor<AEnrichmentDecl>(node);
                    foreach (IList declList in visibleDecls)
                    {
                        foreach (PDecl decl in declList)
                        {
                            if (decl is AEnrichmentDecl)
                            {
                                AEnrichmentDecl enrichment = (AEnrichmentDecl)decl;
                                if (!Util.TypesEqual(type, enrichment.GetType(), data))
                                    continue;
                                foreach (PDecl enrichmentDecl in enrichment.GetDecl())
                                {
                                    if (enrichmentDecl is AMethodDecl)
                                    {
                                        AMethodDecl methodDecl = (AMethodDecl)enrichmentDecl;

                                        if (methodDecl.GetName().Text == name &&
                                            methodDecl.GetFormals().Count == argTypes.Count &&
                                            methodDecl.GetDelegate() == null)
                                        {
                                            matchingNames.Add(methodDecl);

                                            //Visibility
                                            if (methodDecl.GetVisibilityModifier() is APrivateVisibilityModifier &&
                                                enrichment != currentEnrichment)
                                                continue;
                                            if (methodDecl.GetStatic() != null)
                                                continue;
                                            //Check return type
                                            if (returnType != null && !(returnType is AVoidType) &&
                                                !Assignable(methodDecl.GetReturnType(), returnType))
                                                continue;
                                            //Check that parameters are assignable
                                            bool add = true;
                                            bool matchImplicit = false;
                                            for (int j = 0; j < argTypes.Count; j++)
                                            {
                                                PType argType = argTypes[j];
                                                AALocalDecl formal = (AALocalDecl)methodDecl.GetFormals()[j];
                                                PType formalType = formal.GetType();
                                                if (formal.GetOut() != null && !Assignable(formalType, argType)
                                                    ||
                                                    formal.GetRef() != null &&
                                                    !(Assignable(argType, formalType) && Assignable(formalType, argType))
                                                    ||
                                                    formal.GetOut() == null && formal.GetRef() == null &&
                                                    !Assignable(argType, formalType))
                                                {
                                                    add = false;
                                                    if (formal.GetOut() == null && formal.GetRef() == null &&
                                                        ImplicitAssignable(argType, formalType))
                                                    {
                                                        matchImplicit = true;
                                                    }
                                                    else
                                                    {
                                                        matchImplicit = false;
                                                        break;
                                                    }
                                                }
                                            }
                                            if (!add && !matchImplicit)
                                                continue;
                                            if (candidates.Count == 0 && implicitCandidates.Count == 0)
                                            {//Set base exp
                                                baseExp = (PExp)reciever;
                                            }
                                            if (add)
                                                candidates.Add(methodDecl);
                                            if (matchImplicit)
                                                implicitCandidates.Add(methodDecl);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            int candidateCount = candidates.Count + (matchArrayResize ? 1 : 0);
            if (candidateCount + implicitCandidates.Count == 0 && !matchArrayResize)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (AMethodDecl matchingName in matchingNames)
                {
                    subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText124")));
                }
                errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText125"), false, subErrors.ToArray()));
                throw new ParserException(node, "TypeChecking.GetTargets");
            }
            if (candidateCount > 1)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (AMethodDecl matchingName in candidates)
                {
                    subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText38")));
                }
                if (matchArrayResize)
                    subErrors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText126")));
                errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText127"), false, subErrors.ToArray()));
                throw new ParserException(node, "TypeChecking.GetTargets");
            }
            if (candidateCount == 0 && implicitCandidates.Count > 1)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (AMethodDecl matchingName in implicitCandidates)
                {
                    subErrors.Add(new ErrorCollection.Error(matchingName.GetName(), LocRM.GetString("ErrorText38")));
                }
                errors.Add(new ErrorCollection.Error(node, LocRM.GetString("ErrorText128"), false, subErrors.ToArray()));
                throw new ParserException(node, "TypeChecking.GetTargets");
            }
        }
Example #18
0
 ArrayList New583()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TypedList listNode6 = new TypedList();
     TypedList listNode5 = (TypedList)nodeArrayList1[0];
     if ( listNode5 != null )
     {
     listNode6.AddAll(listNode5);
     }
     AAName pnameNode4 = new AAName (
       listNode6
     );
     AAmbiguousNameLvalue plvalueNode3 = new AAmbiguousNameLvalue (
       pnameNode4
     );
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TArrow tarrowNode8 = (TArrow)nodeArrayList2[0];
     AArrowDotType pdottypeNode7 = new AArrowDotType (
       tarrowNode8
     );
     TIdentifier tidentifierNode9 = (TIdentifier)nodeArrayList3[0];
     AStructLvalue plvalueNode1 = new AStructLvalue (
       pexpNode2,
       pdottypeNode7,
       tidentifierNode9
     );
     nodeList.Add(plvalueNode1);
     return nodeList;
 }
 public override void OutALvalueExp(ALvalueExp node)
 {
     if (!(node.GetLvalue() is AAmbiguousNameLvalue ||
         node.GetLvalue() is ANamespaceLvalue ||
         node.GetLvalue() is ATypeLvalue))
         if (node.Parent() != null) //If I havent been replaced
             data.ExpTypes[node] = data.LvalueTypes[node.GetLvalue()];
     base.OutALvalueExp(node);
 }
Example #20
0
 ArrayList New589()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TValue tvalueNode4 = (TValue)nodeArrayList1[0];
     AValueLvalue plvalueNode3 = new AValueLvalue (
       tvalueNode4
     );
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TArrow tarrowNode6 = (TArrow)nodeArrayList2[0];
     AArrowDotType pdottypeNode5 = new AArrowDotType (
       tarrowNode6
     );
     TIdentifier tidentifierNode7 = (TIdentifier)nodeArrayList3[0];
     AStructLvalue plvalueNode1 = new AStructLvalue (
       pexpNode2,
       pdottypeNode5,
       tidentifierNode7
     );
     nodeList.Add(plvalueNode1);
     return nodeList;
 }
        private List<PStm> AssignDefault(PLvalue lvalue)
        {
            List<PStm> returner = new List<PStm>();
            PType type = data.LvalueTypes[lvalue];
            PExp rightSide = null;
            if (type is ANamedType)
            {
                ANamedType aType = (ANamedType)type;
                if (aType.IsPrimitive("string"))//aType.GetName().Text == "string")
                {
                    rightSide = new AStringConstExp(new TStringLiteral("\"\""));
                    data.ExpTypes[rightSide] = new ANamedType(new TIdentifier("string"), null);
                }
                else if (aType.IsPrimitive(GalaxyKeywords.NullablePrimitives.words)) //GalaxyKeywords.NullablePrimitives.words.Contains(aType.GetName().Text))
                {
                    rightSide = new ANullExp();
                    data.ExpTypes[rightSide] = new ANamedType(new TIdentifier("null"), null);
                }
                else if (aType.IsPrimitive(new []{"int", "byte", "fixed"}))
                    /*aType.GetName().Text == "int" ||
                    aType.GetName().Text == "byte" ||
                    aType.GetName().Text == "fixed")*/
                {
                    rightSide = new AIntConstExp(new TIntegerLiteral("0"));
                    data.ExpTypes[rightSide] = type;
                }
                else if (aType.IsPrimitive("bool"))//aType.GetName().Text == "bool")
                {
                    rightSide = new ABooleanConstExp(new AFalseBool());
                    data.ExpTypes[rightSide] = type;
                }
                else if (aType.IsPrimitive("color"))//aType.GetName().Text == "color")
                {
                    PExp arg1 = new AIntConstExp(new TIntegerLiteral("0"));
                    PExp arg2 = new AIntConstExp(new TIntegerLiteral("0"));
                    PExp arg3 = new AIntConstExp(new TIntegerLiteral("0"));
                    ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("Color"), new ArrayList() { arg1, arg2, arg3 });
                    rightSide = invoke;
                    data.ExpTypes[rightSide] = type;
                    data.ExpTypes[arg1] =
                        data.ExpTypes[arg2] =
                        data.ExpTypes[arg3] = new ANamedType(new TIdentifier("int"), null);
                    data.SimpleMethodLinks[invoke] =
                        data.Libraries.Methods.First(func => func.GetName().Text == invoke.GetName().Text);
                }
                else if (aType.IsPrimitive("char"))//aType.GetName().Text == "char")
                {
                    //Dunno?!
                    rightSide = new ACharConstExp(new TCharLiteral("'\0'"));
                    data.ExpTypes[rightSide] = type;
                }
                else //Struct
                {
                    AStructDecl str = data.StructTypeLinks[aType];
                    foreach (AALocalDecl localDecl in str.GetLocals())
                    {
                        ALvalueExp reciever = new ALvalueExp(Util.MakeClone(lvalue, data));
                        AStructLvalue newLvalue = new AStructLvalue(reciever, new ADotDotType(new TDot(".")), new TIdentifier(localDecl.GetName().Text));
                        data.StructFieldLinks[newLvalue] = localDecl;
                        data.ExpTypes[reciever] = type;
                        data.LvalueTypes[newLvalue] = localDecl.GetType();
                        returner.AddRange(AssignDefault(newLvalue));
                    }
                    return returner;
                }
                AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), Util.MakeClone(lvalue, data), rightSide);
                data.ExpTypes[assignment] = type;
                return new List<PStm>() { new AExpStm(new TSemicolon(";"), assignment) };
            }
            if (type is AArrayTempType)
            {
                AArrayTempType aType = (AArrayTempType)type;
                for (int i = 0; i < int.Parse(aType.GetIntDim().Text); i++)
                {
                    ALvalueExp reciever = new ALvalueExp(Util.MakeClone(lvalue, data));
                    AArrayLvalue newLvalue = new AArrayLvalue(new TLBracket("["), reciever, new AIntConstExp(new TIntegerLiteral(i.ToString())));
                    data.ExpTypes[reciever] = type;
                    data.LvalueTypes[newLvalue] = aType.GetType();
                    data.ExpTypes[newLvalue.GetIndex()] = new ANamedType(new TIdentifier("int"), null);
                    returner.AddRange(AssignDefault(newLvalue));
                }
                return returner;
            }

            throw new Exception("Unexpected type. (LivenessAnalasys.AssignDefault), got " + type);
        }
 public virtual void CaseALvalueExp(ALvalueExp node)
 {
     DefaultCase(node);
 }
 public override void CaseALvalueExp(ALvalueExp node)
 {
     InALvalueExp(node);
     if (node.GetLvalue() != null)
     {
         node.GetLvalue().Apply(this);
     }
     OutALvalueExp(node);
 }
        public override void OutAAProgram(AAProgram node)
        {
            if (strings.Count == 0)
                return;

            //Obfuscate all strings
            List<string> obfuscated = new List<string>();
            foreach (AStringConstExp stringConstExp in strings)
            {
                TStringLiteral token = stringConstExp.GetStringLiteral();
                string s = token.Text.Substring(1, token.Text.Length - 2);
                obfuscated.Add(Obfuscate(s));
            }

            //Set invokes instead of string constants, and move varaiabes down
            List<AFieldDecl> ignoredFields = new List<AFieldDecl>();
            List<AFieldDecl> moveFieldsIn = new List<AFieldDecl>();
            Dictionary<AFieldDecl, AMethodDecl> fieldMethods = new Dictionary<AFieldDecl, AMethodDecl>();
            for (int i = 0; i < strings.Count; i++)
            {
                AStringConstExp stringExp = strings[i];
                Token token = stringExp.GetStringLiteral();
                bool inDeobfuscator = Util.GetAncestor<AMethodDecl>(stringExp) == finalTrans.data.DeobfuscateMethod;

                if (inDeobfuscator)
                {
                    AFieldDecl field = finalTrans.data.UnobfuscatedStrings[stringExp];

                    AStringConstExp newStringConst = new AStringConstExp(stringExp.GetStringLiteral());

                    field.SetInit(newStringConst);

                    AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text, token.Line, token.Pos));
                    finalTrans.data.FieldLinks[fieldRef] = field;

                    stringExp.ReplaceBy(new ALvalueExp(fieldRef));
                }
                else
                {
                    AFieldDecl field;
                    if (!finalTrans.data.ObfuscatedStrings.ContainsKey(stringExp))
                    {
                        int line = -finalTrans.data.ObfuscatedStrings.Count - 1;
                        field = new AFieldDecl(new APublicVisibilityModifier(), null, new TConst("const", line, 0),
                                                new ANamedType(new TIdentifier("string", line, 1), null),
                                                new TIdentifier("Galaxy_pp_stringO" +
                                                                finalTrans.data.ObfuscatedStrings.Count), null);
                        //If the strings are the same - point them to same field
                        bool newField = true;
                        foreach (AStringConstExp oldStringConstExp in finalTrans.data.ObfuscatedStrings.Keys)
                        {
                            if (stringExp.GetStringLiteral().Text == oldStringConstExp.GetStringLiteral().Text)
                            {
                                field = finalTrans.data.ObfuscatedStrings[oldStringConstExp];
                                newField = false;
                                break;
                            }
                        }
                        if (newField)
                        {
                            AASourceFile file = (AASourceFile)finalTrans.data.DeobfuscateMethod.Parent();
                            file.GetDecl().Insert(file.GetDecl().IndexOf(finalTrans.data.DeobfuscateMethod) + 1, field);

                            finalTrans.data.Fields.Add(new SharedData.DeclItem<AFieldDecl>(file, field));
                        }
                        finalTrans.data.ObfuscatedStrings.Add(stringExp, field);

                    }
                    field = finalTrans.data.ObfuscatedStrings[stringExp];
                    string obfuscatedString = obfuscated[i];

                    ASimpleInvokeExp invoke = new ASimpleInvokeExp();
                    invoke.SetName(new TIdentifier(finalTrans.data.DeobfuscateMethod.GetName().Text,
                                                   stringExp.GetStringLiteral().Line,
                                                   stringExp.GetStringLiteral().Pos));

                    AStringConstExp newStringConst =
                        new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\""));
                    invoke.GetArgs().Add(newStringConst);
                    finalTrans.data.SimpleMethodLinks[invoke] = finalTrans.data.DeobfuscateMethod;

                    if (Util.GetAncestor<PStm>(stringExp) == null && false)
                    {
                        ignoredFields.Add(field);
                        /*if (Util.GetAncestor<ASimpleInvokeExp>(stringExp) == null)
                            stringExp.ReplaceBy(invoke);*/
                        //Add obfuscate call to this location);
                        continue;
                        /*ASimpleInvokeExp invoke = new ASimpleInvokeExp();
                        invoke.SetName(new TIdentifier(finalTrans.data.DeobfuscateMethod.GetName().Text,
                                                       stringExp.GetStringLiteral().Line,
                                                       stringExp.GetStringLiteral().Pos));

                        AStringConstExp newStringConst =
                            new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\""));
                        invoke.GetArgs().Add(newStringConst);
                        stringExp.ReplaceBy(invoke);

                        finalTrans.data.SimpleMethodLinks[invoke] = finalTrans.data.DeobfuscateMethod;
                        continue;*/
                    }

                    if (field.GetInit() == null)
                    {
                        /*field.SetInit(invoke);
                        field.SetConst(null);*/

                        if (
                            stringExp.GetStringLiteral().Text.Remove(0, 1).Substring(0,
                                                                                     stringExp.GetStringLiteral().Text.
                                                                                         Length - 2) == "")
                        {
                            //Make method
                            /*
                                string <field>Method()
                                {
                                    return "";
                                }
                             *
                             */
                            ANullExp nullExp = new ANullExp();

                            field.SetInit(nullExp);
                            field.SetConst(null);

                            AStringConstExp stringConst = new AStringConstExp(new TStringLiteral("\"\""));
                            AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                                 new ANamedType(new TIdentifier("string"), null),
                                                                 new TIdentifier("Get" + field.GetName()),
                                                                 new ArrayList(),
                                                                 new AABlock(
                                                                     new ArrayList()
                                                                         {
                                                                             new AValueReturnStm(new TReturn("return"),
                                                                                                 stringConst)
                                                                         },
                                                                     new TRBrace("}")));

                            AASourceFile pFile = (AASourceFile)field.Parent();
                            pFile.GetDecl().Insert(pFile.GetDecl().IndexOf(field) + 1, method);
                            finalTrans.data.ExpTypes[stringConst] = new ANamedType(new TIdentifier("string"), null);
                            finalTrans.data.ExpTypes[nullExp] = new ANamedType(new TIdentifier("null"), null);

                            fieldMethods[field] = method;
                        }
                        else
                        {
                            //Make method
                            /*
                                string <field>Method()
                                {
                                    if (field == null)
                                    {
                                        field = Invoke;
                                    }
                                    if (field == null)
                                    {
                                        return Invoke;
                                    }
                                    return field;
                                }
                             */

                            ANullExp nullExp1 = new ANullExp();

                            field.SetInit(nullExp1);
                            field.SetConst(null);

                            ANullExp nullExp2 = new ANullExp();
                            AFieldLvalue fieldRef1 = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                            AFieldLvalue fieldRef2 = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                            AFieldLvalue fieldRef3 = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                            ALvalueExp fieldRef1Exp = new ALvalueExp(fieldRef1);
                            ALvalueExp fieldRef3Exp = new ALvalueExp(fieldRef3);
                            ABinopExp binop1 = new ABinopExp(fieldRef1Exp, new AEqBinop(new TEq("==")), nullExp2);
                            AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), fieldRef2, invoke);

                            AIfThenStm ifStm1 = new AIfThenStm(new TLParen("("), binop1,
                                                              new ABlockStm(new TLBrace("{"),
                                                                            new AABlock(
                                                                                new ArrayList()
                                                                                    {
                                                                                        new AExpStm(new TSemicolon(";"),
                                                                                                    assignment)
                                                                                    },
                                                                                new TRBrace("}"))));

                            /*ANullExp nullExp3 = new ANullExp();
                            AFieldLvalue fieldRef4 = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                            ALvalueExp fieldRef4Exp = new ALvalueExp(fieldRef4);
                            AStringConstExp invokeArgClone =
                                new AStringConstExp(new TStringLiteral("\"" + obfuscatedString + "\""));
                            ASimpleInvokeExp invokeClone = new ASimpleInvokeExp(new TIdentifier(invoke.GetName().Text),
                                                                                new ArrayList() { invokeArgClone });
                            finalTrans.data.SimpleMethodLinks[invokeClone] = finalTrans.data.DeobfuscateMethod;
                            ABinopExp binop2 = new ABinopExp(fieldRef4Exp, new AEqBinop(new TEq("==")), nullExp3);

                            AIfThenStm ifStm2 = new AIfThenStm(new TLParen("("), binop2,
                                                              new ABlockStm(new TLBrace("{"),
                                                                            new AABlock(
                                                                                new ArrayList()
                                                                                    {
                                                                                        new AValueReturnStm(new TReturn("return"), invokeClone)
                                                                                    },
                                                                                new TRBrace("}"))));*/

                            AMethodDecl method = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                                 new ANamedType(new TIdentifier("string"), null),
                                                                 new TIdentifier("Get" + field.GetName()),
                                                                 new ArrayList(),
                                                                 new AABlock(
                                                                     new ArrayList()
                                                                         {
                                                                             ifStm1,
                                                                             //ifStm2,
                                                                             new AValueReturnStm(new TReturn("return"),
                                                                                                 fieldRef3Exp)
                                                                         },
                                                                     new TRBrace("}")));
                            AASourceFile pFile = (AASourceFile) field.Parent();
                            pFile.GetDecl().Insert(pFile.GetDecl().IndexOf(field) + 1, method);

                            finalTrans.data.FieldLinks[fieldRef1] =
                                finalTrans.data.FieldLinks[fieldRef2] =
                                finalTrans.data.FieldLinks[fieldRef3] =
                                /*finalTrans.data.FieldLinks[fieldRef4] = */field;
                            finalTrans.data.LvalueTypes[fieldRef1] =
                                finalTrans.data.LvalueTypes[fieldRef2] =
                                finalTrans.data.LvalueTypes[fieldRef3] =
                                //finalTrans.data.LvalueTypes[fieldRef4] =
                                finalTrans.data.ExpTypes[fieldRef1Exp] =
                                finalTrans.data.ExpTypes[fieldRef3Exp] =
                                //finalTrans.data.ExpTypes[fieldRef4Exp] =
                                finalTrans.data.ExpTypes[assignment] = field.GetType();

                            finalTrans.data.ExpTypes[nullExp1] =
                                finalTrans.data.ExpTypes[nullExp2] =
                                /*finalTrans.data.ExpTypes[nullExp3] =*/ new ANamedType(new TIdentifier("null"), null);
                            finalTrans.data.ExpTypes[binop1] =
                                /*finalTrans.data.ExpTypes[binop2] = */new ANamedType(new TIdentifier("bool"), null);

                            fieldMethods[field] = method;
                        }

                        /* AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text, token.Line, token.Pos));
                         finalTrans.data.FieldLinks[fieldRef] = field;*/

                        //stringExp.ReplaceBy(new ALvalueExp(fieldRef));
                    }
                    ASimpleInvokeExp invoke2 =
                            new ASimpleInvokeExp(new TIdentifier(fieldMethods[field].GetName().Text), new ArrayList());
                    finalTrans.data.SimpleMethodLinks[invoke2] = fieldMethods[field];
                    stringExp.ReplaceBy(invoke2);

                    //If we are in a field, move it in
                    if (Util.GetAncestor<AFieldDecl>(invoke2) != null)
                        moveFieldsIn.Add(Util.GetAncestor<AFieldDecl>(invoke2));
                }
            }

            foreach (AFieldDecl field in finalTrans.data.ObfuscationFields)
            {
                if (field.GetInit() == null && field.Parent() != null)
                {
                    field.Parent().RemoveChild(field);
                }
            }

            //A constant field, or a field used by a constant field cannot be moved in
            List<AFieldDecl> constantFields = new List<AFieldDecl>();
            foreach (SharedData.DeclItem<AFieldDecl> field in finalTrans.data.Fields)
            {
                if (field.Decl.GetConst() != null)
                    constantFields.Add(field.Decl);
            }
            for (int i = 0; i < constantFields.Count; i++)
            {
                GetFieldLvalues lvalues = new GetFieldLvalues();
                constantFields[i].Apply(lvalues);
                foreach (AFieldLvalue lvalue in lvalues.Lvalues)
                {
                    AFieldDecl field = finalTrans.data.FieldLinks[lvalue];
                    if (!constantFields.Contains(field))
                        constantFields.Add(field);
                }
            }
            moveFieldsIn.RemoveAll(constantFields.Contains);
            Dictionary<AFieldDecl, List<AFieldDecl>> dependancies = new Dictionary<AFieldDecl, List<AFieldDecl>>();
            //Order the fields so any dependancies are instansiated first
            foreach (AFieldDecl field in moveFieldsIn)
            {
                dependancies.Add(field, new List<AFieldDecl>());
                GetFieldLvalues lvalues = new GetFieldLvalues();
                field.Apply(lvalues);
                foreach (AFieldLvalue lvalue in lvalues.Lvalues)
                {
                    AFieldDecl dependancy = finalTrans.data.FieldLinks[lvalue];
                    if (!dependancies[field].Contains(dependancy))
                        dependancies[field].Add(dependancy);
                }
            }
            List<PStm> newStatements = new List<PStm>();
            while (dependancies.Keys.Count > 0)
            {
                AFieldDecl field = dependancies.FirstOrDefault(f1 => f1.Value.Count == 0).Key ??
                                   dependancies.Keys.First(f => true);

                AFieldLvalue fieldRef = new AFieldLvalue(new TIdentifier(field.GetName().Text));
                AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), fieldRef, field.GetInit());
                field.SetInit(null);

                newStatements.Add(new AExpStm(new TSemicolon(";"), assignment));

                finalTrans.data.FieldLinks[fieldRef] = field;
                finalTrans.data.LvalueTypes[fieldRef] =
                    finalTrans.data.ExpTypes[assignment] = field.GetType();

                foreach (KeyValuePair<AFieldDecl, List<AFieldDecl>> dependancy in dependancies)
                {
                    if (dependancy.Value.Contains(field))
                        dependancy.Value.Remove(field);
                }

                dependancies.Remove(field);
            }
            AABlock initBody = (AABlock) finalTrans.mainEntry.GetBlock();
            for (int i = newStatements.Count - 1; i >= 0; i--)
            {
                initBody.GetStatements().Insert(0, newStatements[i]);
            }
        }
 public virtual void OutALvalueExp(ALvalueExp node)
 {
     DefaultOut(node);
 }
Example #26
0
 ArrayList New390()
 {
     ArrayList nodeList = new ArrayList();
     ArrayList nodeArrayList6 = (ArrayList) Pop();
     ArrayList nodeArrayList5 = (ArrayList) Pop();
     ArrayList nodeArrayList4 = (ArrayList) Pop();
     ArrayList nodeArrayList3 = (ArrayList) Pop();
     ArrayList nodeArrayList2 = (ArrayList) Pop();
     ArrayList nodeArrayList1 = (ArrayList) Pop();
     TypedList listNode9 = new TypedList();
     TThis tthisNode4 = (TThis)nodeArrayList1[0];
     AThisLvalue plvalueNode3 = new AThisLvalue (
       tthisNode4
     );
     ALvalueExp pexpNode2 = new ALvalueExp (
       plvalueNode3
     );
     TDot tdotNode6 = (TDot)nodeArrayList2[0];
     ADotDotType pdottypeNode5 = new ADotDotType (
       tdotNode6
     );
     TIdentifier tidentifierNode7 = (TIdentifier)nodeArrayList3[0];
     TypedList listNode8 = (TypedList)nodeArrayList5[0];
     if ( listNode8 != null )
     {
     listNode9.AddAll(listNode8);
     }
     ANonstaticInvokeExp pexpNode1 = new ANonstaticInvokeExp (
       pexpNode2,
       pdottypeNode5,
       tidentifierNode7,
       listNode9
     );
     nodeList.Add(pexpNode1);
     return nodeList;
 }
        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 CaseASwitchStm(ASwitchStm node)
        {
            node.GetTest().Apply(this);

            AALocalDecl fallThroughDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                          new ANamedType(new TIdentifier("bool"), null),
                                                          new TIdentifier(MakeUniqueLocalName(node, "switchFallThrough")),
                                                          new ABooleanConstExp(new AFalseBool()));
            AALocalDecl continueDecl = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                          new ANamedType(new TIdentifier("bool"), null),
                                                          new TIdentifier(MakeUniqueLocalName(node, "switchContinue")),
                                                          new ABooleanConstExp(new ATrueBool()));

            AALocalDecl testVar = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                          Util.MakeClone(data.ExpTypes[node.GetTest()], data),
                                                          new TIdentifier(MakeUniqueLocalName(node, "switchTestVar")),
                                                          node.GetTest());

            AABlock bigBlock = new AABlock();
            //AABlock previousBlock = bigBlock;
            if (node.GetCases().Count > 0)
            {
                List<SwitchCaseData> switchCaseDatas = new List<SwitchCaseData>();
                //Join cases without a body
                for (int i = node.GetCases().Count - 1; i >= 0; i--)
                {
                    ASwitchCaseStm caseStm = (ASwitchCaseStm) node.GetCases()[i];
                    SwitchCaseData caseData = new SwitchCaseData();
                    caseData.Block = (AABlock) caseStm.GetBlock();
                    if (caseStm.GetType() is ACaseSwitchCaseType)
                        caseData.Tests.Add(((ACaseSwitchCaseType)caseStm.GetType()).GetExp());
                    else
                        caseData.ContainsDefault = true;

                    caseData.IsLast = switchCaseDatas.Count == 0;

                    if (switchCaseDatas.Count == 0 || caseData.Block.GetStatements().Count > 0)
                    {
                        switchCaseDatas.Insert(0, caseData);
                        continue;
                    }
                    switchCaseDatas[0].Tests.AddRange(caseData.Tests);
                }
                for (int i = switchCaseDatas.Count - 1; i >= 0; i--)
                {
                    switchCaseDatas[i].ContainsFallthrough = CanFallthrough(switchCaseDatas[i].Block, out switchCaseDatas[i].HasBreaks, out switchCaseDatas[i].RequiresWhile);
                    if (i == switchCaseDatas.Count - 1)
                        continue;

                    switchCaseDatas[i + 1].TargetForFallThrough = switchCaseDatas[i].ContainsFallthrough;
                    switchCaseDatas[i].RequiresContinue = !switchCaseDatas[i].ContainsFallthrough &&
                                                          (switchCaseDatas[i + 1].RequiresContinue ||
                                                           switchCaseDatas[i + 1].ContainsFallthrough);
                }

                AABlock previousBlock = bigBlock;
                //Make code for specific case
                foreach (SwitchCaseData switchCase in switchCaseDatas)
                {
                    List<PExp> tests = new List<PExp>();
                    AABlock nextBlock;
                    if (switchCase.TargetForFallThrough)
                    {//Add if (continueSwitch) {}
                        ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(continueDecl.GetName().Text));
                        ALvalueExp test = new ALvalueExp(lvalue);
                        nextBlock = new AABlock();
                        AIfThenStm ifStm = new AIfThenStm(new TLParen("("), test, new ABlockStm(new TLBrace("{"), nextBlock));
                        previousBlock.GetStatements().Add(ifStm);
                        previousBlock = nextBlock;

                        data.LocalLinks[lvalue] = continueDecl;
                        data.LvalueTypes[lvalue] = data.ExpTypes[test] = continueDecl.GetType();

                        //First test in next if: if (fallThrough || ...
                        lvalue = new ALocalLvalue(new TIdentifier(fallThroughDecl.GetName().Text));
                        test = new ALvalueExp(lvalue);
                        tests.Add(test);

                        data.LocalLinks[lvalue] = fallThroughDecl;
                        data.LvalueTypes[lvalue] = data.ExpTypes[test] = fallThroughDecl.GetType();
                    }
                    //Make code for the test in the if
                    foreach (PExp exp in switchCase.Tests)
                    {
                        ALocalLvalue leftSide = new ALocalLvalue(new TIdentifier(testVar.GetName().Text));
                        ALvalueExp lvalueExp = new ALvalueExp(leftSide);
                        ABinopExp test = new ABinopExp(lvalueExp, new AEqBinop(new TEq("==")), exp);
                        tests.Add(test);

                        data.LocalLinks[leftSide] = testVar;
                        data.LvalueTypes[leftSide] = data.ExpTypes[lvalueExp] = testVar.GetType();
                        data.ExpTypes[test] = new ANamedType(new TIdentifier("bool"), null);
                    }

                    if (switchCase.ContainsDefault)
                    {
                        ABooleanConstExp test = new ABooleanConstExp(new ATrueBool());
                        tests.Add(test);

                        data.ExpTypes[test] = new ANamedType(new TIdentifier("bool"), null);
                    }

                    PExp finalTest = tests[0];
                    tests.RemoveAt(0);
                    foreach (PExp exp in tests)
                    {
                        finalTest = new ABinopExp(finalTest, new ALazyOrBinop(new TOrOr("||")), exp);

                        data.ExpTypes[finalTest] = new ANamedType(new TIdentifier("bool"), null);
                    }

                    //Transform breaks into assignments

                    //If we can fallthrough, and there are breaks, encase in a while stm
                    AABlock testBlock = switchCase.Block;
                    if (switchCase.RequiresWhile)
                    {
                        AABlock newBlock = new AABlock();
                        PExp whileTest = new ABooleanConstExp(new ATrueBool());
                        AWhileStm whileStm = new AWhileStm(new TLParen("("), whileTest, new ABlockStm(new TLBrace("{"), switchCase.Block));
                        newBlock.GetStatements().Add(whileStm);
                        switchCase.Block = newBlock;
                    }

                    TransformBreaks(testBlock, switchCase, continueDecl, fallThroughDecl);

                    if (switchCase.ContainsFallthrough && !switchCase.TargetForFallThrough)
                    {//Add fallthrough = true;
                        ALocalLvalue lvalue = new ALocalLvalue(new TIdentifier(fallThroughDecl.GetName().Text));
                        ABooleanConstExp rightSide = new ABooleanConstExp(new ATrueBool());
                        AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), lvalue, rightSide);
                        testBlock.GetStatements().Add(new AExpStm(new TSemicolon(";"), assignment));

                        data.LocalLinks[lvalue] = fallThroughDecl;
                        data.LvalueTypes[lvalue] = data.ExpTypes[rightSide] = data.ExpTypes[assignment] = fallThroughDecl.GetType();
                    }

                    if (switchCase.RequiresWhile)
                    {//Add break at the end of the while
                        testBlock.GetStatements().Add(new ABreakStm(new TBreak("break")));
                    }

                    //Make if
                    PStm finalIfStm;
                    if (finalTest is ABooleanConstExp)
                    {//Final if is if(true). dont add it.
                        finalIfStm = new ABlockStm(new TLBrace("{"), switchCase.Block);
                        nextBlock = new AABlock();
                    }
                    else if (switchCase.IsLast || switchCase.ContainsFallthrough)
                    {//One armed if
                        finalIfStm = new AIfThenStm(new TLParen("("), finalTest,
                                                    new ABlockStm(new TLBrace("{"), switchCase.Block));
                        nextBlock = bigBlock;
                    }
                    else
                    {//Two armed if
                        nextBlock = new AABlock();
                        finalIfStm = new AIfThenElseStm(new TLParen("("), finalTest,
                                                        new ABlockStm(new TLBrace("{"), switchCase.Block),
                                                        new ABlockStm(new TLBrace("{"), nextBlock));
                    }

                    previousBlock.GetStatements().Add(finalIfStm);
                    previousBlock = nextBlock;
                }

                //If needed, add fallThroughDecl and continueDecl
                data.Locals.Add(bigBlock, new List<AALocalDecl>());
                if (data.LocalLinks.Values.Contains(fallThroughDecl))
                {
                    bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), fallThroughDecl));
                    data.Locals[bigBlock].Add(fallThroughDecl);
                }
                if (data.LocalLinks.Values.Contains(continueDecl))
                {
                    bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), continueDecl));
                    data.Locals[bigBlock].Add(continueDecl);
                }
                bigBlock.GetStatements().Insert(0, new ALocalDeclStm(new TSemicolon(";"), testVar));
                data.Locals[bigBlock].Add(testVar);

                node.ReplaceBy(new ABlockStm(new TLBrace("{"), bigBlock));
                bigBlock.Apply(this);
            }
        }
            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 OutAArrayLvalue(AArrayLvalue node)
        {
            PType type = data.ExpTypes[node.GetBase()];
            PType argType = data.ExpTypes[node.GetIndex()];

            List<APropertyDecl> matchingArrayProperties = new List<APropertyDecl>();
            List<APropertyDecl> implicitStructArrayProperties = new List<APropertyDecl>();

            if (type is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)type))
            {
                AStructDecl structDecl = data.StructTypeLinks[(ANamedType) type];
                foreach (APropertyDecl property in data.StructProperties[structDecl])
                {
                    if (property.GetName().Text == "")
                    {
                        PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType();
                        if (Assignable(argType, proprtyArgType))
                            matchingArrayProperties.Add(property);
                    }
                }
            }

            if (type is APointerType)
            {
                APointerType aType = (APointerType)type;
                PType baseType = aType.GetType();
                if (baseType is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)baseType))
                {
                    AStructDecl structDecl = data.StructTypeLinks[(ANamedType)baseType];
                    foreach (APropertyDecl property in data.StructProperties[structDecl])
                    {
                        if (property.GetName().Text == "")
                        {
                            PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType();
                            if (Assignable(argType, proprtyArgType))
                                implicitStructArrayProperties.Add(property);
                        }
                    }
                }
            }

            List<IList> visibleDecls = Util.GetVisibleDecls(node, true);
            foreach (IList declList in visibleDecls)
            {
                foreach (PDecl decl in declList)
                {
                    if (decl is AEnrichmentDecl)
                    {
                        AEnrichmentDecl enrichment = (AEnrichmentDecl)decl;
                        if (Util.TypesEqual(type, enrichment.GetType(), data))
                        {
                            foreach (PDecl enrichmentDecl in enrichment.GetDecl())
                            {
                                if (enrichmentDecl is APropertyDecl)
                                {
                                    APropertyDecl property = (APropertyDecl) enrichmentDecl;
                                    if (property.GetName().Text == "")
                                    {
                                        PType proprtyArgType = data.ArrayPropertyLocals[property][0].GetType();
                                        if (Assignable(argType, proprtyArgType))
                                            matchingArrayProperties.Add(property);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            bool matchesNormalArray = false;
            ALvalueExp replaceBaseExp = null;
            if (Assignable(argType, new ANamedType(new TIdentifier("int"), null)))
            {
                if (type is AArrayTempType)
                {
                    AArrayTempType aType = (AArrayTempType) type;
                    type = aType.GetType();
                    matchesNormalArray = true;
                }
                else if (type is ADynamicArrayType)
                {
                    ADynamicArrayType aType = (ADynamicArrayType) type;
                    type = aType.GetType();
                    matchesNormalArray = true;
                }
                else if (type is APointerType)
                {
                    //Implicit conversion for a[] to (*a)[]
                    APointerType aType = (APointerType) type;
                    if (aType.GetType() is AArrayTempType || aType.GetType() is ADynamicArrayType)
                    {
                        APointerLvalue pointer = new APointerLvalue(new TStar("*"), node.GetBase());
                        replaceBaseExp = new ALvalueExp(pointer);
                        matchesNormalArray = true;
                    }
                }
            }
            if (matchingArrayProperties.Count == 0 && !matchesNormalArray && implicitStructArrayProperties.Count == 0)
                errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, LocRM.GetString("ErrorText72")));

            if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) > 1)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (APropertyDecl property in matchingArrayProperties)
                {
                    subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62")));
                }
                if (matchesNormalArray)
                    subErrors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText74")));
                errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray()));
                throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue");
            }

            if (matchingArrayProperties.Count + (matchesNormalArray ? 1 : 0) == 0 &&
                implicitStructArrayProperties.Count > 1)
            {
                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                foreach (APropertyDecl property in implicitStructArrayProperties)
                {
                    subErrors.Add(new ErrorCollection.Error(property.GetName(), LocRM.GetString("ErrorText62")));
                }
                errors.Add(new ErrorCollection.Error(node.GetToken(), LocRM.GetString("ErrorText73"), false, subErrors.ToArray()));
                throw new ParserException(node.GetToken(), "TypeChecking.OutAArrayLvalue");
            }

            if (matchingArrayProperties.Count == 1)
            {
                APropertyDecl property = matchingArrayProperties[0];
                type = property.GetType();
                data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, false);

                CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken());
            }
            else if (implicitStructArrayProperties.Count == 1)
            {
                APropertyDecl property = implicitStructArrayProperties[0];
                type = property.GetType();
                data.ArrayPropertyLinks[node] = new Util.Pair<APropertyDecl, bool>(property, true);

                CheckPropertyAccessibility(property, node.Parent() is AAssignmentExp, node.GetToken());
            }

            if (replaceBaseExp == null)
                data.LvalueTypes[node] = type;
            else
            {
                node.SetBase(replaceBaseExp);
                //pointer.Apply(this);
                OutAPointerLvalue((APointerLvalue)replaceBaseExp.GetLvalue());
                OutALvalueExp(replaceBaseExp);
                OutAArrayLvalue(node);
            }

            //if (!Assignable(data.ExpTypes[node.GetIndex()], new ANamedType(new TIdentifier("int"), null)))
            //    errors.Add(new ErrorCollection.Error(node.GetToken(), currentSourceFile, "Indexes of arrays must be of integer type."));
        }