public static TemplateExpression Parse(ExpressionWalker ew) { ew.IsCurrentOrThrow(ExpressionToken.Template); ew.NextOrThrow(); // ReSharper disable once UseObjectOrCollectionInitializer var ret = new TemplateExpression(); ew.IsCurrentOrThrow(ExpressionToken.StringLiteral); ret._matchPath = new RegexResult[] { ew.Current.Match.AsResult() }; ret.Path = ew.Current.Match.Value.StartsWith("\"") ? ew.Current.Match.Value.Substring(1, ew.Current.Match.Length - 2) : ew.Current.Match.Value; ret._matchForEvery = ew.Next(ExpressionToken.ForEvery, true).Match.AsResult(); ew.NextOrThrow(); ret.Arguments = ArgumentsExpression.Parse(ew, token => token.Token == ExpressionToken.NewLine || token.Token == ExpressionToken.Mod, false, typeof(ForeachExpression)); //we have to fall back because ArgumentsExpression.Parse swallows mod. ew.IsBack(ExpressionToken.Mod, true); if (ew.IsCurrent(ExpressionToken.Mod)) { ew.Back(1); } return(ret); }
public static Expression Parse(ExpressionWalker ew, Expression left = null) { var fc = new CallExpression(); fc.FunctionName = left ?? IdentityExpression.Parse(ew); fc.Arguments = ArgumentsExpression.Parse(ew, ExpressionToken.LeftParen, ExpressionToken.RightParen, true); return(InteractableExpression.TryExpand(fc, ew)); }
public static ArgumentsExpression Parse(ExpressionWalker ew, ExpressionToken left, ExpressionToken right, bool argsOptional, Type caller = null) { var args = new ArgumentsExpression(); ew.IsCurrentOrThrow(left); ew.NextOrThrow(); var exprs = new List <Expression>(); while (ew.Current.Token != right && ew.HasNext) { if (ew.Current.Token == ExpressionToken.Comma) { if (ew.HasBack && ew.PeakBack.Token == ExpressionToken.Comma) { exprs.Add(NullIdentity.Instance); } ew.NextOrThrow(); continue; } var expression = ParseExpression(ew, caller); if (ew.IsCurrent(ExpressionToken.Colon)) { //handle keyvalue item exprs.Add(KeyValueExpression.Parse(ew, expression, caller)); } else { exprs.Add(expression); } } if (exprs.Count == 0 && !argsOptional) { throw new UnexpectedTokenException($"Was expecting an expression between {left} and {right}"); } ew.Next(); args.Arguments = exprs.ToArray(); return(args); }
public static ArgumentsExpression Parse(ExpressionWalker ew, Func <TokenMatch, bool> parseTill, bool argsOptional, Type caller = null) { var args = new ArgumentsExpression(); var exprs = new List <Expression>(); while (!parseTill(ew.Current) && ew.HasNext) { if (ew.Current.Token == ExpressionToken.Comma) { if (ew.HasBack && ew.PeakBack.Token == ExpressionToken.Comma) { exprs.Add(NullIdentity.Instance); } ew.NextOrThrow(); continue; } var expression = ParseExpression(ew, caller); if (ew.IsCurrent(ExpressionToken.Colon)) { //handle keyvalue item exprs.Add(KeyValueExpression.Parse(ew, expression)); } else { exprs.Add(expression); } } if (exprs.Count == 0 && !argsOptional) { throw new UnexpectedTokenException($"Was expecting arguments but found none while argsOptional is false"); } ew.Next(); args.Arguments = exprs.ToArray(); return(args); }
public static ParserAction Parse(ExpressionWalker ew, string code, LineBuilder output) { // multiline: // %foreach expr% // code #1 // % // singleline: // %foreach expr // code #1 ew.IsCurrentOrThrow(ExpressionToken.Foreach); ew.NextOrThrow(); //parse the arguments for the foreach var args = ArgumentsExpression.Parse(ew, token => token.Token == ExpressionToken.NewLine || token.Token == ExpressionToken.Mod, false, typeof(ForeachExpression)); //ew.Back(); //agrumentsExpression skips the closer token and we need it to identify if this is a singleline or multiline if (output == null) { output = new LineBuilder(code); } string content; var relatedLines = new List <Line>(); relatedLines.AddRange(output.GetLinesRelated(args.Matches())); if (ew.PeakBack.Token == ExpressionToken.Mod) { //the content is % to % block var leftBorder = ew.Current.Match; var nextMod = ForeachExpression.FindCloser(leftBorder.Index, code); //handle implicit end block (when % is not existing) if (nextMod == -1) { nextMod = code.Length - 1; } ew.SkipForwardWhile(token => token.Match.Index < nextMod); ew.Next(); //skip % itself var l1 = output.GetLineAt(leftBorder.Index) ?? output.Lines.First(); relatedLines.AddRange(new Range(l1.LineNumber, output.GetLineAt(nextMod).LineNumber).EnumerateIndexes().Select(output.GetLineByLineNumber)); content = null; } else { //the content is only next line var leftMod = ew.Current.Match; var nextMod = code.IndexOf('\n', leftMod.Index); relatedLines.Add(output.GetLineByLineNumber(relatedLines.Last().LineNumber + 1)); //next line. content = code.Substring(leftMod.Index, nextMod == -1 ? (code.Length - leftMod.Index) : nextMod - leftMod.Index); } relatedLines = relatedLines.Distinct().OrderBy(l => l.StartIndex).ToList(); if (relatedLines.Count(l => l.Content.Contains("%foreach")) <= relatedLines.Count(l => l.CleanContent() == "%") && relatedLines.Last().CleanContent() == "%") { relatedLines[relatedLines.Count - 1].MarkedForDeletion = true; relatedLines.RemoveAt(relatedLines.Count - 1); } //make sure to clean out % at the end if (content == null) { content = relatedLines.Select(l => l.Content).StringJoin(); } //all lines of the foreach are destined to deletion foreach (var line in relatedLines) { line.MarkedForDeletion = true; } return(new ParserAction(ParserToken.ForeachLoop, relatedLines, new ForeachExpression() { Content = content, Arguments = args })); }
public CallExpression(Expression functionName, ArgumentsExpression args) { FunctionName = functionName; Arguments = args; }
public static Expression Parse(ExpressionWalker ew, Expression left = null) { var ret = new IndexerCallExpression(left ?? IdentityExpression.Parse(ew), ArgumentsExpression.Parse(ew, ExpressionToken.LeftBracet, ExpressionToken.RightBracet, false)); return(InteractableExpression.TryExpand(ret, ew)); }
public IndexerCallExpression(Expression left, ArgumentsExpression arguments) { Left = left; Arguments = arguments; }
public static ArrayExpression Parse(ExpressionWalker ew) { return(new ArrayExpression(ArgumentsExpression.Parse(ew, ExpressionToken.LeftBracet, ExpressionToken.RightBracet, true).Arguments)); }
public CallExpression(string functionName, params Expression[] args) { FunctionName = IdentityExpression.WrapVariable(functionName); Arguments = new ArgumentsExpression(args); }