From: Gunnar Beutner Date: Mon, 24 Nov 2014 08:53:45 +0000 (+0100) Subject: Implement the __if and __else keywords X-Git-Tag: v2.3.0~620 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ec499be178b7ffa18be0a871fdc907d2a4ccd0b;p=icinga2 Implement the __if and __else keywords fixes #7824 --- diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index 8b93df51a..f24c8d225 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -251,6 +251,8 @@ __function return T_FUNCTION; __return return T_RETURN; __for return T_FOR; __signal return T_SIGNAL; +__if return T_IF; +__else return T_ELSE; =\> return T_FOLLOWS; \<\< return T_SHIFT_LEFT; \>\> return T_SHIFT_RIGHT; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 92989ef26..f38a255d9 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -165,6 +165,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %token T_RETURN "return (T_RETURN)" %token T_FOR "for (T_FOR)" %token T_SIGNAL "signal (T_SIGNAL)" +%token T_IF "if (T_IF)" +%token T_ELSE "else (T_ELSE)" %token T_FOLLOWS "=> (T_FOLLOWS)" %type identifier @@ -855,6 +857,23 @@ rterm_without_indexer: T_STRING $$ = new ForExpression($3, "", $5, aexpr, DebugInfoRange(@1, @7)); free($3); } + | T_IF '(' rterm ')' rterm_scope + { + DictExpression *atrue = dynamic_cast($5); + atrue->MakeInline(); + + $$ = new ConditionalExpression($3, atrue, NULL, DebugInfoRange(@1, @5)); + } + | T_IF '(' rterm ')' rterm_scope T_ELSE rterm_scope + { + DictExpression *atrue = dynamic_cast($5); + atrue->MakeInline(); + + DictExpression *afalse = dynamic_cast($7); + afalse->MakeInline(); + + $$ = new ConditionalExpression($3, atrue, afalse, DebugInfoRange(@1, @7)); + } ; target_type_specifier: /* empty */ diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index 063b92255..bd5bb7852 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -346,6 +346,14 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const return right; } +Value ConditionalExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const +{ + if (m_Condition->Evaluate(frame, dhint)) + return m_TrueBranch->Evaluate(frame, dhint); + else if (m_FalseBranch) + return m_FalseBranch->Evaluate(frame, dhint); +} + Value ReturnExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const { BOOST_THROW_EXCEPTION(InterruptExecutionError(m_Operand->Evaluate(frame))); diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index d9d9ca556..73ea30f7b 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -556,6 +556,29 @@ private: }; +class I2_CONFIG_API ConditionalExpression : public DebuggableExpression +{ +public: + ConditionalExpression(Expression *condition, Expression *true_branch, Expression *false_branch, const DebugInfo& debugInfo = DebugInfo()) + : DebuggableExpression(debugInfo), m_Condition(condition), m_TrueBranch(true_branch), m_FalseBranch(false_branch) + { } + + ~ConditionalExpression(void) + { + delete m_Condition; + delete m_TrueBranch; + delete m_FalseBranch; + } + +protected: + virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const; + +private: + Expression *m_Condition; + Expression *m_TrueBranch; + Expression *m_FalseBranch; +}; + class I2_CONFIG_API ReturnExpression : public UnaryExpression { public: