public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     node.GetBase().Apply(this);
     Write("[");
     node.GetIndex().Apply(this);
     Write("]");
 }
 public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     bool containedLiteral = containsLiteral;
     containsLiteral = false;
     node.GetIndex().Apply(this);
     bool hasLiteral = containsLiteral;
     containsLiteral = containedLiteral;
     PType type = data.ExpTypes[node.GetIndex()];
     if (!hasLiteral && type is ANamedType && ((ANamedType)type).IsPrimitive("byte"))
     {
         AIntConstExp intConst = new AIntConstExp(new TIntegerLiteral("0"));
         ABinopExp binop = new ABinopExp(node.GetIndex(), new APlusBinop(new TPlus("+")), intConst);
         data.ExpTypes[intConst] =
             data.ExpTypes[binop] = new ANamedType(new TIdentifier("int"), null);
         node.SetIndex(binop);
     }
     node.GetBase().Apply(this);
 }
 public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     InAArrayLvalue(node);
     if (node.GetIndex() != null)
     {
         node.GetIndex().Apply(this);
     }
     if (node.GetBase() != null)
     {
         node.GetBase().Apply(this);
     }
     if (node.GetToken() != null)
     {
         node.GetToken().Apply(this);
     }
     OutAArrayLvalue(node);
 }
        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."));
        }
 public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     bool wasLeftAssign = isLeftAssign;
     node.GetBase().Apply(this);
     isLeftAssign = false;
     node.GetIndex().Apply(this);
     isLeftAssign = wasLeftAssign;
 }
 public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     node.GetBase().Apply(this);
 }
            private void MakeAssignmentRightDynamic(PLvalue leftSide, PExp rightSide, PType type, AABlock block, ref int index)
            {
                if (Util.IsBulkCopy(type))
                {
                    if (type is ANamedType)
                    {
                        ANamedType aType = (ANamedType)type;
                        AStructDecl structDecl = data.StructTypeLinks[aType];
                        foreach (AALocalDecl localDecl in structDecl.GetLocals())
                        {
                            AStructLvalue newleftSide = new AStructLvalue(new ALvalueExp(leftSide),
                                                                          new ADotDotType(new TDot(".")),
                                                                          new TIdentifier(localDecl.GetName().Text));

                            ABinopExp newrightSide = new ABinopExp(rightSide, new APlusBinop(new TPlus("+")),
                                                     new AStringConstExp(
                                                         new TStringLiteral("\"." + localDecl.GetName().Text + "\"")));

                             data.ExpTypes[newrightSide] =
                                data.ExpTypes[newrightSide.GetRight()] =
                                new ANamedType(new TIdentifier("string"), null);

                            data.ExpTypes[newleftSide.GetReceiver()] = type;
                            data.LvalueTypes[newleftSide] = localDecl.GetType();

                            data.StructFieldLinks[newleftSide] = localDecl;

                            MakeAssignmentRightDynamic(newleftSide, newrightSide, localDecl.GetType(), block, ref index);
                        }
                    }
                    else
                    {//Is array type. Can Only be a constant array type
                        AArrayTempType aType = (AArrayTempType)type;
                        for (int i = 0; i < int.Parse(aType.GetIntDim().Text); i++)
                        {
                            AArrayLvalue newleftSide = new AArrayLvalue(new TLBracket("["), new ALvalueExp(leftSide), new AIntConstExp(new TIntegerLiteral(i.ToString())));

                            ABinopExp newrightSide = new ABinopExp(rightSide, new APlusBinop(new TPlus("+")),
                                                     new AStringConstExp(
                                                         new TStringLiteral("\"[" + i + "]\"")));
                            data.ExpTypes[newrightSide] =
                                data.ExpTypes[newrightSide.GetRight()] =
                                new ANamedType(new TIdentifier("string"), null);

                            data.ExpTypes[newleftSide.GetBase()] = type;
                            data.ExpTypes[newleftSide.GetIndex()] = new ANamedType(new TIdentifier("int"), null);
                            data.LvalueTypes[newleftSide] = aType.GetType();

                            MakeAssignmentRightDynamic(newleftSide, newrightSide, aType.GetType(), block, ref index);

                        }

                    }
                }
                else
                {
                    ANamedType aType;// = type is APointerType ? new ANamedType(new TIdentifier("string"), null) : (ANamedType)type;
                    if (type is APointerType)
                    {
                        if (Util.IsIntPointer(type, ((APointerType)type).GetType(), data))
                            aType = new ANamedType(new TIdentifier("int"), null);
                        else
                            aType = new ANamedType(new TIdentifier("string"), null);
                    }
                    else
                    {
                        aType = (ANamedType) type;
                    }
                    string capitalType = Util.Capitalize(aType.AsIdentifierString());//Char.ToUpper(aType.GetName().Text[0]) + aType.GetName().Text.Substring(1);
                    leftSide = Util.MakeClone(leftSide, data);
                    rightSide = Util.MakeClone(rightSide, data);

                    ABooleanConstExp trueConst1 = new ABooleanConstExp(new ATrueBool());
                    //ABooleanConstExp trueConst2 = new ABooleanConstExp(new ATrueBool());
                    ASimpleInvokeExp innerInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableGet" + capitalType), new ArrayList() { trueConst1, rightSide });
                    //ASimpleInvokeExp outerInvoke = new ASimpleInvokeExp(new TIdentifier("DataTableSet" + capitalType), new ArrayList() { trueConst2, leftSide, innerInvoke });
                    AAssignmentExp assignment = new AAssignmentExp(new TAssign("="), leftSide, innerInvoke);
                    block.GetStatements().Insert(index, new AExpStm(new TSemicolon(";"), assignment));
                    index++;

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

                    data.ExpTypes[innerInvoke] = aType;
                    data.ExpTypes[assignment] = aType;

                    data.SimpleMethodLinks[innerInvoke] =
                        data.Libraries.Methods.First(m => m.GetName().Text == innerInvoke.GetName().Text);
                }
            }
            public override void CaseAArrayLvalue(AArrayLvalue node)
            {
                hadPointer = false;
                node.GetIndex().Apply(this);
                if (hadPointer)
                {//The index is a dynamic int
                    string typeName = ((ANamedType) data.ExpTypes[node.GetIndex()]).AsString();
                    node.GetIndex().ReplaceBy(CreateDynaicGetStm(typeName));
                }
                node.GetBase().Apply(this);
                if (hadPointer)
                {

                    //if (Util.GetAncestor<AAssignmentExp>(node) != null || Util.GetAncestor<APArrayLengthLvalue>(node) != null)
                    {
                        //Todo: Check if the index is within array (runtime)

                        ASimpleInvokeExp intToString = new ASimpleInvokeExp(new TIdentifier("IntToString"),
                                                                            new ArrayList());
                        intToString.GetArgs().Add(Util.MakeClone(node.GetIndex(), data));

                        ABinopExp binopExp1 = new ABinopExp(nameExp, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"[\"")));
                        ABinopExp binopExp2 = new ABinopExp(binopExp1, new APlusBinop(new TPlus("+")), intToString);
                        ABinopExp binopExp3 = new ABinopExp(binopExp2, new APlusBinop(new TPlus("+")), new AStringConstExp(new TStringLiteral("\"]\"")));

                        data.ExpTypes[binopExp1] =
                        data.ExpTypes[binopExp2] =
                        data.ExpTypes[binopExp3] =
                        data.ExpTypes[binopExp1.GetRight()] =
                        data.ExpTypes[binopExp3.GetRight()] =
                            data.ExpTypes[intToString] =new ANamedType(new TIdentifier("string"), null);
                        data.SimpleMethodLinks[intToString] =
                            data.Libraries.Methods.First(method => method.GetName().Text == intToString.GetName().Text);
                        nameExp = binopExp3;
                    }
                    CheckDynamicLvalue(node);
                }
            }
 public override void CaseAArrayLvalue(AArrayLvalue node)
 {
     node.GetIndex().Apply(this);
     currentLocal = null;
     node.GetBase().Apply(this);
 }