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); }