From 599429ec9324667755d08171765037b0592274fd Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 20 Oct 2013 15:06:05 +0200 Subject: [PATCH] config: Implement AST support for const expressions. --- lib/config/Makefile.am | 4 ++ lib/config/aexpression.cpp | 69 +++++++++++++++++++++++++++++++ lib/config/aexpression.h | 67 ++++++++++++++++++++++++++++++ lib/config/avalue.cpp | 52 +++++++++++++++++++++++ lib/config/avalue.h | 63 ++++++++++++++++++++++++++++ lib/config/config.vcxproj | 4 ++ lib/config/config.vcxproj.filters | 12 ++++++ lib/config/config_parser.yy | 67 ++++++++++++++---------------- 8 files changed, 301 insertions(+), 37 deletions(-) create mode 100644 lib/config/aexpression.cpp create mode 100644 lib/config/aexpression.h create mode 100644 lib/config/avalue.cpp create mode 100644 lib/config/avalue.h diff --git a/lib/config/Makefile.am b/lib/config/Makefile.am index 6def093dc..b9f1669c3 100644 --- a/lib/config/Makefile.am +++ b/lib/config/Makefile.am @@ -23,6 +23,10 @@ AM_YFLAGS = -d config_lexer.cc: config_parser.h libconfig_la_SOURCES = \ + aexpression.cpp \ + aexpression.h \ + avalue.cpp \ + avalue.h \ base-type.conf \ configcompiler.cpp \ configcompiler.h \ diff --git a/lib/config/aexpression.cpp b/lib/config/aexpression.cpp new file mode 100644 index 000000000..98c438fc9 --- /dev/null +++ b/lib/config/aexpression.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "config/aexpression.h" + +using namespace icinga; + +AExpression::AExpression(AOperator op, const AValue& operand1) + : m_Operator(op), m_Operand1(operand1) +{ + ASSERT(op == AEReturn); +} + +AExpression::AExpression(AOperator op, const AValue& operand1, const AValue& operand2) + : m_Operator(op), m_Operand1(operand1), m_Operand2(operand2) +{ + ASSERT(op == AEAdd || op == AESubtract || op == AEMultiply || op == AEDivide || + op == AEBinaryAnd || op == AEBinaryOr || op == AEShiftLeft || op == AEShiftRight); +} + +Value AExpression::Evaluate(const Object::Ptr& thisRef) const +{ + Value left, right; + + left = m_Operand1.Evaluate(thisRef); + right = m_Operand2.Evaluate(thisRef); + + switch (m_Operator) { + case AEReturn: + return left; + case AEAdd: + if (left.GetType() == ValueString || right.GetType() == ValueString) + return (String)left + (String)right; + else + return (double)left + (double)right; + case AESubtract: + return (double)left + (double)right; + case AEMultiply: + return (double)left * (double)right; + case AEDivide: + return (double)left / (double)right; + case AEBinaryAnd: + return (long)left & (long)right; + case AEBinaryOr: + return (long)left | (long)right; + case AEShiftLeft: + return (long)left << (long)right; + case AEShiftRight: + return (long)left >> (long)right; + default: + ASSERT(!"Invalid operator."); + } +} \ No newline at end of file diff --git a/lib/config/aexpression.h b/lib/config/aexpression.h new file mode 100644 index 000000000..3da667651 --- /dev/null +++ b/lib/config/aexpression.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef AEXPRESSION_H +#define AEXPRESSION_H + +#include "config/i2-config.h" +#include "config/avalue.h" +#include "base/object.h" + +namespace icinga +{ + +/** + * @ingroup config + */ +enum AOperator +{ + AEReturn, + AEAdd, + AESubtract, + AEMultiply, + AEDivide, + AEBinaryAnd, + AEBinaryOr, + AEShiftLeft, + AEShiftRight +}; + +/** + * @ingroup config + */ +class AExpression : public Object +{ +public: + DECLARE_PTR_TYPEDEFS(AExpression); + + AExpression(AOperator op, const AValue& operand1); + AExpression(AOperator op, const AValue& operand1, const AValue& operand2); + + Value Evaluate(const Object::Ptr& thisRef) const; + +private: + AOperator m_Operator; + AValue m_Operand1; + AValue m_Operand2; +}; + +} + +#endif /* TYPERULE_H */ diff --git a/lib/config/avalue.cpp b/lib/config/avalue.cpp new file mode 100644 index 000000000..8b792e0c7 --- /dev/null +++ b/lib/config/avalue.cpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "config/avalue.h" +#include "config/aexpression.h" +#include "base/scriptvariable.h" + +using namespace icinga; + +AValue::AValue(void) + : m_Type(ATSimple), m_Expression(NULL) +{ } + +AValue::AValue(const AExpression::Ptr& expr) + : m_Type(ATExpression), m_Expression(expr) +{ } + +AValue::AValue(AValueType type, const Value& value) + : m_Type(type), m_Value(value), m_Expression(NULL) +{ } + +Value AValue::Evaluate(const Object::Ptr& thisRef) const +{ + switch (m_Type) { + case ATSimple: + return m_Value; + case ATVariable: + return ScriptVariable::Get(m_Value); + case ATThisRef: + VERIFY(!"Not implemented."); + case ATExpression: + return m_Expression->Evaluate(thisRef); + default: + ASSERT(!"Invalid type."); + } +} diff --git a/lib/config/avalue.h b/lib/config/avalue.h new file mode 100644 index 000000000..107940025 --- /dev/null +++ b/lib/config/avalue.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef AVALUE_H +#define AVALUE_H + +#include "config/i2-config.h" +#include "base/value.h" +#include "base/object.h" + +namespace icinga +{ + +/** + * @ingroup config + */ +enum AValueType +{ + ATSimple, + ATVariable, + ATThisRef, + ATExpression +}; + +class AExpression; + +/** + * @ingroup config + */ +class AValue +{ +public: + AValue(void); + AValue(const shared_ptr& expr); + AValue(AValueType type, const Value& value); + + Value Evaluate(const Object::Ptr& thisRef) const; + +private: + AValueType m_Type; + Value m_Value; + shared_ptr m_Expression; +}; + +} + +#endif /* AVALUE_H */ \ No newline at end of file diff --git a/lib/config/config.vcxproj b/lib/config/config.vcxproj index 36acd56bc..81f430190 100644 --- a/lib/config/config.vcxproj +++ b/lib/config/config.vcxproj @@ -20,6 +20,8 @@ + + @@ -34,6 +36,8 @@ + + NotUsing NotUsing diff --git a/lib/config/config.vcxproj.filters b/lib/config/config.vcxproj.filters index 624ef3131..f1f58b4d6 100644 --- a/lib/config/config.vcxproj.filters +++ b/lib/config/config.vcxproj.filters @@ -37,6 +37,12 @@ Quelldateien + + Quelldateien + + + Quelldateien + @@ -75,6 +81,12 @@ Headerdateien + + Headerdateien + + + Headerdateien + diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 672a91de1..584dd5ecb 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -26,6 +26,7 @@ #include "config/configcompilercontext.h" #include "config/typerule.h" #include "config/typerulelist.h" +#include "config/aexpression.h" #include "base/value.h" #include "base/utility.h" #include "base/array.h" @@ -61,6 +62,7 @@ using namespace icinga; Expression *expr; ExpressionList *exprl; Array *array; + Value *aexpr; } %token T_STRING @@ -109,8 +111,8 @@ using namespace icinga; %type partial_specifier %type object_inherits_list %type object_inherits_specifier -%type constterm -%type constexpression +%type aterm +%type aexpression %left '+' '-' %left '*' '/' %left '&' @@ -535,85 +537,74 @@ simplevalue: T_STRING } ; -constterm: '(' constexpression ')' +aterm: '(' aexpression ')' { $$ = $2; } -constexpression: T_STRING +aexpression: T_STRING { - $$ = new Value($1); + $$ = new Value(boost::make_shared(AEReturn, AValue(ATSimple, $1))); free($1); } | T_NUMBER { - $$ = new Value($1); + $$ = new Value(boost::make_shared(AEReturn, AValue(ATSimple, $1))); } | T_IDENTIFIER { - $$ = new Value(ScriptVariable::Get($1)); + $$ = new Value(boost::make_shared(AEReturn, AValue(ATVariable, $1))); free($1); } - | constexpression '+' constexpression + | aexpression '+' aexpression { - if ($1->GetType() == ValueString || $3->GetType() == ValueString) - $$ = new Value((String)*$1 + (String)*$3); - else - $$ = new Value((double)*$1 + (double)*$3); - + $$ = new Value(boost::make_shared(AEAdd, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression '-' constexpression + | aexpression '-' aexpression { - $$ = new Value((double)*$1 - (double)*$3); - + $$ = new Value(boost::make_shared(AESubtract, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression '*' constexpression + | aexpression '*' aexpression { - $$ = new Value((double)*$1 * (double)*$3); - + $$ = new Value(boost::make_shared(AEMultiply, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression '/' constexpression + | aexpression '/' aexpression { - $$ = new Value((double)*$1 / (double)*$3); - + $$ = new Value(boost::make_shared(AEDivide, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression '&' constexpression + | aexpression '&' aexpression { - $$ = new Value((long)*$1 & (long)*$3); - + $$ = new Value(boost::make_shared(AEBinaryAnd, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression '|' constexpression + | aexpression '|' aexpression { - $$ = new Value((long)*$1 | (long)*$3); - + $$ = new Value(boost::make_shared(AEBinaryOr, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression T_SHIFT_LEFT constexpression + | aexpression T_SHIFT_LEFT aexpression { - $$ = new Value((long)*$1 << (long)*$3); - + $$ = new Value(boost::make_shared(AEShiftLeft, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | constexpression T_SHIFT_RIGHT constexpression + | aexpression T_SHIFT_RIGHT aexpression { - $$ = new Value((long)*$1 >> (long)*$3); - + $$ = new Value(boost::make_shared(AEShiftRight, static_cast(*$1), static_cast(*$3))); delete $1; delete $3; } - | '(' constexpression ')' + | '(' aexpression ')' { $$ = $2; } @@ -625,9 +616,11 @@ value: simplevalue ExpressionList::Ptr exprl = ExpressionList::Ptr($1); $$ = new Value(exprl); } - | constterm + | aterm { - $$ = $1; + AExpression::Ptr aexpr = *$1; + $$ = new Value(aexpr->Evaluate(Object::Ptr())); + delete $1; } ; %% -- 2.40.0