/// <summary> /// Parses the fluent function call. /// </summary> /// <returns></returns> public override Expr Parse() { // 1. Is it a function call? var fnameToken = _tokenIt.NextToken; _tokenIt.Advance(_result.TokenCount); var remainderOfFuncName = string.Empty; var parts = new List <Expr>(); TokenData firstPart = null; // NOTES: // Given: function "Find user by" * // And: called via Find use by name role // wildcard part 1: name // wildcard part 2: role // full wildcard: "name role" var partsToken = _tokenIt.NextToken; // 1. Capture all the remaining parts of the wild card. while (_tokenIt.NextToken.Token.Kind == TokenKind.Ident) { var part = _tokenIt.NextToken.Token.Text; // a. Store the token of the first wildcard part if (firstPart == null) { firstPart = _tokenIt.NextToken; } // b. Build up the full name from all wildcards remainderOfFuncName += " " + part; // c. Create a constant expr from the wildcard // as it will be part of an array of strings passed to function var partExp = Exprs.Const(new LString(part), _tokenIt.NextToken); parts.Add(partExp); // d. Move to the next token for another possible wildcard. _tokenIt.Advance(); // e. Check for end of statement. if (_tokenIt.IsEndOfStmtOrBlock()) { break; } } var exp = new FunctionCallExpr(); exp.ParamListExpressions = new List <Expr>(); exp.ParamList = new List <object>(); remainderOfFuncName = remainderOfFuncName.Trim(); var fullWildCard = Exprs.Const(new LString(string.Empty), fnameToken) as ConstantExpr; // 2. Create a constant expr representing the full wildcard if (!string.IsNullOrEmpty(remainderOfFuncName)) { fullWildCard.Value = remainderOfFuncName; _parser.SetupContext(fullWildCard, firstPart); } var token = _tokenIt.NextToken.Token; // CASE 1: Parse parameters with parenthesis "(" if (token == Tokens.LeftParenthesis) { _parser.ParseParameters(exp, true, false, false); } // CASE 2: Parse parameters with ":" until newline. else if (token == Tokens.Colon) { _tokenIt.Advance(); _parser.ParseParameters(exp, false, false, true); } exp.NameExp = Exprs.Ident(_result.Name, fnameToken); // Have to restructure the arguments. // 1. const expr , fullwildcard, "name role" // 2. list<constexpr>, wildcard parts, ["name", "role"] // 3. list<expr>, args, "kishore", "admin" var args = new List <Expr>(); args.Add(fullWildCard); args.Add(Exprs.Array(parts, partsToken)); args.Add(Exprs.Array(exp.ParamListExpressions, fnameToken)); // Finally reset the parameters expr on the function call. exp.ParamListExpressions = args; return(exp); }
/// <summary> /// run step 123. /// </summary> /// <returns></returns> public override Expr Parse() { /* * [ * name | pages | author * 'c#' | 150 | 'microsoft' * 'ruby' | 140 | 'matz' * 'fluent' | 100 | 'codehelix' * ]; * [ * name | pages | author * 'c#' , 150 , 'microsoft' * 'ruby' , 140 , 'matz' * 'fluent' , 100 , 'codehelix' * ]; */ var startToken = _tokenIt.NextToken; // 1. Move past "[" _tokenIt.Advance(1, true); var columnNames = new List <string>(); var token = _tokenIt.NextToken.Token; while (!Token.IsNewLine(token) && !_tokenIt.IsEnded) { // Expect column name. var columnName = _tokenIt.ExpectId(false); columnNames.Add(columnName); _tokenIt.Advance(1, false); // "|" pipe to separate column names. if (_tokenIt.NextToken.Token == Tokens.Pipe) { _tokenIt.Advance(1, false); } else if (_tokenIt.NextToken.Token != Tokens.NewLine) { throw _tokenIt.BuildSyntaxExpectedException("| or new line"); } token = _tokenIt.NextToken.Token; } if (_tokenIt.IsEnded) { throw _tokenIt.BuildEndOfScriptException(); } // Hit new line? _tokenIt.Advance(); var records = new List <List <Tuple <string, Expr> > >(); var record = new List <Tuple <string, Expr> >(); var colIndex = 0; Token firstColumnDataDelimiter = null; // Build up all the records. while (token != Tokens.RightBracket && !_tokenIt.IsEnded) { // 1. Get the column value: 'C#' var exp = _parser.ParseExpression(_endTokens, true, passNewLine: false); var colName = columnNames[colIndex]; record.Add(new Tuple <string, Expr>(colName, exp)); // 2. Is the next one a | or new line ? //_tokenIt.Advance(1, false); token = _tokenIt.NextToken.Token; // 3. If "|" or "," it separates expression/column values. if (firstColumnDataDelimiter == null && token == Tokens.Pipe || token == Tokens.Comma) { firstColumnDataDelimiter = token; } if (token == firstColumnDataDelimiter) { _tokenIt.Advance(1, false); colIndex++; } // 4. If Newline, end of current record. else if (token == Tokens.NewLine) { records.Add(record); record = new List <Tuple <string, Expr> >(); _tokenIt.Advance(); colIndex = 0; } else if (token == Tokens.RightBracket) { records.Add(record); record = new List <Tuple <string, Expr> >(); colIndex = 0; } else { throw _tokenIt.BuildSyntaxExpectedException("| or new line"); } token = _tokenIt.NextToken.Token; } _tokenIt.Expect(Tokens.RightBracket); // Now finally build array of maps. var array = new List <Expr>(); foreach (var rec in records) { var item = Exprs.Map(rec, startToken); array.Add(item); } var arrayExp = Exprs.Array(array, startToken); return(arrayExp); }