Example #1
0
        Identifier ReadIdentifer(IdContainer Container, Identifier Parent)
        {
            var IdScope = Container.GetParent <IdentifierScope>();

            if (IdScope == null || IdScope.Identifier != Parent)
            {
                throw new ApplicationException();
            }

            var IdPos = Reader.BaseStream.Position - BeginningPos;

            if (IdPos != ReadLEB128_Long())
            {
                throw new InvalidAssemblyException();
            }

#warning CHECK
            var ParentIdRef = ReadLEB128_Int();

            var Byte           = Reader.ReadByte();
            var DeclaredIdType = (DeclaredIdType)(Byte & 15);
            var Access         = (IdentifierAccess)(Byte >> 4);

            var FlagData       = Reader.ReadUInt16();
            var Flags          = (IdentifierFlags)FlagData & IdentifierFlags.All;
            var HasName        = (FlagData & 16384) != 0;
            var HasOverloads   = (FlagData & 32768) != 0;
            var HasSpecialName = (Flags & IdentifierFlags.SpecialName) != 0;

            var Name         = HasName ? new CodeString(ReadLEB128_String()) : new CodeString();
            var AssemblyName = HasSpecialName ? ReadLEB128_String() : null;

            var StructuredScope = Container as StructuredScope;
            var IsGlobal        = (Flags & IdentifierFlags.Static) != 0 || !(Container.RealContainer is StructuredScope);

            var Ret = (Identifier)null;
            if (DeclaredIdType == DeclaredIdType.Alias)
            {
                Ret = new IdentifierAlias(Container, Name, null);
                ReadReference(Ret, ReferenceDestination.RealId, -1);
                UpdateList.Add(Ret);
            }
            else if (DeclaredIdType == DeclaredIdType.Class || DeclaredIdType == DeclaredIdType.Struct)
            {
                StructuredType Structured;
                if (DeclaredIdType == DeclaredIdType.Class)
                {
                    Ret = Structured = new ClassType(Container, Name);
                }
                else
                {
                    Ret = Structured = new StructType(Container, Name);
                }

                Structured.InstanceSize = ReadLEB128_Int();
                if (Structured.InstanceSize <= 0)
                {
                    throw new InvalidAssemblyException("Invalid size");
                }

                Structured.Align            = ReadLEB128_Int();
                Structured.LayoutCalculated = true;
                if (!DataStoring.VerifyAlign(Structured.Align))
                {
                    throw new InvalidAssemblyException("Invalid alingment");
                }

                if (DeclaredIdType == DeclaredIdType.Struct)
                {
                    Structured.Size = Structured.InstanceSize;
                }

                Structured.Guid = ReadGuid();
                var BaseCount = ReadLEB128_Int();
                Structured.BaseStructures = new StructureBase[BaseCount];
                for (var i = 0; i < BaseCount; i++)
                {
                    ReadReferenceDeclared(Structured, ReferenceDestination.Base, i);
                }

                Structured.FunctionTableIndex = ReadLEB128_Int();
                var Scope = new StructuredScope(Container, new CodeString(), Structured);
                Container.Children.Add(Scope);
                Structured.StructuredScope = Scope;
                ReadIdList(Scope, Structured);
                UpdateList.Add(Ret);
            }
            else if (DeclaredIdType == DeclaredIdType.Enum || DeclaredIdType == DeclaredIdType.Flag)
            {
                EnumType Enum;
                if (DeclaredIdType == Zinnia.DeclaredIdType.Enum)
                {
                    Ret = Enum = new EnumType(Container, Name, new CodeString());
                }
                else
                {
                    Ret = Enum = new FlagType(Container, Name, new CodeString());
                }
                ReadReference(Enum, ReferenceDestination.Children, 0);

                var Scope = new EnumScope(Container, new CodeString(), Enum);
                Container.Children.Add(Scope);
                Enum.EnumScope = Scope;

                var MemberCount = ReadLEB128_Int();
                if (MemberCount != 0)
                {
                    if (MemberCount < 0)
                    {
                        throw new InvalidAssemblyException();
                    }

                    for (var i = 0; i < MemberCount; i++)
                    {
                        var ConstName = new CodeString(ReadLEB128_String());
                        if (!ConstName.IsValidIdentifierName)
                        {
                            throw new InvalidAssemblyException("Invalid identifier name");
                        }

                        if (Identifiers.IsDefined(Scope.IdentifierList, ConstName.ToString()))
                        {
                            throw new InvalidAssemblyException("Identifier already defined");
                        }

                        var Const = new ConstVariable(Container, ConstName, Enum, ReadConst());
                        Scope.IdentifierList.Add(Const);
                    }
                }

                UpdateList.Add(Enum);
            }
            else if (DeclaredIdType == DeclaredIdType.Function || DeclaredIdType == DeclaredIdType.Constructor)
            {
                Function          Function;
                FunctionOverloads Overloads;
                if (DeclaredIdType == Zinnia.DeclaredIdType.Function)
                {
                    Overloads = Container.GetOverload(Name.ToString());
                    if (IsGlobal)
                    {
                        Ret = Function = new Function(Container, Name, null, Overloads);
                    }
                    else
                    {
                        Ret = Function = new MemberFunction(Container, Name, null, Overloads);
                    }
                }
                else
                {
                    if (HasName)
                    {
                        throw new InvalidAssemblyException("Constructors cannot have name");
                    }
                    if (StructuredScope == null)
                    {
                        throw new InvalidAssemblyException("Invalid container");
                    }

                    if (StructuredScope.ConstructorOverloads == null)
                    {
                        StructuredScope.ConstructorOverloads = new FunctionOverloads(null);
                    }

                    Overloads = StructuredScope.ConstructorOverloads;
                    Ret       = Function = new Constructor(Container, null, Overloads, new CodeString());
                }

                ReadReference(Function, ReferenceDestination.Children, 0);

                var OverloadIndex = HasOverloads ? ReadLEB128_Int() : 0;
                for (var i = 0; i < Overloads.Functions.Count; i++)
                {
                    var OverloadFunc = Overloads.Functions[i];
                    if (OverloadFunc.OverloadIndex == OverloadIndex)
                    {
                        throw new InvalidAssemblyException("Function with the same overload index");
                    }

                    /*
                     * if (Function.AreParametersSame(OverloadFunc))
                     *  throw new InvalidAssemblyException("Function with the same name and parameters");*/
                }

                Function.OverloadIndex = OverloadIndex;
                Overloads.Functions.Add(Function);

                if ((Flags & IdentifierFlags.Virtual) != 0)
                {
                    var MemberFunc = Function as MemberFunction;
                    MemberFunc.VirtualIndex = ReadLEB128_Int();
                    if ((Flags & IdentifierFlags.Override) != 0)
                    {
                        ReadReferenceDeclared(MemberFunc, ReferenceDestination.OverriddenId, -1);
                    }
                }

                Function.GlobalPointerIndex = ReadLEB128_Int();
            }
            else if (DeclaredIdType == DeclaredIdType.Destructor)
            {
                if (HasName)
                {
                    throw new InvalidAssemblyException("Destructors cannot have name");
                }
                if (StructuredScope == null)
                {
                    throw new InvalidAssemblyException("Invalid container");
                }

                var Function = new Destructor(Container, null, new CodeString());
                ReadReference(Function, ReferenceDestination.Children, 0);
                Function.GlobalPointerIndex = ReadLEB128_Int();
                Ret = Function;
            }
            else if (DeclaredIdType == DeclaredIdType.Variable)
            {
                if (IsGlobal)
                {
                    Ret = new GlobalVariable(Container, Name, null);
                }
                else
                {
                    Ret = new MemberVariable(Container, Name, null);
                }

                ReadReference(Ret, ReferenceDestination.Children, 0);

                if (!IsGlobal)
                {
                    var MemVar = Ret as MemberVariable;
                    MemVar.Offset = ReadLEB128_Int();
                }
                else
                {
                    var Global = Ret as GlobalVariable;
                    Global.GlobalPointerIndex = ReadLEB128_Int();
                }
            }
            else if (DeclaredIdType == DeclaredIdType.Constant)
            {
                var Const = new ConstVariable(Container, Name, null, null);
                ReadReference(Const, ReferenceDestination.Children, 0);
                Const.ConstInitValue = ReadConst();
                Ret = Const;
            }
            else if (DeclaredIdType == DeclaredIdType.Property)
            {
                var Property = new Property(Container, Name, (Type)null);
                var PScope   = new PropertyScope(Container, new CodeString(), Property);
                Container.Children.Add(PScope);
                Property.PropertyScope = PScope;
                ReadReference(Property, ReferenceDestination.Children, 0);
                ReadParameterReferences(Property);

                var Data = Reader.ReadByte();
                if ((Data & 1) != 0)
                {
                    PScope.Getter = ReadIdentifer(PScope, Property) as Function;
                }
                if ((Data & 2) != 0)
                {
                    PScope.Setter = ReadIdentifer(PScope, Property) as Function;
                }
                Ret = Property;
            }
            else if (DeclaredIdType == DeclaredIdType.Namespace)
            {
                var Scope = Container as NamespaceScope;
                if (Scope == null)
                {
                    throw new InvalidAssemblyException("Invalid container");
                }
                if (Access != IdentifierAccess.Public)
                {
                    throw new InvalidAssemblyException("Invalid access");
                }

                var Options = new GetIdOptions()
                {
                    Func = x => x is Namespace
                };
                var Namespace = Identifiers.GetMember(State, Parent, Name, Options) as Namespace;
                if (Namespace == null)
                {
                    Ret = Namespace = new Namespace(Container, Name);
                }

                var NewScope = new NamespaceScope(Container, new CodeString(), Namespace);
                Container.Children.Add(NewScope);
                Namespace.AddScope(NewScope);

                ReadIdList(NewScope, Namespace);
            }
            else
            {
                throw new InvalidAssemblyException("Invalid identifier type");
            }

            if (Ret != null)
            {
                if (HasSpecialName)
                {
                    Ret.AssemblyName = AssemblyName;
                }

                Ret.Access       = Access;
                Ret.Flags        = Flags;
                Ret.DescPosition = IdPos;
                CurrentAssembly.Ids.Add(IdPos, Ret);
            }

            return(Ret);
        }
Example #2
0
        public bool Declare(bool AddUsingLate = false)
        {
            var State = Scope.State;
            var Rec   = State.Language.NamespaceDeclRecognizer;

            for (var i = 0; i < Names.Count; i++)
            {
                if (!Names[i].IsValidIdentifierName)
                {
                    State.Messages.Add(MessageId.NotValidName, Names[i]);
                    return(false);
                }
            }

            if (Type == NamespaceDeclType.Declare)
            {
                var Options = new GetIdOptions();
                Options.Func = x => x is Namespace;

                Namespace = Scope.Namespace;
                NewScope  = Scope;
                for (var i = 0; i < Names.Count; i++)
                {
                    Namespace = Identifiers.GetMember(State, Namespace, Names[i], Options) as Namespace;

                    if (Namespace == null)
                    {
                        Namespace = new Namespace(NewScope, Names[i]);
                        if (!NewScope.DeclareIdentifier(Namespace))
                        {
                            return(false);
                        }
                    }

                    var OldScope = NewScope;
                    var NewInner = i == Names.Count - 1 ? Inner : new CodeString();

                    NewScope = new NamespaceScope(OldScope, NewInner, Namespace);
                    OldScope.Children.Add(NewScope);
                    Namespace.AddScope(NewScope);
                }
            }
            else
            {
                var Options = GetIdOptions.Default;
                Options.Func = x => x is Namespace;

                Namespace = Identifiers.Recognize(Scope, Names[0], Options) as Namespace;
                if (Namespace == null)
                {
                    return(false);
                }

                for (var i = 1; i < Names.Count; i++)
                {
                    Namespace = Identifiers.GetMember(State, Namespace, Names[i]) as Namespace;
                    if (Namespace == null)
                    {
                        return(false);
                    }
                }

                if (!AddUsingLate)
                {
                    Scope.UsedNamespaces.Add(Namespace);
                }
            }

            return(true);
        }