diff --git a/doc/15-language-reference.md b/doc/15-language-reference.md index ea4112cccea..17fab5fd8ac 100644 --- a/doc/15-language-reference.md +++ b/doc/15-language-reference.md @@ -574,6 +574,16 @@ For lambdas which take exactly one argument the braces around the arguments can f = x => x * x +## Abbreviated Lambda Syntax + +Lambdas which take no arguments can also be written using the abbreviated lambda syntax. + +Example: + + f = {{ 3 }} + +This creates a new function which returns the value 3. + ## Variable Scopes When setting a variable Icinga checks the following scopes in this order whether the variable diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index 169fd7dba83..5885e3de19a 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -217,6 +217,8 @@ while return T_WHILE; in return T_IN; && return T_LOGICAL_AND; \|\| return T_LOGICAL_OR; +\{\{ return T_NULLARY_LAMBDA_BEGIN; +\}\} return T_NULLARY_LAMBDA_END; [a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; } @[a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = strdup(yytext + 1); return T_IDENTIFIER; } \<[^ \>]*\> { yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING_ANGLE; } diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index acef893fa94..83a2e551490 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -177,6 +177,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %token T_ELSE "else (T_ELSE)" %token T_WHILE "while (T_WHILE)" %token T_FOLLOWS "=> (T_FOLLOWS)" +%token T_NULLARY_LAMBDA_BEGIN "{{ (T_NULLARY_LAMBDA_BEGIN)" +%token T_NULLARY_LAMBDA_END "}} (T_NULLARY_LAMBDA_END)" %type identifier %type rterm_items @@ -871,6 +873,23 @@ rterm_no_side_effect: T_STRING $$ = new FunctionExpression(*$3, $5, aexpr, @$); delete $3; } + | T_NULLARY_LAMBDA_BEGIN statements T_NULLARY_LAMBDA_END + { + std::vector dlist; + typedef std::pair EListItem; + int num = 0; + BOOST_FOREACH(const EListItem& litem, *$2) { + if (!litem.second.SideEffect && num != $2->size() - 1) + yyerror(&litem.second.DebugInfo, NULL, NULL, "Value computed is not used."); + dlist.push_back(litem.first); + num++; + } + delete $2; + DictExpression *aexpr = new DictExpression(dlist, @$); + aexpr->MakeInline(); + + $$ = new FunctionExpression(std::vector(), NULL, aexpr, @$); + } ; rterm: rterm_side_effect