예제 #1
0
        static Command CreateJump(IdContainer Container, string Label, CodeString Code)
        {
            var Plugin = Container.GetPlugin();

            if (!Plugin.Begin())
            {
                return(null);
            }

            var Node = Plugin.NewNode(new LabelExpressionNode(Code, Label));

            if (Node == null || Plugin.End(ref Node) == PluginResult.Failed)
            {
                return(null);
            }

            return(CreateJump(Container, Node, Code));
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }