public static ImportExpression Parse(ExpressionWalker ew) { ew.IsCurrentOrThrow(ExpressionToken.Import); ew.NextOrThrow(); // ReSharper disable once UseObjectOrCollectionInitializer var ret = new ImportExpression(); if (ew.IsCurrent(ExpressionToken.StringLiteral)) { ret._matchType = new RegexResult[] { ew.Current.Match.AsResult() }; ret.Type = ew.Current.Match.Value.Trim('\"'); } else { ret._matchType = ew.TakeForwardWhile(t => t.Token == ExpressionToken.Period || t.Token == ExpressionToken.Literal) .Select(t => t.Match.AsResult()).ToArray(); ret.Type = ret._matchType.Select(m => m.Value).StringJoin(); if (ew.IsCurrent(ExpressionToken.As)) { ret._matchAlias = ew.Next(ExpressionToken.Literal, true).Match.AsResult(); ret.As = ret._matchAlias.Value; } } ew.Next(); return(ret); }
public static GroupExpression Parse(ExpressionWalker ew, ExpressionToken left, ExpressionToken right) { ew.IsCurrentOrThrow(left); ew.NextOrThrow(); if (ew.Current.Token == right) { throw new UnexpectedTokenException($"Expected an expression, found end of group of type {right}"); } var expr = ParseExpression(ew, typeof(GroupExpression)); var grp = new GroupExpression() { _matchLeft = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(left).Emit.AsResult(), _matchRight = AttributeExtensions.GetAttribute <ExpressionTokenAttribute>(right).Emit.AsResult() }; if (ew.IsCurrent(ExpressionToken.Or)) { grp.InnerExpression = TernaryExpression.Parse(ew, expr); } else { grp.InnerExpression = expr; } ew.IsCurrentOrThrow(right); ew.Next(); return(grp); }
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 TryParse(ExpressionWalker ew, Type caller = null) { if (ew.IsCurrent(ExpressionToken.Hashtag) && ew.HasNext && ew.IsNext(ExpressionToken.NumberLiteral)) { return(Parse(ew, caller)); } return(null); }
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 IdentityExpression Parse(ExpressionWalker ew, Type caller = null, Expression left = null) { var ret = new IdentityExpression(); //types: //justname //justname.accessor //justname.accessor[5].second //justname.method().someval //justname.method().someval[3].thatsfar if (left == null) { ew.IsCurrentOrThrow(ExpressionToken.Literal); } if (ew.HasNext && ew.PeakNext.WhitespacesAfterMatch == 0 && ew.PeakNext.Token == ExpressionToken.Period && caller != typeof(IdentityExpression) || left != null) { var first = left ?? ParseExpression(ew, typeof(IdentityExpression)); ew.NextOrThrow(); //skip the predicted period. var next = ew.PeakNext; switch (next.Token) { //currently we are at Literal case ExpressionToken.Period: ret.Identity = new PropertyIdentity(first, Parse(ew)); return(ret); case ExpressionToken.LeftBracet: ret.Identity = new PropertyIdentity(first, IndexerCallExpression.Parse(ew)); return(ret); case ExpressionToken.LeftParen: ret.Identity = new PropertyIdentity(first, CallExpression.Parse(ew)); return(ret); default: if (left != null) { return(new IdentityExpression(new PropertyIdentity(left, Parse(ew, typeof(IdentityExpression), null)))); } if (first != null) { //just a plain single word! var right = new IdentityExpression(); if (ew.IsCurrent(ExpressionToken.Null)) { right.Identity = NullIdentity.Instance; } else { ew.IsCurrentOrThrow(ExpressionToken.Literal); right.Identity = StringIdentity.Create(ew.Current.Match); } ew.Next(); return(new IdentityExpression(new PropertyIdentity(first, right))); } goto _plain_identity; } } _plain_identity: //just a plain single word! if (ew.IsCurrent(ExpressionToken.Null)) { ret.Identity = NullIdentity.Instance; } else { ew.IsCurrentOrThrow(ExpressionToken.Literal); ret.Identity = StringIdentity.Create(ew.Current.Match); } ew.Next(); return(ret); }
public static Expression ParseExpression(ExpressionWalker ew, Type caller = null) { Expression ret = null; _retry: bool isOperatorCall = caller == typeof(OperatorExpression) || caller == typeof(RightOperatorExpression) || caller == typeof(ForeachExpression); var current = ew.Current.Token; if (current == ExpressionToken.Literal) { //cases like variable(.., variable[.., variable + .., variable if (ew.HasNext) { var peak = ew.PeakNextOrThrow().Token; if (peak == ExpressionToken.LeftParen) { ret = CallExpression.Parse(ew); } else if (peak == ExpressionToken.Period && caller != typeof(IdentityExpression) && caller != typeof(InteractableExpression)) { ret = IdentityExpression.Parse(ew); } else if (peak == ExpressionToken.LeftBracet) { ret = IndexerCallExpression.Parse(ew); } else if (peak == ExpressionToken.New) { ret = NewExpression.Parse(ew); } else if (RightOperatorExpression.IsNextAnRightUniOperation(ew, caller) && caller != typeof(RightOperatorExpression)) { ret = RightOperatorExpression.Parse(ew); } else if (OperatorExpression.IsNextAnOperation(ew) && !isOperatorCall) { ret = OperatorExpression.Parse(ew); } else { ret = IdentityExpression.Parse(ew, caller); } } else { ret = IdentityExpression.Parse(ew, caller); } } else if (LeftOperatorExpression.IsCurrentAnLeftUniOperation(ew)) { ret = LeftOperatorExpression.Parse(ew); } else if (current == ExpressionToken.NumberLiteral) { ret = NumberLiteral.Parse(ew); } else if (current == ExpressionToken.StringLiteral) { ret = StringLiteral.Parse(ew); } else if (current == ExpressionToken.LeftParen) { ret = GroupExpression.Parse(ew, ExpressionToken.LeftParen, ExpressionToken.RightParen); } else if (current == ExpressionToken.LeftBracet) { ret = ArrayExpression.Parse(ew); } else if (current == ExpressionToken.New) { ret = NewExpression.Parse(ew); } else if (current == ExpressionToken.Boolean) { ret = BooleanLiteral.Parse(ew); } else if (current == ExpressionToken.CharLiteral) { ret = CharLiteral.Parse(ew); } else if (current == ExpressionToken.Throw) { ret = ThrowExpression.Parse(ew); } else if (current == ExpressionToken.Hashtag && ew.HasNext && ew.PeakNext.Token == ExpressionToken.NumberLiteral) { ret = HashtagReferenceExpression.Parse(ew, caller); } else if (current == ExpressionToken.Null) { ret = NullIdentity.Parse(ew); } else if (current == ExpressionToken.NewLine) { ew.NextOrThrow(); goto _retry; } else { throw new UnexpectedTokenException($"Token was not expected to be a {ew.Current.Token}"); } _rereview: //here we parse chained math operations while (OperatorExpression.IsCurrentAnOperation(ew) && !isOperatorCall) { if (RightOperatorExpression.IsCurrentAnRightUniOperation(ew) && caller != typeof(OperatorExpression)) { ret = RightOperatorExpression.Parse(ew, ret); } else if (OperatorExpression.IsCurrentAnOperation(ew)) { ret = OperatorExpression.Parse(ew, ret); } } if (ew.IsCurrent(ExpressionToken.Or) && caller != typeof(TernaryExpression) && caller != typeof(OperatorExpression)) { ret = TernaryExpression.Parse(ew, ret); } if (ew.IsCurrent(ExpressionToken.LeftBracet)) { ret = IndexerCallExpression.Parse(ew, ret); goto _rereview; } if (ew.IsCurrent(ExpressionToken.LeftParen)) { ret = CallExpression.Parse(ew, ret); goto _rereview; } return(ret); }