Пример #1
0
        private static IExpression TryMatchExpressionOnFile(ParseContext ctx, SkriptTypesManager skriptTypesManager,
                                                            ParseContext clone, int currentPos, SkriptType skriptType)
        {
            IExpression result = null;

            //If we're dealing with a file, try matching event values too
            if (ctx is FileParseContext fileParseContext)
            {
                var currentNode = fileParseContext.File.Nodes[fileParseContext.CurrentLine];

                if (currentNode?.RootParentSyntax?.Element is SkriptEvent rootEvent)
                {
                    var typesAndExpressions = skriptTypesManager.GetEventExpressionsForEvent(rootEvent);

                    var exprs = typesAndExpressions;

                    if (exprs != null)
                    {
                        foreach (var(_, expressions) in exprs)
                        {
                            if (expressions != null)
                            {
                                foreach (var expression in expressions)
                                {
                                    clone.CurrentPosition = currentPos;
                                    clone.StartRangeMeasure("Event-Value Expression");
                                    clone.Matches.Clear();

                                    clone.VisitExpression(skriptType, expression);

                                    for (var index = 0; index < expression.PatternNodes.Length; index++)
                                    {
                                        var pattern     = expression.PatternNodes[index];
                                        var resultValue = pattern.Parse(clone);
                                        if (resultValue.IsSuccess)
                                        {
                                            var range = clone.EndRangeMeasure("Event-Value Expression");
                                            ctx.ReadUntilPosition(clone.CurrentPosition);

                                            result = new SkriptExpression(expression, range, ctx);
                                        }
                                    }

                                    clone.UndoRangeMeasure();
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
        public IExpression TryParseValue(ParseContext ctx)
        {
            ctx.StartRangeMeasure();
            if (ctx.PeekNext(1) == "(")
            {
                ctx.ReadNext(1); //Read the first bracket
                var nextBracket = ctx.FindNextBracket('(', ')');

                if (nextBracket != -1)
                {
                    var ctxClone = ctx.Clone(false);

                    var result = InnerPattern.Parse(ctxClone);
                    var value  = result.Matches.OfType <ExpressionParseMatch>().FirstOrDefault()?.Expression;
                    var oldPos = ctxClone.CurrentPosition;
                    if (result.IsSuccess)
                    {
                        ctx.ReadUntilPosition(oldPos);
                    }

                    if (value != null && ctx.ReadNext(1) == ")")
                    {
                        return(new ParenthesesExpression(value, this)
                        {
                            Range = ctx.EndRangeMeasure()
                        });
                    }

                    //Rollback in case of it not working
                    ctx.CurrentPosition = oldPos;
                }
            }

            ctx.UndoRangeMeasure();
            return(null);
        }
        public IExpression?TryParseValue(ParseContext ctx)
        {
            var typeInstance     = Type.CreateNewInstance();
            var ourContext       = ctx.Clone(false);
            var resultExpression = new MultiValueExpression();

            ctx.StartRangeMeasure();
            ctx.StartMatch();

            var count       = 0;
            var isValid     = true;
            var lastGoodPos = ourContext.CurrentPosition;

            while (isValid)
            {
                ourContext.Matches.Clear();
                ourContext.RemoveNarrowLimit();

                var result = NextValuePattern.Parse(ourContext);
                isValid = result.IsSuccess;

                if (!isValid)
                {
                    continue;
                }

                //Check if the parser consumed content and had a valid result. If not, just let go and give up.
                if (lastGoodPos == ourContext.CurrentPosition)
                {
                    break;
                }

                var expr = (ourContext.Matches.FirstOrDefault() as ExpressionParseMatch)?.Expression;
                if (expr != null)
                {
                    resultExpression.Values.Add(
                        new MultiValueExpression.ValueDescription(expr,
                                                                  ourContext.Matches.Where(c => c != null && !(c is ExpressionParseMatch))
                                                                  .Where(c => !c.RawContent.IsEmpty()).Skip(1).FirstOrDefault()));
                }

                count++;
            }

            if (count > 0)
            {
                //Remove last splitter
                var lastVal = resultExpression.Values?.Last();
                if (lastVal != null)
                {
                    if (lastVal.RawSplitter != null)
                    {
                        ourContext.CurrentPosition = (int)lastVal.RawSplitter.Range.Start.Character;
                        lastVal.RawSplitter        = null;
                    }

                    ctx.ReadUntilPosition(ourContext.CurrentPosition);
                }
            }

            if (count > 0)
            {
                resultExpression.Range   = ctx.EndRangeMeasure();
                resultExpression.Context = ctx;
                resultExpression.Type    = typeInstance;

                return(resultExpression);
            }

            ctx.UndoRangeMeasure();
            ctx.UndoMatch();
            return(null);
        }