예제 #1
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            var State = Container.State;

            if (RecognizerHelper.Find(this, State, Code.String).Position != -1)
            {
                var DeclListFlags = VarDeclarationListFlags.EnableUnnamed;
                if (Options.EnableMessages)
                {
                    DeclListFlags |= VarDeclarationListFlags.EnableMessages;
                }
                var DeclList = VarDeclarationList.Create(Container, Code, null, DeclListFlags);
                if (DeclList == null)
                {
                    return(SimpleRecResult.Failed);
                }

                Ret = DeclList.ToTupleType(Container, Options.EnableMessages);
                if (Ret == null)
                {
                    return(SimpleRecResult.Failed);
                }

                if (Options.Func == null || Options.Func(Ret))
                {
                    return(SimpleRecResult.Succeeded);
                }
            }

            return(SimpleRecResult.Unknown);
        }
예제 #2
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            var Result = Code.StartsWith(Operators, Skip, IdCharCheck: new IdCharCheck(true));

            if (Result.Index != -1)
            {
                var State  = Container.State;
                var ChildC = Code.TrimmedSubstring(State, Result.String.Length, Options.EnableMessages);
                if (!ChildC.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                var TOptions = Options;
                TOptions.Func = x => x.RealId is Type;

                var Child = Identifiers.Recognize(Container, ChildC, TOptions);
                if (Child == null)
                {
                    return(SimpleRecResult.Failed);
                }

                var RChild = Child.RealId as Type;
                if (RChild == null || (RChild.TypeFlags & TypeFlags.CanBeReference) == 0)
                {
                    if (Options.EnableMessages)
                    {
                        State.Messages.Add(MessageId.UnknownId, Code);
                    }

                    return(SimpleRecResult.Failed);
                }

                ReferenceMode Mode;
                if (Result.Index == 0)
                {
                    Mode = ReferenceMode.Unsafe;
                }
                else if (Result.Index == 1)
                {
                    Mode = ReferenceMode.IdMustBeAssigned;
                }
                else if (Result.Index == 2)
                {
                    Mode = ReferenceMode.IdGetsAssigned;
                }
                else
                {
                    throw new ApplicationException();
                }

                Ret = new ReferenceType(Container, Child, Mode);
                if (Options.Func == null || Options.Func(Ret))
                {
                    return(SimpleRecResult.Succeeded);
                }
            }

            return(SimpleRecResult.Unknown);
        }
예제 #3
0
        public static ExpressionNode Throw(PluginRoot Plugin, Identifier ContainerId, CodeString ExceptionType,
                                           CodeString Code, BeginEndMode BEMode = BeginEndMode.Both)
        {
            var Options = new GetIdOptions()
            {
                EnableMessages = true, Func = x => x.RealId is ClassType
            };
            var IdExceptionType = Identifiers.GetFromMembers(ContainerId, ExceptionType, Options);

            if (IdExceptionType == null)
            {
                return(null);
            }

            return(Throw(Plugin, IdExceptionType, Code, BEMode));
        }
예제 #4
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            var State  = Container.State;
            var Result = RecognizerHelper.Find(this, State, Code.String);

            if (Result.Position != -1)
            {
                var Left  = Code.TrimmedSubstring(State, 0, Result.Position, Options.EnableMessages);
                var Right = Code.TrimmedSubstring(State, Result.Position + 1, Options.EnableMessages);
                if (!Left.IsValid || !Right.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                Ret = Identifiers.GetMember(Container, Left, Right, Options);
                return(Ret == null ? SimpleRecResult.Failed : SimpleRecResult.Succeeded);
            }

            return(SimpleRecResult.Unknown);
        }
예제 #5
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            if (!Check(Container.State, Code))
            {
                return(SimpleRecResult.Failed);
            }

            var NewCode = Code.TrimBrackets(Container.State);

            if (!NewCode.IsValid)
            {
                return(SimpleRecResult.Failed);
            }
            if (NewCode.Length == Code.Length)
            {
                return(SimpleRecResult.Unknown);
            }

            Ret = Identifiers.Recognize(Container, NewCode, Options);
            return(Ret == null ? SimpleRecResult.Failed : SimpleRecResult.Succeeded);
        }
예제 #6
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            if (Code.IsValidIdentifierName)
            {
                var List = Container.GetIdentifier(Code.ToString(), Options.Mode, Options.Func);
                Ret = Identifiers.SelectIdentifier(Container.State, List, Code, Options);
                if (Ret == null)
                {
                    return(SimpleRecResult.Failed);
                }

                if (!Identifiers.VerifyAccess(Container, Ret, Code, Options.EnableMessages))
                {
                    return(SimpleRecResult.Failed);
                }

                return(SimpleRecResult.Succeeded);
            }

            return(SimpleRecResult.Unknown);
        }
예제 #7
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            if (Code.Length > 0 && Code[Code.Length - 1] == '*')
            {
                var State  = Container.State;
                var ChildC = Code.TrimmedSubstring(State, 0, Code.Length - 1, Options.EnableMessages);
                if (!ChildC.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                var TOptions = Options;
                TOptions.Func = x => x.RealId is Type;

                var Child = Identifiers.Recognize(Container, ChildC, TOptions);
                if (Child == null)
                {
                    return(SimpleRecResult.Failed);
                }

                var RChild = Child.RealId as Type;
                if (RChild == null || (RChild.TypeFlags & TypeFlags.CanBePointer) == 0)
                {
                    if (Options.EnableMessages)
                    {
                        State.Messages.Add(MessageId.UnknownId, Code);
                    }

                    return(SimpleRecResult.Failed);
                }

                Ret = new PointerType(Container, Child);
                if (Options.Func == null || Options.Func(Ret))
                {
                    return(SimpleRecResult.Succeeded);
                }
            }

            return(SimpleRecResult.Unknown);
        }
예제 #8
0
        public Function GetEntryFunction()
        {
            if (State.Entry == null)
            {
                throw new ApplicationException();
            }

            var Options = new GetIdOptions();

            Options.Func = x => x is Function;

            var Name = new CodeString(State.Entry);
            var Fun  = Identifiers.GetFromMembers(GlobalNamespace, Name, Options);

            if (Fun == null)
            {
                State.Messages.Add(MessageId.EntryNotFound, new CodeString(), State.Entry);
                return(null);
            }

            return(Fun as Function);
        }
예제 #9
0
        public SimpleRecResult Declare()
        {
            var Options = new GetIdOptions(GetIdMode.Everywhere, false);
            var Id      = Container.RecognizeIdentifier(OldName, Options);

            if (Id == null)
            {
                return(SimpleRecResult.Unknown);
            }

            var Alias = new IdentifierAlias(Container, NewName, Id);

            if (Mods != null && !Modifiers.Apply(Mods, Alias))
            {
                return(SimpleRecResult.Failed);
            }

            if (!Container.DeclareIdentifier(Alias))
            {
                return(SimpleRecResult.Failed);
            }

            return(SimpleRecResult.Succeeded);
        }
예제 #10
0
 public Identifier RecognizeIdentifier(CodeString Code, GetIdOptions Options, IList <IIdRecognizer> Recognizers)
 {
     return(Identifiers.Recognize(this, Code, Options, Recognizers));
 }
예제 #11
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            var Position = Code.Length - 1;

            if (Position >= 0 && Code[Position] == ']')
            {
                var State = Container.State;
                var ZPos  = Code.GetBracketPos(State, true, Options.EnableMessages);
                if (ZPos == -1)
                {
                    return(SimpleRecResult.Failed);
                }

                var Left = Code.TrimmedSubstring(State, 0, ZPos, Options.EnableMessages);
                if (!Left.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                var TOptions = Options;
                TOptions.Func = x => x.RealId is Type;

                var TypeOfVals = Identifiers.Recognize(Container, Left, TOptions);
                if (TypeOfVals == null)
                {
                    return(SimpleRecResult.Failed);
                }

                var RTypeOfVals = TypeOfVals.RealId as Type;
                if (RTypeOfVals == null || (RTypeOfVals.TypeFlags & TypeFlags.CanBeArrayType) == 0)
                {
                    if (Options.EnableMessages)
                    {
                        State.Messages.Add(MessageId.UnknownId, Code);
                    }

                    return(SimpleRecResult.Failed);
                }

                var StrParams = Code.Substring(ZPos + 1, Position - ZPos - 1).Trim();
                if (StrParams.IsEqual("?"))
                {
                    Ret = new NonrefArrayType(Container, TypeOfVals, null);
                    if (Options.Func == null || Options.Func(Ret))
                    {
                        return(SimpleRecResult.Succeeded);
                    }
                }
                else if (StrParams.IsEqual("*"))
                {
                    if ((RTypeOfVals.TypeFlags & TypeFlags.CanBePointer) == 0)
                    {
                        if (Options.EnableMessages)
                        {
                            State.Messages.Add(MessageId.UnknownId, Code);
                        }

                        return(SimpleRecResult.Failed);
                    }

                    Ret = new PointerAndLength(Container, TypeOfVals);
                    if (Options.Func == null || Options.Func(Ret))
                    {
                        return(SimpleRecResult.Succeeded);
                    }
                }

                var SplParams = RecognizerHelper.SplitToParameters(State, StrParams,
                                                                   ',', Options.EnableMessages, true);

                if (SplParams == null)
                {
                    return(SimpleRecResult.Failed);
                }

                if (SplParams.Length == 0 || SplParams[0].Length == 0)
                {
                    for (var i = 0; i < SplParams.Length; i++)
                    {
                        if (SplParams[i].Length > 0)
                        {
                            State.Messages.Add(MessageId.NotExpected, SplParams[i]);
                            return(SimpleRecResult.Failed);
                        }
                    }

                    var IndexCount = SplParams.Length == 0 ? 1 : SplParams.Length;
                    Ret = new RefArrayType(Container, TypeOfVals, IndexCount);
                    if (Options.Func == null || Options.Func(Ret))
                    {
                        return(SimpleRecResult.Succeeded);
                    }
                }
                else
                {
                    var Plugin = Container.GetPlugin();
                    Plugin.GetPlugin <EvaluatorPlugin>().MustBeConst = true;

                    var Lengths = new int[SplParams.Length];
                    for (var i = 0; i < SplParams.Length; i++)
                    {
                        var Node    = Expressions.CreateExpression(SplParams[i], Plugin);
                        var ConstCh = Node as ConstExpressionNode;
                        if (ConstCh == null)
                        {
                            return(SimpleRecResult.Failed);
                        }

                        if (!(ConstCh.Type is NonFloatType))
                        {
                            if (Options.EnableMessages)
                            {
                                State.Messages.Add(MessageId.MustBeInteger, StrParams);
                            }

                            return(SimpleRecResult.Failed);
                        }

                        if (!VerifyArrayLength(State, ConstCh, StrParams, Options.EnableMessages))
                        {
                            return(SimpleRecResult.Failed);
                        }

                        Lengths[i] = (int)ConstCh.Integer;
                    }

                    Ret = new NonrefArrayType(Container, TypeOfVals, Lengths);
                    if (Options.Func == null || Options.Func(Ret))
                    {
                        return(SimpleRecResult.Succeeded);
                    }
                }
            }

            return(SimpleRecResult.Unknown);
        }
예제 #12
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Ret)
        {
            if (Code.StartsWith(Operators, Skip, IdCharCheck: new IdCharCheck(true)).Index == 0)
            {
                var State = Container.State;
                if (Code[Code.Length - 1] != ')')
                {
                    if (Options.EnableMessages)
                    {
                        State.Messages.Add(MessageId.NotExpected, Code);
                    }

                    return(SimpleRecResult.Failed);
                }

                var BracketPos = Code.GetBracketPos(State, true, Options.EnableMessages);
                if (BracketPos == -1)
                {
                    return(SimpleRecResult.Failed);
                }

                var Left = Code.TrimmedSubstring(State, 3, BracketPos - 3, Options.EnableMessages);
                if (!Left.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                CallingConvention CallConv;
                if (!Modifiers.GetCallConv(Container, ref Left, out CallConv))
                {
                    return(SimpleRecResult.Failed);
                }

                if (CallConv == CallingConvention.Unknown)
                {
                    CallConv = Container.DefaultCallConv;
                }

                var TOptions = Options;
                TOptions.Func = x => x.RealId is Type;

                var RetType   = Identifiers.Recognize(Container, Left, TOptions);
                var StrParams = Code.Substring(BracketPos + 1, Code.Length - BracketPos - 2).Trim();

                var Flags = VarDeclarationListFlags.EnableUnnamed | VarDeclarationListFlags.EnableInitValue;
                if (Options.EnableMessages)
                {
                    Flags |= VarDeclarationListFlags.EnableMessages;
                }
                var DeclList = VarDeclarationList.Create(Container, StrParams, null, Flags);
                if (DeclList == null || RetType == null)
                {
                    return(SimpleRecResult.Failed);
                }

                if (!(RetType.RealId is Type))
                {
                    State.Messages.Add(MessageId.UnknownType, Left);
                    return(SimpleRecResult.Failed);
                }

                var Params = DeclList.ToFuncParams(Container.GetPlugin());
                if (Params == null || Params.Contains(null))
                {
                    return(SimpleRecResult.Failed);
                }

                Ret = new TypeOfFunction(Container, CallConv, RetType, Params);
                if (Options.Func == null || Options.Func(Ret))
                {
                    return(SimpleRecResult.Succeeded);
                }
            }

            return(SimpleRecResult.Unknown);
        }
예제 #13
0
        public SimpleRecResult Recognize(IdContainer Container, CodeString Code, GetIdOptions Options, ref Identifier Out)
        {
            var State  = Container.State;
            var Result = RecognizerHelper.Find(this, State, Code.String);

            if (Result.Position != -1)
            {
                var OldCode = Code;
                var Mods    = Modifiers.Recognize(Container, ref Code);
                if (Mods == null)
                {
                    return(SimpleRecResult.Failed);
                }

                Result.Position -= Code.Index - OldCode.Index;

                var Left = Code.TrimmedSubstring(State, 0, Result.Position, Options.EnableMessages);
                if (!Left.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                var Right = Code.TrimmedSubstring(State, Result.Position + Result.String.Length, Options.EnableMessages);
                if (!Right.IsValid)
                {
                    return(SimpleRecResult.Failed);
                }

                var Flags = VarDeclarationListFlags.EnableUnnamed | VarDeclarationListFlags.EnableInitValue
                            | VarDeclarationListFlags.EnableVoidOnly;

                if (Options.EnableMessages)
                {
                    Flags |= VarDeclarationListFlags.EnableMessages;
                }
                var ParamDeclList = VarDeclarationList.Create(Container, Left, null, Flags);
                if (ParamDeclList == null)
                {
                    return(SimpleRecResult.Failed);
                }

                if (ParamDeclList.Count == 1 && ParamDeclList[0].Type.RealId is VoidType)
                {
                    ParamDeclList.RemoveAt(0);
                }

                var Params = ParamDeclList.ToFuncParams(Container.GetPlugin());
                if (Params == null || Params.Contains(null))
                {
                    return(SimpleRecResult.Failed);
                }

                Flags &= ~VarDeclarationListFlags.EnableInitValue;
                var RetDeclList = VarDeclarationList.Create(Container, Right, null, Flags);
                if (RetDeclList == null)
                {
                    return(SimpleRecResult.Failed);
                }

                Identifier RetType;
                if (RetDeclList.Count == 1 && !RetDeclList[0].Name.IsValid)
                {
                    RetType = RetDeclList[0].Type;
                }
                else
                {
                    RetType = RetDeclList.ToTupleType(Container, Options.EnableMessages);
                    if (RetType == null)
                    {
                        return(SimpleRecResult.Failed);
                    }
                }

                var CallConv  = Container.DefaultCallConv;
                var Succeeded = true;
                var Static    = false;

                Mods.ForEach(x =>
                {
                    if (x is CallingConventionModifier)
                    {
                        var CCM  = x as CallingConventionModifier;
                        CallConv = CCM.CallingConvention;
                    }
                    else if (x is FlagModifier)
                    {
                        var FM = x as FlagModifier;
                        if ((FM.Flags & IdentifierFlags.Static) != 0)
                        {
                            Static = true;
                        }

                        if ((FM.Flags & ~IdentifierFlags.Static) != 0)
                        {
                            if (Options.EnableMessages)
                            {
                                State.Messages.Add(MessageId.ModifierCantBeUsed, x.Code);
                            }

                            Succeeded = false;
                        }
                    }
                    else
                    {
                        if (Options.EnableMessages)
                        {
                            State.Messages.Add(MessageId.ModifierCantBeUsed, x.Code);
                        }

                        Succeeded = false;
                    }
                });

                if (!Succeeded)
                {
                    return(SimpleRecResult.Failed);
                }

                Identifier FuncType = new TypeOfFunction(Container, CallConv, RetType, Params);
                Out = Static ? FuncType : new NonstaticFunctionType(Container, FuncType);

                if (Options.Func == null || Options.Func(Out))
                {
                    return(SimpleRecResult.Succeeded);
                }
                return(SimpleRecResult.Succeeded);
            }

            return(SimpleRecResult.Unknown);
        }
예제 #14
0
        public bool SearchCommonIdentifiers()
        {
            if (CommonIds.EmptyBase == null)
            {
                CommonIds.EmptyBase = new StructureBase[0];
            }

            CommonIds.ValueTypeBase = CommonIds.EmptyBase;
            CommonIds.EnumBase      = CommonIds.EmptyBase;
            CommonIds.TupleBase     = CommonIds.EmptyBase;
            CommonIds.ArrayBase     = CommonIds.EmptyBase;

            var System = Identifiers.GetByFullNameFast <Namespace>(this, "System", false);

            if (System == null)
            {
                return(false);
            }

            var StructOptions = new GetIdOptions()
            {
                EnableMessages = false, Func = x => x is StructType
            };
            var ClassOptions = new GetIdOptions()
            {
                EnableMessages = false, Func = x => x is ClassType
            };

            CommonIds.SByte.UnderlyingType = Identifiers.GetMember(State, System, "SByte", StructOptions) as StructuredType;
            CommonIds.Int16.UnderlyingType = Identifiers.GetMember(State, System, "Int16", StructOptions) as StructuredType;
            CommonIds.Int32.UnderlyingType = Identifiers.GetMember(State, System, "Int32", StructOptions) as StructuredType;
            CommonIds.Int64.UnderlyingType = Identifiers.GetMember(State, System, "Int64", StructOptions) as StructuredType;

            CommonIds.Byte.UnderlyingType   = Identifiers.GetMember(State, System, "Byte", StructOptions) as StructuredType;
            CommonIds.UInt16.UnderlyingType = Identifiers.GetMember(State, System, "UInt16", StructOptions) as StructuredType;
            CommonIds.UInt32.UnderlyingType = Identifiers.GetMember(State, System, "UInt32", StructOptions) as StructuredType;
            CommonIds.UInt64.UnderlyingType = Identifiers.GetMember(State, System, "UInt64", StructOptions) as StructuredType;

            CommonIds.Single.UnderlyingType = Identifiers.GetMember(State, System, "Single", StructOptions) as StructuredType;
            CommonIds.Double.UnderlyingType = Identifiers.GetMember(State, System, "Double", StructOptions) as StructuredType;

            CommonIds.Boolean.UnderlyingType = Identifiers.GetMember(State, System, "Boolean", StructOptions) as StructuredType;
            CommonIds.Object.UnderlyingType  = Identifiers.GetMember(State, System, "Object", ClassOptions) as StructuredType;
            CommonIds.String.UnderlyingType  = Identifiers.GetMember(State, System, "String", ClassOptions) as StructuredType;
            CommonIds.Char.UnderlyingType    = Identifiers.GetMember(State, System, "Char", StructOptions) as StructuredType;
            CommonIds.Void.UnderlyingType    = Identifiers.GetMember(State, System, "Void", StructOptions) as StructuredType;

            CommonIds.ValueType = Identifiers.GetMember(State, System, "ValueType", ClassOptions);
            CommonIds.Enum      = Identifiers.GetMember(State, System, "Enum", ClassOptions);
            CommonIds.Tuple     = Identifiers.GetMember(State, System, "Tuple", ClassOptions);
            CommonIds.Array     = Identifiers.GetMember(State, System, "Array", ClassOptions);

            if (CommonIds.ValueType != null)
            {
                CommonIds.ValueTypeBase = new StructureBase[1]
                {
                    new StructureBase(CommonIds.ValueType, StructureBaseFlags.Unreal),
                };
            }

            if (CommonIds.Enum != null)
            {
                CommonIds.EnumBase = new StructureBase[1]
                {
                    new StructureBase(CommonIds.Enum, StructureBaseFlags.Unreal),
                };
            }

            if (CommonIds.Tuple != null)
            {
                CommonIds.TupleBase = new StructureBase[1]
                {
                    new StructureBase(CommonIds.Tuple, StructureBaseFlags.Unreal),
                };
            }

            if (CommonIds.Array != null)
            {
                CommonIds.ArrayBase = new StructureBase[1]
                {
                    new StructureBase(CommonIds.Array, StructureBaseFlags.Unreal),
                };
            }

            if (CommonIds.ValueType == null || CommonIds.Enum == null ||
                CommonIds.Tuple == null || CommonIds.Array == null)
            {
                return(false);
            }

            return(CommonIds.BuiltinTypes.TrueForAll(x =>
            {
                if (x.UnderlyingType == null)
                {
                    return false;
                }

                x.UnderlyingType.RealId = x;
                return true;
            }));
        }
예제 #15
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);
        }
예제 #16
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);
        }