Example #1
0
        public override TypeNode VisitTypeReference(TypeNode type)
        { //TODO: break up this method
            if (type == null)
            {
                return(null);
            }
            TypeNodeList pars = this.pars;
            TypeNodeList args = this.args;

            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType arrType  = (ArrayType)type;
                TypeNode  elemType = this.VisitTypeReference(arrType.ElementType);
                if (elemType == arrType.ElementType || elemType == null)
                {
                    return(arrType);
                }
                if (arrType.IsSzArray())
                {
                    return(elemType.GetArrayType(1));
                }
                return(elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds));

            case NodeType.DelegateNode:
            {
                FunctionType ftype = type as FunctionType;
                if (ftype == null)
                {
                    goto default;
                }
                TypeNode referringType = ftype.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(ftype.DeclaringType);
                return(FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), referringType));
            }

            case NodeType.Pointer:
                Pointer pType = (Pointer)type;
                elemType = this.VisitTypeReference(pType.ElementType);
                if (elemType == pType.ElementType || elemType == null)
                {
                    return(pType);
                }
                return(elemType.GetPointerType());

            case NodeType.Reference:
                Reference rType = (Reference)type;
                elemType = this.VisitTypeReference(rType.ElementType);
                if (elemType == rType.ElementType || elemType == null)
                {
                    return(rType);
                }
                return(elemType.GetReferenceType());

            case NodeType.ArrayTypeExpression:
                ArrayTypeExpression aExpr = (ArrayTypeExpression)type;
                aExpr.ElementType = this.VisitTypeReference(aExpr.ElementType);
                return(aExpr);

            case NodeType.BoxedTypeExpression:
                BoxedTypeExpression bExpr = (BoxedTypeExpression)type;
                bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
                return(bExpr);

            case NodeType.ClassExpression:
            {
                ClassExpression cExpr = (ClassExpression)type;
                cExpr.Expression = this.VisitTypeExpression(cExpr.Expression);

                //Could happen if the expression is a template parameter
                if (cExpr.Expression is Literal lit)
                {
                    return(lit.Value as TypeNode);
                }

                cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
                return(cExpr);
            }

            case NodeType.ClassParameter:
            case NodeType.TypeParameter:
                int key = type.UniqueKey;
                for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++)
                {
                    //^ assert pars != null && args != null;
                    TypeNode tp = pars[i];
                    if (tp == null)
                    {
                        continue;
                    }
                    if (tp.UniqueKey == key)
                    {
                        return(args[i]);
                    }
                    if (tp.Name.UniqueIdKey == type.Name.UniqueIdKey && (tp is ClassParameter && type is TypeParameter))
                    {
                        //This shouldn't really happen, but in practice it does. Hack past it.
                        return(args[i]);
                    }
                }
                return(type);

            case NodeType.FlexArrayTypeExpression:
                FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type;
                flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
                return(flExpr);

            case NodeType.FunctionTypeExpression:
                FunctionTypeExpression ftExpr = (FunctionTypeExpression)type;
                ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
                ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
                return(ftExpr);

            case NodeType.InvariantTypeExpression:
                InvariantTypeExpression invExpr = (InvariantTypeExpression)type;
                invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
                return(invExpr);

            case NodeType.InterfaceExpression:
                InterfaceExpression iExpr = (InterfaceExpression)type;
                if (iExpr.Expression == null)
                {
                    goto default;
                }
                iExpr.Expression        = this.VisitTypeExpression(iExpr.Expression);
                iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
                return(iExpr);

            case NodeType.NonEmptyStreamTypeExpression:
                NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type;
                neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
                return(neExpr);

            case NodeType.NonNullTypeExpression:
                NonNullTypeExpression nnExpr = (NonNullTypeExpression)type;
                nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
                return(nnExpr);

            case NodeType.NonNullableTypeExpression:
                NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type;
                nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
                return(nbExpr);

            case NodeType.NullableTypeExpression:
                NullableTypeExpression nuExpr = (NullableTypeExpression)type;
                nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
                return(nuExpr);

            case NodeType.OptionalModifier:
            {
                TypeModifier modType      = (TypeModifier)type;
                TypeNode     modifiedType = this.VisitTypeReference(modType.ModifiedType);
                TypeNode     modifierType = this.VisitTypeReference(modType.Modifier);
                if (modifiedType == null || modifierType == null)
                {
                    return(type);
                }

                return(OptionalModifier.For(modifierType, modifiedType));
            }

            case NodeType.RequiredModifier:
            {
                TypeModifier modType      = (TypeModifier)type;
                TypeNode     modifiedType = this.VisitTypeReference(modType.ModifiedType);
                TypeNode     modifierType = this.VisitTypeReference(modType.Modifier);
                if (modifiedType == null || modifierType == null)
                {
                    Debug.Fail(""); return(type);
                }
                return(RequiredModifier.For(modifierType, modifiedType));
            }

            case NodeType.OptionalModifierTypeExpression:
                OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type;
                optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
                optmodType.Modifier     = this.VisitTypeReference(optmodType.Modifier);
                return(optmodType);

            case NodeType.RequiredModifierTypeExpression:
                RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type;
                reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
                reqmodType.Modifier     = this.VisitTypeReference(reqmodType.Modifier);
                return(reqmodType);

            case NodeType.PointerTypeExpression:
                PointerTypeExpression pExpr = (PointerTypeExpression)type;
                pExpr.ElementType = this.VisitTypeReference(pExpr.ElementType);
                return(pExpr);

            case NodeType.ReferenceTypeExpression:
                ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type;
                rExpr.ElementType = this.VisitTypeReference(rExpr.ElementType);
                return(rExpr);

            case NodeType.StreamTypeExpression:
                StreamTypeExpression sExpr = (StreamTypeExpression)type;
                sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
                return(sExpr);

            case NodeType.TupleTypeExpression:
                TupleTypeExpression tuExpr = (TupleTypeExpression)type;
                tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
                return(tuExpr);

            case NodeType.TypeExpression:
            {
                TypeExpression tExpr = (TypeExpression)type;
                tExpr.Expression = this.VisitTypeExpression(tExpr.Expression);
                if (tExpr.Expression is Literal)
                {
                    return(type);
                }
                tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
                return(tExpr);
            }

            case NodeType.TypeIntersectionExpression:
                TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type;
                tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
                return(tiExpr);

            case NodeType.TypeUnionExpression:
                TypeUnionExpression tyuExpr = (TypeUnionExpression)type;
                tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
                return(tyuExpr);

            default:
                TypeNode declaringType = this.VisitTypeReference(type.DeclaringType);
                if (declaringType != null)
                {
                    Identifier tname = type.Name;
                    if (type.Template != null && type.IsGeneric)
                    {
                        tname = type.Template.Name;
                    }
                    TypeNode nt = declaringType.GetNestedType(tname);
                    if (nt != null)
                    {
                        TypeNodeList arguments = type.TemplateArguments;
                        type = nt;
                        if (TargetPlatform.UseGenerics)
                        {
                            if (arguments != null && arguments.Count > 0 && nt.ConsolidatedTemplateParameters != null && nt.ConsolidatedTemplateParameters.Count > 0)
                            {
                                type = nt.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, arguments);
                            }
                        }
                    }
                }

                if (type.Template != null && (type.ConsolidatedTemplateParameters == null || type.ConsolidatedTemplateParameters.Count == 0))
                {
                    if (!type.IsNotFullySpecialized && (!type.IsNormalized ||
                                                        (this.CurrentType != null && type.DeclaringModule == this.CurrentType.DeclaringModule)))
                    {
                        return(type);
                    }

                    // Type is a template instance, but some of its arguments were themselves parameters.
                    // See if any of these parameters are to be specialized by this specializer.
                    bool         mustSpecializeFurther = false;
                    TypeNodeList targs   = type.TemplateArguments;
                    int          numArgs = targs == null ? 0 : targs.Count;

                    if (targs != null)
                    {
                        targs = new TypeNodeList(targs);

                        for (int i = 0; i < numArgs; i++)
                        {
                            TypeNode targ = targs[i];

                            if (targ is ITypeParameter tparg)
                            {
                                for (int j = 0, np = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; j < np && j < m; j++)
                                {
                                    //^ assert pars != null && args != null;
                                    if (TargetPlatform.UseGenerics)
                                    {
                                        if (!(pars[j] is ITypeParameter par))
                                        {
                                            continue;
                                        }

                                        if (tparg == par || (tparg.ParameterListIndex == par.ParameterListIndex && tparg.DeclaringMember == par.DeclaringMember))
                                        {
                                            targ = this.args[j];
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (targ == pars[j])
                                        {
                                            targ = this.args[j];
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (targ != type)
                                {
                                    targ = this.VisitTypeReference(targ);
                                }

                                if (targ == type)
                                {
                                    continue;
                                }
                            }

                            mustSpecializeFurther |= targs[i] != targ;
                            targs[i] = targ;
                        }
                    }

                    if (targs == null || !mustSpecializeFurther)
                    {
                        return(type);
                    }

                    return(type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs));
                }

                TypeNodeList tPars = type.TemplateParameters;
                if (tPars == null || tPars.Count == 0)
                {
                    return(type);                                       //Not a parameterized type. No need to get an instance.
                }
                TypeNodeList tArgs = new TypeNodeList();
                for (int i = 0, n = tPars.Count; i < n; i++)
                {
                    TypeNode tPar = tPars[i];
                    tArgs.Add(tPar);     //Leave parameter in place if there is no match
                    if (tPar == null || tPar.Name == null)
                    {
                        continue;
                    }
                    int idKey = tPar.Name.UniqueIdKey;
                    for (int j = 0, m = pars == null ? 0 : pars.Count, k = args == null ? 0 : args.Count; j < m && j < k; j++)
                    {
                        //^ assert pars != null && args != null;
                        TypeNode par = pars[j];
                        if (par == null || par.Name == null)
                        {
                            continue;
                        }
                        if (par.Name.UniqueIdKey == idKey)
                        {
                            tArgs[i] = args[j];
                            break;
                        }
                    }
                }
                return(type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs));
            }
        }
Example #2
0
        public override TypeNode VisitTypeReference(TypeNode type)
        {
            if (type == null)
            {
                return(null);
            }
            Class cl = type as Class;

            if (cl != null)
            {
                this.VisitTypeReference(cl.BaseClass);
            }
            if (this.MembersToFind[type.UniqueKey] != null)
            {
                this.FoundMembers[type.UniqueKey] = type;
                if (!this.insideMethodBody)
                {
                    this.AllReferencesAreConfinedToMethodBodies = false;
                }
                return(type);
            }
            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType arrType = (ArrayType)type;
                this.VisitTypeReference(arrType.ElementType);
                return(type);

            case NodeType.DelegateNode: {
                FunctionType ftype = type as FunctionType;
                if (ftype == null)
                {
                    goto default;
                }
                this.VisitTypeReference(ftype.ReturnType);
                this.VisitParameterList(ftype.Parameters);
                return(type);
            }

            case NodeType.Pointer:
                Pointer pType = (Pointer)type;
                this.VisitTypeReference(pType.ElementType);
                return(type);

            case NodeType.Reference:
                Reference rType = (Reference)type;
                this.VisitTypeReference(rType.ElementType);
                return(type);

            case NodeType.TupleType: {
                TupleType  tType   = (TupleType)type;
                MemberList members = tType.Members;
                int        n       = members == null ? 0 : members.Count;
                for (int i = 0; i < n; i++)
                {
                    Field f = members[i] as Field;
                    if (f == null)
                    {
                        continue;
                    }
                    this.VisitTypeReference(f.Type);
                }
                return(type);
            }

            case NodeType.TypeIntersection:
                TypeIntersection tIntersect = (TypeIntersection)type;
                this.VisitTypeReferenceList(tIntersect.Types);
                return(type);

            case NodeType.TypeUnion:
                TypeUnion tUnion = (TypeUnion)type;
                this.VisitTypeReferenceList(tUnion.Types);
                return(type);

            case NodeType.ArrayTypeExpression:
                ArrayTypeExpression aExpr = (ArrayTypeExpression)type;
                this.VisitTypeReference(aExpr.ElementType);
                return(type);

            case NodeType.BoxedTypeExpression:
                BoxedTypeExpression bExpr = (BoxedTypeExpression)type;
                this.VisitTypeReference(bExpr.ElementType);
                return(type);

            case NodeType.ClassExpression:
                ClassExpression cExpr = (ClassExpression)type;
                this.VisitExpression(cExpr.Expression);
                this.VisitTypeReferenceList(cExpr.TemplateArguments);
                return(type);

            case NodeType.ClassParameter:
            case NodeType.TypeParameter:
                return(type);

            case NodeType.ConstrainedType:
                ConstrainedType conType = (ConstrainedType)type;
                this.VisitTypeReference(conType.UnderlyingType);
                this.VisitExpression(conType.Constraint);
                return(type);

            case NodeType.FlexArrayTypeExpression:
                FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type;
                this.VisitTypeReference(flExpr.ElementType);
                return(type);

            case NodeType.FunctionTypeExpression:
                FunctionTypeExpression ftExpr = (FunctionTypeExpression)type;
                this.VisitParameterList(ftExpr.Parameters);
                this.VisitTypeReference(ftExpr.ReturnType);
                return(type);

            case NodeType.InvariantTypeExpression:
                InvariantTypeExpression invExpr = (InvariantTypeExpression)type;
                this.VisitTypeReference(invExpr.ElementType);
                return(type);

            case NodeType.InterfaceExpression:
                InterfaceExpression iExpr = (InterfaceExpression)type;
                this.VisitExpression(iExpr.Expression);
                this.VisitTypeReferenceList(iExpr.TemplateArguments);
                return(type);

            case NodeType.NonEmptyStreamTypeExpression:
                NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type;
                this.VisitTypeReference(neExpr.ElementType);
                return(type);

            case NodeType.NonNullTypeExpression:
                NonNullTypeExpression nnExpr = (NonNullTypeExpression)type;
                this.VisitTypeReference(nnExpr.ElementType);
                return(type);

            case NodeType.NonNullableTypeExpression:
                NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type;
                this.VisitTypeReference(nbExpr.ElementType);
                return(type);

            case NodeType.NullableTypeExpression:
                NullableTypeExpression nuExpr = (NullableTypeExpression)type;
                this.VisitTypeReference(nuExpr.ElementType);
                return(type);

            case NodeType.OptionalModifier:
            case NodeType.RequiredModifier:
                TypeModifier modType = (TypeModifier)type;
                this.VisitTypeReference(modType.ModifiedType);
                this.VisitTypeReference(modType.Modifier);
                return(type);

            case NodeType.PointerTypeExpression:
                PointerTypeExpression pExpr = (PointerTypeExpression)type;
                this.VisitTypeReference(pExpr.ElementType);
                return(type);

            case NodeType.ReferenceTypeExpression:
                ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type;
                this.VisitTypeReference(rExpr.ElementType);
                return(type);

            case NodeType.StreamTypeExpression:
                StreamTypeExpression sExpr = (StreamTypeExpression)type;
                this.VisitTypeReference(sExpr.ElementType);
                return(type);

            case NodeType.TupleTypeExpression:
                TupleTypeExpression tuExpr = (TupleTypeExpression)type;
                this.VisitFieldList(tuExpr.Domains);
                return(type);

            case NodeType.TypeExpression:
                TypeExpression tExpr = (TypeExpression)type;
                this.VisitExpression(tExpr.Expression);
                this.VisitTypeReferenceList(tExpr.TemplateArguments);
                return(type);

            case NodeType.TypeIntersectionExpression:
                TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type;
                this.VisitTypeReferenceList(tiExpr.Types);
                return(type);

            case NodeType.TypeUnionExpression:
                TypeUnionExpression tyuExpr = (TypeUnionExpression)type;
                this.VisitTypeReferenceList(tyuExpr.Types);
                return(type);

            default:
                if (type.Template != null && type.TemplateArguments != null)
                {
                    this.VisitTypeReference(type.Template);
                    this.VisitTypeReferenceList(type.TemplateArguments);
                }
                return(type);
            }
        }
Example #3
0
        public static void report(Node node, int shift)
        {
            if (node == null)
            {
                indent(shift);
                Console.WriteLine("NULL ENTITY");
                return;
            }

            switch (node.NodeType)
            {
            case NodeType.AliasDefinition:
            {
                AliasDefinition alias = node as AliasDefinition;
                indent(shift);
                Console.WriteLine("using {0} = {1};", alias.Alias.Name, alias.AliasedUri.Name);
                break;
            }

            case NodeType.CompilationUnit:
            case NodeType.CompilationUnitSnippet:
            {
                CompilationUnit cu = node as CompilationUnit;

                for (int i = 0, n = cu.Nodes.Length; i < n; i++)
                {
                    report(cu.Nodes[i], 0);
                }
                break;
            }

            case NodeType.Namespace:
            {
                Namespace ns = node as Namespace;

                if (ns.UsedNamespaces != null && ns.UsedNamespaces.Length != 0)
                {
                    indent(shift);
                    Console.WriteLine("using ");
                    for (int i = 0, n = ns.UsedNamespaces.Length; i < n; i++)
                    {
                        Console.Write("{0}", ns.UsedNamespaces[i].Namespace.Name);
                        if (i < n - 1)
                        {
                            Console.Write(", ");
                        }
                    }
                    Console.WriteLine();
                }

                indent(shift);
                Console.WriteLine("namespace {0}", ns.FullNameId.Name);

                indent(shift);
                Console.WriteLine("{");

                if (ns.AliasDefinitions != null && ns.AliasDefinitions.Length != 0)
                {
                    for (int i = 0, n = ns.AliasDefinitions.Length; i < n; i++)
                    {
                        report(ns.AliasDefinitions[i], shift + ind);
                    }
                }

                if (ns.NestedNamespaces != null && ns.NestedNamespaces.Length != 0)
                {
                    for (int i = 0, n = ns.NestedNamespaces.Length; i < n; i++)
                    {
                        report(ns.NestedNamespaces[i], shift + ind);
                    }
                }

                if (ns.Types != null && ns.Types.Length != 0)
                {
                    for (int i = 0, n = ns.Types.Length; i < n; i++)
                    {
                        report(ns.Types[i], shift + ind);
                    }
                }

                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Class:
            {
                Class cls = node as Class;

                if (cls == SystemTypes.Object)
                {
                    Console.Write(cls.Name);
                    break;
                }

                indent(shift);

                if (cls.IsAbstract)
                {
                    Console.Write("abstract ");
                }
                if (cls.IsPrivate)
                {
                    Console.Write("private ");
                }
                else if (cls.IsPublic)
                {
                    Console.Write("public ");
                }
                else
                {
                    Console.Write("internal ");                             // ??????????????
                }
                if (cls.IsSealed)
                {
                    Console.Write("sealed ");
                }

                Console.Write("class ");
                if (cls.DeclaringType != null)
                {
                    Console.Write("{0}::", cls.DeclaringType.Name.Name);
                }
                Console.Write("{0}", cls.Name != null?cls.Name.Name:"<NONAME>");

                if (cls.BaseClass != null)
                {
                    Console.Write(" : {0}", cls.BaseClass.Name.Name);
                }

                if (cls.Interfaces != null && cls.Interfaces.Length != 0)
                {
                    if (cls.BaseClass != null)
                    {
                        Console.Write(",");
                    }
                    else
                    {
                        Console.Write(" :");
                    }

                    for (int i = 0, n = cls.Interfaces.Length; i < n; i++)
                    {
                        Interface interfac = cls.Interfaces[i];
                        if (interfac != null)
                        {
                            Console.Write(" {0}", interfac.Name.Name);
                        }
                        if (i < n - 1)
                        {
                            Console.Write(",");
                        }
                    }
                }
                Console.WriteLine();

                indent(shift);
                Console.WriteLine("{");

                if (cls.Members != null && cls.Members.Length != 0)
                {
                    for (int i = 0, n = cls.Members.Length; i < n; i++)
                    {
                        Member member = cls.Members[i];

                        if (member == null)
                        {
                            indent(shift + ind);
                            Console.WriteLine("<UNRESOLVED MEMBER>");
                            continue;
                        }
                        report(member, shift + ind);
                    }
                }
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Struct:
            {
                Struct struc = node as Struct;

                indent(shift);

                if (struc.IsAbstract)
                {
                    Console.Write("abstract ");
                }
                if (struc.IsPrivate)
                {
                    Console.Write("private ");
                }
                else if (struc.IsPublic)
                {
                    Console.Write("public ");
                }
                else
                {
                    Console.Write("internal ");                               // ??????????????
                }
                if (struc.IsSealed)
                {
                    Console.Write("sealed ");
                }

                Console.Write("struct ");
                if (struc.DeclaringType != null)
                {
                    Console.Write("{0}::", struc.DeclaringType.Name.Name);
                }
                Console.Write("{0}", struc.Name != null?struc.Name.Name:"<NONAME>");

                if (struc.Interfaces != null && struc.Interfaces.Length != 0)
                {
                    Console.Write(" :");
                    for (int i = 0, n = struc.Interfaces.Length; i < n; i++)
                    {
                        Interface interfac = struc.Interfaces[i];
                        if (interfac != null)
                        {
                            Console.Write(" {0}", interfac.Name.Name);
                        }
                        if (i < n - 1)
                        {
                            Console.Write(",");
                        }
                    }
                }
                Console.WriteLine();

                indent(shift);
                Console.WriteLine("{");

                if (struc.Members != null && struc.Members.Length != 0)
                {
                    for (int i = 0, n = struc.Members.Length; i < n; i++)
                    {
                        Member member = struc.Members[i];

                        if (member == null)
                        {
                            indent(shift + ind);
                            Console.WriteLine("<UNRESOLVED MEMBER>");
                            continue;
                        }
                        report(member, shift + ind);
                    }
                }
                indent(shift);
                Console.WriteLine("}");
                break;
            }

            case NodeType.EnumNode:
            {
                EnumNode enume = node as EnumNode;

                indent(shift);
                if (enume.Name != null && enume.Name.Name != null)
                {
                    Console.Write("enum {0} = ", enume.Name.Name);
                }
                else
                {
                    Console.Write("enum <NONAME> = ");
                }
                Console.Write("{");

                for (int i = 0, n = enume.Members.Length; i < n; i++)
                {
                    Field enumerator = (Field)enume.Members[i];
                    Console.Write("{0}", enumerator.Name.Name);
                    if (enumerator.DefaultValue != null)
                    {
                        Console.Write(" = {0}", enumerator.DefaultValue.ToString());
                    }
                    if (i < n - 1)
                    {
                        Console.Write(", ");
                    }
                }
                Console.WriteLine("};");

                break;
            }

            case NodeType.Interface:
            {
                Interface interfac = node as Interface;

                indent(shift);

                if (interfac.IsAbstract)
                {
                    Console.Write("abstract ");
                }
                if (interfac.IsPrivate)
                {
                    Console.Write("private ");
                }
                else if (interfac.IsPublic)
                {
                    Console.Write("public ");
                }
                else
                {
                    Console.Write("internal ");                                // ???????????
                }
                Console.WriteLine("interface {0}", interfac.Name.Name);
                indent(shift);
                Console.WriteLine("{");

                if (interfac.Members != null && interfac.Members.Length != 0)
                {
                    for (int i = 0, n = interfac.Members.Length; i < n; i++)
                    {
                        Member member = interfac.Members[i];

                        if (member == null)
                        {
                            indent(shift + ind);
                            Console.WriteLine("<UNRESOLVED MEMBER>");
                            continue;
                        }
                        report(member, shift + ind);
                    }
                }
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Method:
            case NodeType.InstanceInitializer:
            {
                Method method = node as Method;

                indent(shift);

                if (method.IsAbstract)
                {
                    Console.Write("abstract ");
                }
                if (method.IsPublic)
                {
                    Console.Write("public ");
                }
                if (method.IsStatic)
                {
                    Console.Write("static ");
                }
                if (method.IsVirtual)
                {
                    Console.Write("virtual ");
                }
                if (method.IsPrivate)
                {
                    Console.Write("private ");
                }
                if (method.OverriddenMethod != null)
                {
                    Console.Write("override ");
                }

                if (method.ReturnType != null && method.ReturnType.Name != null)
                {
                    Console.Write("{0} ", method.ReturnType.Name.Name);
                }
                if (method.Name != null)
                {
                    if (method.ImplementedInterfaceMethods != null && method.ImplementedInterfaceMethods.Length != 0)
                    {
                        Method interf = method.ImplementedInterfaceMethods[0];
                        if (interf != null)
                        {
                            string name = interf.DeclaringType.Name.Name;
                            Console.Write("{0}.", name);
                        }
                    }
                    Console.Write("{0}", method.Name.Name);
                }
                Console.Write(" (");

                if (method.Parameters != null && method.Parameters.Length != 0)
                {
                    for (int i = 0, n = method.Parameters.Length; i < n; i++)
                    {
                        Parameter par = method.Parameters[i];
                        if (par == null)
                        {
                            continue;
                        }
                        if ((par.Flags & ParameterFlags.In) != 0)
                        {
                            Console.Write("in ");
                        }
                        if ((par.Flags & ParameterFlags.Out) != 0)
                        {
                            Console.Write("out ");
                        }

                        if (par.Type != null && par.Type.Name != null)
                        {
                            Console.Write("{0}", par.Type.Name.Name);
                        }
                        else
                        {
                            report(par.Type, 0);
                        }
                        Console.Write(" {0}", par.Name.Name);
                        if (i < n - 1)
                        {
                            Console.Write(", ");
                        }
                    }
                }
                Console.Write(" )");

                // method body
                if (method.Body != null)
                {
                    Console.WriteLine();
                    report(method.Body, shift);
                }
                else
                {
                    Console.WriteLine(";");
                }
                break;
            }

            case NodeType.DelegateNode:
            {
                DelegateNode dn = node as DelegateNode;

                indent(shift);
                Console.Write("delegate ");

                if (dn.ReturnType != null && dn.ReturnType.Name != null)
                {
                    Console.Write("{0} ", dn.ReturnType.Name.Name);
                }
                if (dn.Name != null)
                {
                    Console.Write("{0}", dn.Name.Name);
                }
                Console.Write(" (");

                if (dn.Parameters != null && dn.Parameters.Length != 0)
                {
                    for (int i = 0, n = dn.Parameters.Length; i < n; i++)
                    {
                        Parameter par = dn.Parameters[i];
                        if (par == null)
                        {
                            continue;
                        }
                        if ((par.Flags & ParameterFlags.In) != 0)
                        {
                            Console.Write("in ");
                        }
                        if ((par.Flags & ParameterFlags.Out) != 0)
                        {
                            Console.Write("out ");
                        }

                        if (par.Type != null && par.Type.Name != null)
                        {
                            Console.Write("{0}", par.Type.Name.Name);
                        }
                        else
                        {
                            report(par.Type, 0);
                        }
                        Console.Write(" {0}", par.Name.Name);
                        if (i < n - 1)
                        {
                            Console.Write(", ");
                        }
                    }
                }
                Console.WriteLine(" );");
                break;
            }

            case NodeType.StaticInitializer:
            {
                StaticInitializer si = node as StaticInitializer;

                indent(shift);

                Console.WriteLine("static {0} ( )", si.Name.Name);

                // body
                if (si.Body != null)
                {
                    report(si.Body, shift);
                }
                else
                {
                    Console.WriteLine("NO BODY");
                }
                break;
            }

            case NodeType.FieldInitializerBlock:
            {
                FieldInitializerBlock initializers = node as FieldInitializerBlock;

                indent(shift);
                if (initializers.IsStatic)
                {
                    Console.Write("static ");
                }
                Console.WriteLine("init {");
                for (int i = 0, n = initializers.Statements.Length; i < n; i++)
                {
                    report(initializers.Statements[i], shift + ind);
                }
                indent(shift);
                Console.WriteLine("}");
                break;
            }

            case NodeType.Base:
            {
                Console.Write("base");
                break;
            }

            case NodeType.Field:
            {
                Field field = node as Field;

                indent(shift);

                if (field.IsPrivate)
                {
                    Console.Write("private ");
                }
                else if (field.IsPublic)
                {
                    Console.Write("public ");
                }

                if (field.IsStatic)
                {
                    Console.Write("static ");
                }
                if (field.IsInitOnly)
                {
                    Console.Write("readonly ");
                }

                if (field.Type != null)
                {
                    if (field.Type.Name != null)
                    {
                        Console.Write("{0}", field.Type.Name.Name);
                    }
                    else
                    {
                        report(field.Type, 0);
                    }
                }
                Console.Write(" {0}", field.Name.Name);

                if (field.Initializer != null)
                {
                    Console.Write(" = ");
                    report(field.Initializer, 0);
                }
                Console.WriteLine(";");

                break;
            }

            case NodeType.VariableDeclaration:
            {
                VariableDeclaration variable = node as VariableDeclaration;

                indent(shift);
                if (variable.Type != null && variable.Type.Name != null)
                {
                    Console.Write("{0}", variable.Type.Name.Name);
                }
                else
                {
                    report(variable.Type, 0);
                }

                Console.Write(" {0}", variable.Name.Name);

                if (variable.Initializer != null)
                {
                    Console.Write(" = ");
                    report(variable.Initializer, 0);
                }
                Console.WriteLine(";");

                break;
            }

            case NodeType.LocalDeclarationsStatement:
            {
                LocalDeclarationsStatement stmt = node as LocalDeclarationsStatement;

                indent(shift);

                TypeNode type = stmt.Type;
                if (type != null && type.Name != null)
                {
                    Console.Write("{0}", type.Name.Name);
                }
                else
                {
                    report(type, 0);
                }
                Console.Write(" ");

                LocalDeclarationList list = stmt.Declarations;
                for (int i = 0, n = list.Length; i < n; i++)
                {
                    LocalDeclaration local = list[i];
                    Console.Write("{0}", local.Name.Name);
                    if (local.InitialValue != null)
                    {
                        Console.Write(" = ");
                        report(local.InitialValue, 0);
                    }
                    if (i < n - 1)
                    {
                        Console.Write(", ");
                    }
                }
                Console.WriteLine(";");
                break;
            }

            case NodeType.Property:
            {
                Property property = node as Property;

                indent(shift);

                if (property.IsPrivate)
                {
                    Console.Write("private ");
                }
                else if (property.IsPublic)
                {
                    Console.Write("public ");
                }

                if (property.IsStatic)
                {
                    Console.Write("static ");
                }

                if (property != null)
                {
                    if (property.Type != null && property.Type.Name != null)
                    {
                        Console.Write("{0} ", property.Type.Name.Name);
                    }

                    if (property.ImplementedTypes != null)
                    {
                        TypeNode typ = property.ImplementedTypes[0];
                        Console.Write("{0}.", typ.Name.Name);
                    }
                    if (property.Name != null)
                    {
                        Console.WriteLine("{0}", property.Name.Name);
                    }
                }
                indent(shift);
                Console.WriteLine("{");

                if (property.Getter != null)
                {
                    report(property.Getter, shift + ind);
                }
                if (property.Setter != null)
                {
                    report(property.Setter, shift + ind);
                }

                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Lock:
            {
                Lock _lock = node as Lock;

                indent(shift);
                Console.Write("lock(");
                report(_lock.Guard, shift);
                Console.WriteLine(")");
                report(_lock.Body, shift + ind);
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Block:
            {
                Block block = node as Block;
                if (block == null || block.Statements == null)
                {
                    break;
                }
                indent(shift);
                Console.WriteLine("{");

                for (int i = 0, n = block.Statements.Length; i < n; i++)
                {
                    report(block.Statements[i], shift + ind);
                    Console.WriteLine();
                }
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.MemberBinding:
            {
                MemberBinding mb = node as MemberBinding;
                if (mb.TargetObject != null)
                {
                    report(mb.TargetObject, 0);
                }
                else if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null)
                {
                    Console.Write(mb.BoundMember.DeclaringType.Name);
                }
                Console.Write(".");
                if (mb.BoundMember.Name != null)
                {
                    Console.Write(mb.BoundMember.Name.Name);
                }
                else
                {
                    report(mb.BoundMember, 0);
                }
                break;
            }

            case NodeType.AssignmentStatement:
            {
                AssignmentStatement assignment = node as AssignmentStatement;

                indent(shift);

                report(assignment.Target, 0);
                switch (assignment.Operator)
                {
                case NodeType.Nop: Console.Write(" = "); break;

                case NodeType.Add: Console.Write(" += "); break;

                case NodeType.Add_Ovf: Console.Write(" += "); break;

                case NodeType.Add_Ovf_Un: Console.Write(" += "); break;

                case NodeType.Sub: Console.Write(" -= "); break;

                case NodeType.Sub_Ovf: Console.Write(" -= "); break;

                case NodeType.Sub_Ovf_Un: Console.Write(" -= "); break;

                case NodeType.Mul: Console.Write(" *= "); break;

                case NodeType.Mul_Ovf: Console.Write(" *= "); break;

                case NodeType.Mul_Ovf_Un: Console.Write(" *= "); break;
                }
                report(assignment.Source, 0);
                Console.Write(";");
                break;
            }

            case NodeType.ExpressionStatement:
            {
                ExpressionStatement exprStatement = node as ExpressionStatement;

                indent(shift);

                report(exprStatement.Expression, 0);
                Console.Write(";");
                break;
            }

            case NodeType.Return:
            {
                Return return_stmt = node as Return;

                indent(shift);
                Console.Write("return");
                if (return_stmt.Expression != null)
                {
                    Console.Write(" ");
                    report(return_stmt.Expression, 0);
                }
                Console.Write(";");

                break;
            }

            case NodeType.Branch:
            {
                Branch branch = node as Branch;

                indent(shift);
                Console.WriteLine("break; (???)");

                break;
            }

            case NodeType.For:
            {
                For for_stmt = node as For;

                indent(shift);
                Console.Write("for ( ");
                for (int i = 0, n = for_stmt.Initializer.Length; i < n; i++)
                {
                    report(for_stmt.Initializer[i], 0);
                }
                report(for_stmt.Condition, 0);
                Console.Write("; ");
                for (int i = 0, n = for_stmt.Incrementer.Length; i < n; i++)
                {
                    report(for_stmt.Incrementer[i], 0);
                }
                Console.WriteLine(")");

                indent(shift);
                Console.WriteLine("{");
                report(for_stmt.Body, shift + ind);
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.While:
            {
                While while_loop = node as While;

                indent(shift);
                Console.Write("while ( ");
                report(while_loop.Condition, 0);
                Console.WriteLine(" )");

                report(while_loop.Body, shift);

                break;
            }

            case NodeType.DoWhile:
            {
                DoWhile repeat = node as DoWhile;

                indent(shift);
                Console.WriteLine("do");
                report(repeat.Body, shift);

                indent(shift);
                Console.Write("while (");
                report(repeat.Condition, 0);
                Console.WriteLine(" );");

                break;
            }

            case NodeType.If:
            {
                If if_stmt = node as If;

                indent(shift);
                Console.Write("if ( ");
                report(if_stmt.Condition, 0);
                Console.WriteLine(" )");

                report(if_stmt.TrueBlock, shift);

                if (if_stmt.FalseBlock == null ||
                    if_stmt.FalseBlock.Statements == null ||
                    if_stmt.FalseBlock.Statements.Length == 0)
                {
                    break;
                }

                indent(shift);
                Console.WriteLine("else");
                report(if_stmt.FalseBlock, shift);

                break;
            }

            case NodeType.Switch:
            {
                Switch swtch = node as Switch;

                indent(shift);
                Console.Write("switch ( ");
                report(swtch.Expression, 0);
                Console.WriteLine(" )");

                indent(shift);
                Console.WriteLine("{");

                for (int i = 0, n = swtch.Cases.Length; i < n; i++)
                {
                    indent(shift + ind);
                    if (swtch.Cases[i].Label != null)
                    {
                        Console.Write("case ");
                        report(swtch.Cases[i].Label, 0);
                        Console.WriteLine(":");
                    }
                    else
                    {
                        Console.WriteLine("default:");
                    }
                    report(swtch.Cases[i].Body, shift + ind);
                }
                indent(shift);
                Console.WriteLine("}");

                break;
            }

            case NodeType.Throw:
            {
                Throw thro = node as Throw;

                indent(shift);
                Console.Write("throw (");
                report(thro.Expression, 0);
                Console.Write(");");
                break;
            }

            case NodeType.Exit:
            {
                indent(shift);
                Console.WriteLine("exit;");
                break;
            }

            case NodeType.Continue:
            {
                indent(shift);
                Console.WriteLine("continue;");
                break;
            }

            case NodeType.Try:
            {
                Try trys = node as Try;

                indent(shift);
                Console.WriteLine("try {");
                report(trys.TryBlock, shift + ind);
                indent(shift);
                Console.WriteLine("}");
                if (trys.Catchers != null)
                {
                    for (int i = 0, n = trys.Catchers.Length; i < n; i++)
                    {
                        indent(shift);
                        if (trys.Catchers[i].Type != null)
                        {
                            Console.Write("catch ( {0} ", trys.Catchers[i].Type.FullName);
                        }
                        else
                        {
                            Console.Write("catch ( ");
                        }
                        if (trys.Catchers[i].Variable != null)
                        {
                            report(trys.Catchers[i].Variable, 0);
                        }
                        Console.WriteLine(" ) {");
                        report(trys.Catchers[i].Block, shift + ind);
                        indent(shift);
                        Console.WriteLine("}");
                    }
                }
                if (trys.Finally != null && trys.Finally.Block != null)
                {
                    indent(shift);
                    Console.WriteLine("finally");
                    report(trys.Finally.Block, shift);
                }
                break;
            }

            case NodeType.BlockExpression:
            {
                BlockExpression be = node as BlockExpression;

                Console.WriteLine("(");
                StatementList sl = be.Block.Statements;
                for (int i = 0, n = sl.Length; i < n; i++)
                {
                    report(sl[i], shift + ind);
                }
                indent(shift);
                Console.Write(")");
                break;
            }

            case NodeType.ArrayTypeExpression:
            {
                ArrayTypeExpression array = node as ArrayTypeExpression;

                indent(shift);

                if (array.ElementType != null &&
                    array.ElementType.Name != null &&
                    array.ElementType.Name.Name != null)
                {
                    Console.Write(array.ElementType.Name.Name);
                }
                else
                {
                    report(array.ElementType, 0);
                }

                Console.Write("[");
                for (int i = 0, n = array.Rank; i < n; i++)
                {
                    if (array.Sizes != null)
                    {
                        Console.Write(array.Sizes[i]);
                    }
                    if (i < n - 1)
                    {
                        Console.Write(",");
                    }
                }
                Console.Write("]");

                break;
            }

            case NodeType.Construct:
            {
                Construct construct = node as Construct;

                indent(shift);
                Console.Write("new ");
                report(construct.Constructor, 0);
                Console.Write("(");
                if (construct.Operands != null)
                {
                    for (int i = 0, n = construct.Operands.Length; i < n; i++)
                    {
                        report(construct.Operands[i], 0);
                        if (i < n - 1)
                        {
                            Console.Write(",");
                        }
                    }
                }
                Console.Write(")");
                break;
            }

            case NodeType.ConstructArray:
            {
                ConstructArray initializer = node as ConstructArray;

                Console.Write("new ");

                if (initializer.ElementType != null &&
                    initializer.ElementType.Name != null &&
                    initializer.ElementType.Name.Name != null)
                {
                    Console.Write(initializer.ElementType.Name.Name);
                }
                else
                {
                    report(initializer.ElementType, 0);
                }

                Console.Write("[");
                for (int i = 0, n = initializer.Operands.Length; i < n; i++)
                {
                    report(initializer.Operands[i], 0);
                    if (i < n - 1)
                    {
                        Console.Write(",");
                    }
                }
                Console.Write("]");

                break;
            }

            case NodeType.ConstructDelegate:
            {
                ConstructDelegate cd = node as ConstructDelegate;

                // Console.Write("new {0}({1})",cd.DelegateType.Name.Name,cd.MethodName.Name);
                Console.Write("new {0}(", cd.DelegateType.Name.Name);
                report(cd.TargetObject, 0);
                Console.Write(".{0})", cd.MethodName.Name);
                // cd.Type;
                break;
            }

            default:
            {
                if (node is ZonnonCompilation)
                {
                    ZonnonCompilation zc = node as ZonnonCompilation;
                    report(zc.CompilationUnits[0], shift);
                }
                // Expression?

                else if (node is MethodCall)
                {
                    MethodCall call = node as MethodCall;

                    report(call.Callee, 0);
                    Console.Write("(");

                    if (call.Operands != null && call.Operands.Length != 0)
                    {
                        for (int i = 0, n = call.Operands.Length; i < n; i++)
                        {
                            report(call.Operands[i], 0);
                            if (i < n - 1)
                            {
                                Console.Write(",");
                            }
                        }
                    }

                    Console.Write(")");
                }
                else if (node is Variable)
                {
                    Variable variable = node as Variable;
                    Console.Write("{0}", variable.Name.Name);
                }
                else if (node is Identifier)
                {
                    Identifier identifier = node as Identifier;
                    Console.Write("{0}", identifier.Name);
                }
                else if (node is QualifiedIdentifier)
                {
                    QualifiedIdentifier qualid = node as QualifiedIdentifier;
                    report(qualid.Qualifier, 0);
                    Console.Write(".{0}", qualid.Identifier == null?"<UNRESOLVED>":qualid.Identifier.Name);
                }
                else if (node is Literal)
                {
                    Literal literal = node as Literal;
                    if (literal.Value == null)
                    {
                        Console.Write("null");
                    }
                    else
                    {
                        if (literal.Value is string)
                        {
                            Console.Write("\"");
                        }
                        else if (literal.Value is char)
                        {
                            Console.Write("'");
                        }
                        Console.Write("{0}", literal.Value.ToString());
                        if (literal.Value is string)
                        {
                            Console.Write("\"");
                        }
                        else if (literal.Value is char)
                        {
                            Console.Write("'");
                        }
                    }
                }
                else if (node is Indexer)
                {
                    Indexer indexer = node as Indexer;
                    report(indexer.Object, 0);
                    Console.Write("[");
                    for (int i = 0, n = indexer.Operands.Length; i < n; i++)
                    {
                        report(indexer.Operands[i], 0);
                        if (i < n - 1)
                        {
                            Console.Write(",");
                        }
                    }
                    Console.Write("]");
                }
                else if (node is UnaryExpression)
                {
                    UnaryExpression unexpr = node as UnaryExpression;

                    bool add_pars = unexpr.Operand is BinaryExpression ||
                                    unexpr.Operand is UnaryExpression;

                    switch (unexpr.NodeType)
                    {
                    case NodeType.Add: Console.Write("+");  break;

                    case NodeType.Sub: Console.Write("-");  break;

                    case NodeType.Neg: Console.Write("-");  break;

                    case NodeType.Not: Console.Write("~");  break;

                    case NodeType.UnaryPlus: Console.Write("+"); break;

                    case NodeType.LogicalNot: Console.Write("!"); break;

                    case NodeType.Conv_U2: Console.Write("(UInt16)"); break;

                    case NodeType.RefAddress: Console.Write("ref "); break;

                    case NodeType.Ckfinite: Console.Write("(Ckfinite)"); break;

                    default:           Console.Write("???");  break;
                    }

                    if (add_pars)
                    {
                        Console.Write("(");
                    }
                    report(unexpr.Operand, 0);
                    if (add_pars)
                    {
                        Console.Write(")");
                    }
                }
                else if (node is BinaryExpression)
                {
                    BinaryExpression binexpr = node as BinaryExpression;

                    bool add_pars = binexpr.Operand1 is BinaryExpression ||
                                    binexpr.Operand1 is UnaryExpression;

                    if (binexpr.NodeType == NodeType.Castclass)
                    {
                        Console.Write("(");
                        report(binexpr.Operand2, 0);
                        Console.Write(")");

                        if (add_pars)
                        {
                            Console.Write("(");
                        }
                        report(binexpr.Operand1, 0);
                        if (add_pars)
                        {
                            Console.Write(")");
                        }
                        break;
                    }

                    if (add_pars)
                    {
                        Console.Write("(");
                    }
                    report(binexpr.Operand1, 0);
                    if (add_pars)
                    {
                        Console.Write(")");
                    }

                    switch (binexpr.NodeType)
                    {
                    case NodeType.Add: Console.Write(" + "); break;

                    case NodeType.Add_Ovf: Console.Write(" + "); break;

                    case NodeType.Add_Ovf_Un: Console.Write(" + "); break;

                    case NodeType.Sub: Console.Write(" - "); break;

                    case NodeType.Sub_Ovf: Console.Write(" - "); break;

                    case NodeType.Sub_Ovf_Un: Console.Write(" - "); break;

                    case NodeType.Mul: Console.Write(" * "); break;

                    case NodeType.Mul_Ovf: Console.Write(" * "); break;

                    case NodeType.Mul_Ovf_Un: Console.Write(" * "); break;

                    case NodeType.Div: Console.Write(" / "); break;

                    // case NodeType.Div : Console.Write(" DIV "); break;  // "DIV" ?????
                    case NodeType.Rem: Console.Write(" % "); break;          // "MOD" ?????

                    case NodeType.Or: Console.Write(" | "); break;

                    case NodeType.And: Console.Write(" & "); break;

                    case NodeType.Eq: Console.Write(" == "); break;

                    case NodeType.Ne: Console.Write(" != "); break;

                    case NodeType.Lt: Console.Write(" < "); break;

                    case NodeType.Le: Console.Write(" <= "); break;

                    case NodeType.Gt: Console.Write(" > "); break;

                    case NodeType.Ge: Console.Write(" >= "); break;

                    case NodeType.LogicalOr: Console.Write(" || "); break;

                    case NodeType.LogicalAnd: Console.Write(" && "); break;

                    case NodeType.Is: Console.Write(" is "); break;

                    case NodeType.Comma: Console.Write(","); break;

                    // case OPERATORS.In           : expression.NodeType = NodeType  // "IN" break;
                    // case OPERATORS.Implements   : expression.NodeType = NodeType  // "IMPLEMENTS" break;
                    default: Console.Write(" !! "); break;
                    }

                    add_pars = binexpr.Operand2 is BinaryExpression ||
                               binexpr.Operand2 is UnaryExpression;

                    if (add_pars)
                    {
                        Console.Write("(");
                    }
                    report(binexpr.Operand2, 0);
                    if (add_pars)
                    {
                        Console.Write(")");
                    }
                }
                else if (node is TernaryExpression)
                {
                    TernaryExpression ter = node as TernaryExpression;
                    if (ter.NodeType == NodeType.Conditional)
                    {
                        report(ter.Operand1, 0);
                        Console.Write(" ? ");
                        report(ter.Operand2, 0);
                        Console.Write(" : ");
                        report(ter.Operand3, 0);
                    }
                }
                else if (node is PostfixExpression)
                {
                    PostfixExpression postfixExpr = node as PostfixExpression;

                    report(postfixExpr.Expression, 0);

                    switch (postfixExpr.Operator)
                    {
                    case NodeType.Increment: Console.Write("++"); break;

                    case NodeType.Decrement: Console.Write("--"); break;

                    default: Console.Write("???"); break;
                    }
                }
                else if (node is LabeledStatement)
                {
                    LabeledStatement lbst = node as LabeledStatement;
                    indent(shift);
                    report(lbst.Label, 0);
                    Console.Write(" : ");
                    report(lbst.Statement, 0);
                }
                else if (node is Goto)
                {
                    Goto gt = node as Goto;
                    indent(shift);
                    Console.Write("goto ");
                    report(gt.TargetLabel, 0);
                }
                else
                {
                    indent(shift);
                    Console.WriteLine("No code for reporting {0}:{1}", node.UniqueKey, node.ToString());
                }
                break;
            }
            }
        }
Example #4
0
        public static Block createElementInitializerInternal(TYPE type, Expression indexer, int level, List <Expression> nonConstantDimensions, bool skipFirstLevel, SourceContext sourceContext)
        {
            // Generates internal part of array initializer:
            // either object constructor or, again, array initializer.
            // Check if the type is ARRAY.
            if (!(type is ARRAY_TYPE) && !(type is OBJECT_TYPE))
            {
                return(null);
            }

            if (type is ARRAY_TYPE)
            {
                EXPRESSION_LIST   declaredDimensions = ((ARRAY_TYPE)type).dimensions;
                int               Rank       = declaredDimensions.Length;
                List <Expression> dimensions = new List <Expression>();
                // Check if all dimensions are constants or there is an expression available.
                for (int i = 0, n = Rank; i < n; i++)
                {
                    if (declaredDimensions[i] == null || declaredDimensions[i].calculate() == null)
                    {
                        if (nonConstantDimensions == null)
                        {
                            return(null);
                        }
                        if (nonConstantDimensions.Count > 0)
                        {
                            dimensions.Add(nonConstantDimensions[0]);
                            nonConstantDimensions.RemoveAt(0);
                        }
                        else
                        {
                            ERROR.MissingParameters(Rank, type.sourceContext);
                            return(null);
                        }
                    }
                    else
                    {
                        long    d   = (long)declaredDimensions[i].calculate();
                        Literal dim = new Literal((int)d, SystemTypes.Int32);
                        dimensions.Add(dim);
                    }
                }


                Block block = new Block(new StatementList());

                // Generate array initializer:
                //  x = new object[n];

                if (skipFirstLevel && level == 0)
                {
                    goto Bypass;
                }
                AssignmentStatement array_initializer = new AssignmentStatement();
                array_initializer.NodeType = NodeType.AssignmentStatement;
                array_initializer.Operator = NodeType.Nop;  // this means "normal" assignment, but not += etc.

                // Generate 'new object[n]'
                ConstructArray array_construct = new ConstructArray();

                Node elem_type = ((ARRAY_TYPE)type).base_type.convert();
                if (elem_type is ArrayTypeExpression)
                {
                    ArrayTypeExpression arr_type = (elem_type.Clone()) as ArrayTypeExpression;
                    //  for ( int i=0, n=arr_type.Rank; i<n; i++ )
                    //      arr_type.Sizes[i] = -1;
                    elem_type = arr_type;
                }
                array_construct.ElementType   = (TypeNode)elem_type;
                array_construct.Rank          = Rank;
                array_construct.SourceContext = sourceContext;
                array_construct.Type          = (TypeNode)type.convert();
                array_construct.Operands      = new ExpressionList();
                for (int i = 0; i < Rank; i++)
                {
                    array_construct.Operands.Add(dimensions[i]);
                }

                array_initializer.Source        = array_construct;
                array_initializer.Target        = indexer;
                array_initializer.SourceContext = sourceContext;
                block.Statements.Add(array_initializer);

Bypass:

                // Generate x[i0,i1,...] for passing to the recursive call.
                Indexer new_indexer     = new Indexer();
                new_indexer.Object      = indexer;
                new_indexer.Type        = type.convert() as TypeNode;
                new_indexer.ElementType = ((ARRAY_TYPE)type).base_type.convert() as TypeNode;
                new_indexer.Operands    = new ExpressionList();
                for (int i = 0; i < Rank; i++)
                {
                    Identifier index = Identifier.For("_i" + (level + i).ToString());
                    new_indexer.Operands.Add(index);
                }

                // Generate the last part (see comment, part 4, below).
                Block elem_initializers =
                    createElementInitializerInternal(((ARRAY_TYPE)type).base_type, new_indexer, level + Rank, nonConstantDimensions, true, sourceContext);
                if (elem_initializers == null)
                {
                    return(block);
                }
                // We do not need loops to initialize elements...
                // Return just array initializer.
                // Otherwise go generate initializers.

                // Generate
                // 1) int i0, i1, ...;
                // 2) for (int i1=0; i1<n; i1++)
                //        for (int i2=0; i2<m; i2++)
                //            ...
                //
                // Generate recursively:
                // 3) Initializers for array elements:  x[i1,i2,...] = new object[n];
                // 4) Initializers for every element (the similar loop(s)).

                // Generate int i0, i1, ...;
                for (int i = 0; i < Rank; i++)
                {
                    VariableDeclaration locali =
                        new VariableDeclaration(Identifier.For("_i" + (level + i).ToString()), SystemTypes.Int32, null);
                    block.Statements.Add(locali);
                }

                // Generate loop headers:
                //      for (int i1=0; i1<n; i1++)
                //          for (int i2=0; i2<m; i2++)
                //              ...

                Block owner = block;  // where to put generated for-node
                for (int i = 0; i < Rank; i++)
                {
                    For forStatement = new For();
                    // forStatement.NodeType;
                    forStatement.SourceContext = sourceContext;

                    // Making for-statement's body
                    forStatement.Body           = new Block();
                    forStatement.Body.Checked   = true;
                    forStatement.Body.HasLocals = false;
                    // forStatement.Body.NodeType;
                    // forStatement.Body.Scope;
                    forStatement.Body.SourceContext = sourceContext;
                    forStatement.Body.SuppressCheck = false;
                    forStatement.Body.Statements    = new StatementList();
                    // Now leave the body empty...

                    // Making condition: i<n
                    BinaryExpression condition = new BinaryExpression();
                    condition.NodeType      = NodeType.Lt;
                    condition.Operand1      = Identifier.For("_i" + (level + i).ToString());
                    condition.Operand2      = dimensions[i];
                    condition.SourceContext = sourceContext;
                    forStatement.Condition  = condition;

                    // Making incrementer: i+=1
                    forStatement.Incrementer = new StatementList();
                    AssignmentStatement assignment = new AssignmentStatement();
                    assignment.NodeType = NodeType.AssignmentStatement;
                    assignment.Operator = NodeType.Add;  // Hope this means +=
                    // assignment.OperatorOverload
                    assignment.Source        = new Literal((int)1, SystemTypes.Int32);
                    assignment.SourceContext = sourceContext;
                    assignment.Target        = Identifier.For("_i" + (level + i).ToString());
                    forStatement.Incrementer.Add(assignment);

                    // Making initializer: i=0
                    forStatement.Initializer = new StatementList();
                    AssignmentStatement initializer = new AssignmentStatement();
                    initializer.NodeType      = NodeType.AssignmentStatement;
                    initializer.Operator      = NodeType.Nop; // this means "normal" assignment, but not += etc.
                    initializer.Source        = new Literal(0, SystemTypes.Int32);
                    initializer.Target        = Identifier.For("_i" + (level + i).ToString());
                    initializer.SourceContext = sourceContext;

                    forStatement.Initializer.Add(initializer);

                    owner.Statements.Add(forStatement);
                    owner = forStatement.Body; // for next iteration
                }

                // Adding element initializers generated in advance.
                owner.Statements.Add(elem_initializers);

                return(block);
            }
            else if (type is OBJECT_TYPE)
            {
                // Check if the type is VAL-object.
                if (!((OBJECT_TYPE)type).ObjectUnit.modifiers.Value)
                {
                    return(null);
                }

                Block block = new Block(new StatementList());

                // Generate 'new obj'


                DECLARATION objct = ((OBJECT_TYPE)type).ObjectUnit;

                // We do it for only own value types. They have
                // extra constcutor that takes ont fictive intgere. Might have
                // Chtck and call it
                Construct construct = new Construct();

                // Strange thing: CCI expects _class_ in Construst.Constructor,
                // but not a constructor itself!..
                // construct.Constructor = new MemberBinding(null,((TypeNode)objct.convert()).GetConstructors()[0]); //  NODE.convertTypeName(objct);
                construct.Constructor      = new MemberBinding(null, (TypeNode)objct.convert());
                construct.Constructor.Type = SystemTypes.Type;

                construct.Operands      = new ExpressionList();
                construct.SourceContext = sourceContext;
                construct.Type          = (TypeNode)objct.convert();
                construct.Operands.Add(new Literal(1, SystemTypes.Int32));

                // Generate x[i0,i1,...] = new obj;
                AssignmentStatement main_initializer = new AssignmentStatement();
                main_initializer.NodeType      = NodeType.AssignmentStatement;
                main_initializer.Operator      = NodeType.Nop; // this means "normal" assignment, but not += etc.
                main_initializer.Source        = construct;
                main_initializer.Target        = indexer;
                main_initializer.SourceContext = sourceContext;



                block.Statements.Add(main_initializer);
                return(block);
            }
            else
            if (type is EXTERNAL_TYPE)
            {
                // Only value types might need extra calls
                Struct str = ((EXTERNAL_TYPE)type).entity as Struct;

                InstanceInitializer ctr         = str.GetConstructor(new TypeNode[] { SystemTypes.Int32 });
                bool possibly_was_our_structure = (ctr != null);
                if (ctr == null)
                {
                    ctr = str.GetConstructor(new TypeNode[0] {
                    });
                }

                // TO_DO: When metadata is available replace this with
                // more consistent check

                Block block = new Block(new StatementList());

                // Generate 'new obj'
                Construct construct = new Construct();


                construct.Constructor = new MemberBinding(null, ctr);
                construct.Operands    = new ExpressionList();
                construct.Type        = str;
                // We do it for only own value types. They have
                // extra constcutor that takes ont fictive intgere. Might have
                // Chtck and call it
                if (possibly_was_our_structure)
                {
                    construct.Operands.Add(Literal.Int32MinusOne);
                }

                // Generate x[i0,i1,...] = new obj;
                AssignmentStatement main_initializer = new AssignmentStatement();
                main_initializer.NodeType      = NodeType.AssignmentStatement;
                main_initializer.Operator      = NodeType.Nop; // this means "normal" assignment, but not += etc.
                main_initializer.Source        = construct;
                main_initializer.Target        = indexer;
                main_initializer.SourceContext = sourceContext;

                indexer.Type = construct.Type;

                block.Statements.Add(main_initializer);
                return(block);
            }
            else
            {
                return(null);
            }
        }
Example #5
0
 private Expression ParseArrayInitializer(ArrayTypeExpression arrayTypeExpression, TokenSet followers)
   //^ requires this.currentToken == Token.LeftBrace;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   uint rank = arrayTypeExpression.Rank;
   SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   List<Expression> initializers = this.ParseArrayInitializers(rank, arrayTypeExpression.ElementType, followers, false, slb);
   //^ assert followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   List<Expression> lowerBounds = new List<Expression>(0);
   List<Expression> sizes = new List<Expression>(0);
   Expression result = new CreateArray(arrayTypeExpression.ElementType, initializers, lowerBounds, rank, sizes, slb);
   //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   return result;
 }
Example #6
0
 private Expression ParseNew(TokenSet followers) 
   //^ requires this.currentToken == Token.New;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken);
   this.GetNextToken();
   if (this.currentToken == Token.LeftBracket)
     return this.ParseNewImplicitlyTypedArray(ctx, followers);
   if (this.currentToken == Token.LeftBrace)
     return this.ParseNewAnonymousTypeInstance(ctx, followers);
   TypeExpression t = this.ParseBaseTypeExpression(false, followers|Parser.InfixOperators|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
   if (this.currentToken == Token.Conditional) {
     SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation);
     slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     //^ assume this.currentToken == Token.Conditional; //no side effects from the methods can touch this.currentToken
     this.GetNextToken();
     t = new NullableTypeExpression(t, slb);
   //} else if (this.currentToken == Token.LogicalNot) {
   //  TypeExpression type = t;
   //  t = new NonNullableTypeExpression(type);
   //  t.SourceContext = type.SourceContext;
   //  t.SourceContext.EndPos = this.scanner.endPos;
   //  this.GetNextToken();
   } else if (this.currentToken == Token.Multiply) {
     SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation);
     slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
     //^ assume this.currentToken == Token.Multiply; //no side effects from the methods can touch this.currentToken
     this.GetNextToken();
     t = new PointerTypeExpression(t, slb);
   }
   ctx.UpdateToSpan(t.SourceLocation);
   TypeExpression et = t;
   uint rank = 0;
   while (this.currentToken == Token.LeftBracket) {
     Token nextTok = this.PeekNextToken();
     if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier
     rank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
     et = t;
     t = new ArrayTypeExpression(et, rank, ctx);
   }
   if (rank > 0) {
     //new T[] {...} or new T[,] {{..} {...}...}, etc where T can also be an array type
     List<Expression> initializers;
     if (this.currentToken == Token.LeftBrace)
       initializers = this.ParseArrayInitializers(rank, et, followers, false, ctx);
     else {
       initializers = new List<Expression>(0);
       if (Parser.UnaryStart[this.currentToken])
         this.HandleError(Error.ExpectedLeftBrace);
       else
         this.HandleError(Error.MissingArraySize);
       while (Parser.UnaryStart[this.currentToken]) {
         this.ParseExpression(followers|Token.Comma|Token.RightBrace);
         if (this.currentToken != Token.Comma) break;
         this.GetNextToken();
       }
       ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
       this.SkipOverTo(Token.RightBrace, followers);
     }
     return new CreateArray(et, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, new List<Expression>(0).AsReadOnly(), ctx);
   }
   if (this.currentToken == Token.LeftBracket) {
     //new T[x] or new T[x,y] etc. possibly followed by an initializer or element type rank specifier
     this.GetNextToken();
     List<Expression> sizes = this.ParseExpressionList(ctx, followers|Token.LeftBrace|Token.LeftBracket);
     rank = (uint)sizes.Count;
     List<Expression> initializers;
     if (this.currentToken == Token.LeftBrace)
       initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx);
     else {
       uint elementRank = 0;
     tryAgain:
       while (this.currentToken == Token.LeftBracket) {
         Token nextTok = this.PeekNextToken();
         if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier
         elementRank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
         t = new ArrayTypeExpression(t, elementRank, ctx);
       }
       if (this.currentToken == Token.LeftBrace)
         initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx);
       else {
         if (this.currentToken == Token.LeftBracket) { //new T[x][y] or something like that
           this.GetNextToken();
           this.HandleError(Error.InvalidArray);
           elementRank = (uint)this.ParseExpressionList(ctx, followers).Count;
           goto tryAgain;
         } else {
           initializers = new List<Expression>(0);
           ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken);
           this.SkipTo(followers);
         }
       }
     }
     return new CreateArray(t, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, sizes.AsReadOnly(), ctx);
   }
   //new T(...)
   IEnumerable<Expression> arguments = Expression.EmptyCollection;
   IEnumerable<Expression> elementValues = Expression.EmptyCollection;
   IEnumerable<NamedArgument> namedArguments = NamedArgument.EmptyCollection;
   if (this.currentToken == Token.LeftParenthesis) {
     //if (t is NonNullableTypeExpression) {
     //  this.SkipTo(followers, Error.BadNewExpr);
     //  return null;
     //}
     arguments = this.ParseArgumentList(ctx, followers|Token.LeftBrace).AsReadOnly();
   } else if (this.currentToken != Token.LeftBrace) {
     this.SkipTo(followers, Error.BadNewExpr);
   }
   Expression result = new CreateObjectInstance(t, arguments, ctx.GetSourceLocation());
   if (this.currentToken == Token.LeftBrace) {
     this.ParseElementValuesOrNamedArguments(ref elementValues, ref namedArguments, ctx, followers);
     if (elementValues != Expression.EmptyCollection)
       return new PopulateCollection(result, elementValues, ctx);
     else if (namedArguments != NamedArgument.EmptyCollection)
       return new InitializeObject(result, namedArguments, ctx);
     else {
       this.HandleError(Error.SyntaxError); //TODO: better error
     }
   }
   return result;
 }
Example #7
0
 private TypeExpression ParseArrayType(uint rank, TypeExpression elementType, SourceLocationBuilder sctx, TokenSet followers)
   //^ requires rank > 0;
   //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile;
 {
   List<uint> rankList = new List<uint>();
   for (;;) 
     // ^ invariant forall{int i in (0:rankList.Count); rankList[i] > 0}; //TODO: find out why this does not parse
   {
     rankList.Add(rank); //TODO: find away to tell Boogie that this does not modify this.currentToken
     if (this.currentToken != Token.LeftBracket) break;
     rank = this.ParseRankSpecifier(sctx, followers|Token.LeftBracket);
   }
   for (int i = rankList.Count; i > 0; i--)
     // ^ invariant forall{int i in (0:rankList.Count); rankList[i] > 0};
   {
     rank = rankList[i-1];
     //^ assume rank > 0; 
     elementType = new ArrayTypeExpression(elementType, rank, sctx.GetSourceLocation()); //TODO: find away to tell Boogie that this does not modify this.currentToken
   }
   //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile;
   return elementType;
 }
 public virtual TypeNode VisitArrayTypeExpression(ArrayTypeExpression atExpr){
   if (atExpr == null) return null;
   this.AbstractSealedUsedAsType = Error.AbstractSealedArrayElementType;
   TypeNode et = this.VisitTypeReference(atExpr.ElementType, true);
   this.AbstractSealedUsedAsType = Error.NotAType;
   if (et == null) return null;
   if (et == SystemTypes.DynamicallyTypedReference || et == SystemTypes.ArgIterator){
     this.HandleError(atExpr.ElementType, Error.ArrayElementCannotBeTypedReference, this.GetTypeName(et));
     return null;
   }
   if (atExpr.Rank == 1 && (atExpr.Sizes == null || atExpr.Sizes.Length == 0) && (atExpr.LowerBounds == null || atExpr.LowerBounds.Length == 0))
     return et.GetArrayType(atExpr.Rank);
   else
     return et.GetArrayType(atExpr.Rank, atExpr.Sizes, atExpr.LowerBounds);
 }