From 746fba98d5d490c4c4a7810153f16bf13d65f81f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 28 Nov 2014 12:50:58 +0100 Subject: [PATCH] DSL verb token: move to distinct definition header concept finished thus far --- src/lib/unique-malloc-owner.hpp | 8 +- src/lib/verb-token.hpp | 106 ++++++++++++++++++ tests/library/verb-function-dispatch-test.cpp | 35 +----- 3 files changed, 111 insertions(+), 38 deletions(-) create mode 100644 src/lib/verb-token.hpp diff --git a/src/lib/unique-malloc-owner.hpp b/src/lib/unique-malloc-owner.hpp index db83cb04a..a04cf5610 100644 --- a/src/lib/unique-malloc-owner.hpp +++ b/src/lib/unique-malloc-owner.hpp @@ -27,14 +27,14 @@ ** mostly for the purpose of documenting the issue at the ** usage site. ** - ** @see cxx-demangle.cpp + ** @see lib::test::demangleCxx ** @see UniqueMallocOwner_test ** */ -#ifndef UNIQUE_MALLOC_OWNER_H_ -#define UNIQUE_MALLOC_OWNER_H_ +#ifndef LIB_UNIQUE_MALLOC_OWNER_H +#define LIB_UNIQUE_MALLOC_OWNER_H #include "lib/error.hpp" @@ -83,4 +83,4 @@ namespace lib { } // namespace lib -#endif /*UNIQUE_MALLOC_OWNER_HPP_*/ +#endif /*LIB_UNIQUE_MALLOC_OWNER_H*/ diff --git a/src/lib/verb-token.hpp b/src/lib/verb-token.hpp new file mode 100644 index 000000000..684ac2d49 --- /dev/null +++ b/src/lib/verb-token.hpp @@ -0,0 +1,106 @@ +/* + VERB-TOKEN.hpp - double dispatch based on DSL tokens + + Copyright (C) Lumiera.org + 2014, Hermann Vosseler + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file verb-token.hpp + ** Building blocks for a simple DSL using double dispatch to a handler function. + ** Actually this is a specialised variation of the visitor pattern, where the + ** "verb tokens" of the language are the domain objects accepting a "receiver" + ** (visitor) to provide the concrete implementation function for each "verb". + ** + ** The intended usage is to set up a language comprised of several abstract actions ("verbs"), + ** but to defer the concrete implementation to a specific set of handler functions, which + ** is provided late, at application time. This way, we can send a sequence of verbs towards + ** an unknown receiver, which supplies the actual meaning within the target context. In + ** the end, there is a double-dispatch based both on the individual verb given and the + ** concrete receiver, which needs to implement the interface used in the definition + ** of the verb tokens. The handler functions defined within this interface may + ** take additional arguments, which are passed through on application to + ** the concrete receiver, e.g. `VERB_doit (receiver, arg1, arg2)` + ** results in the invocation of \c receiver.doit(arg1,arg2) + ** + ** @see ...TODO + ** @see VerbFunctionDispatch_test + ** + */ + + +#ifndef LIB_VERB_TOKEN_H +#define LIB_VERB_TOKEN_H + + +#include "lib/symbol.hpp" +#include "lib/util.hpp" + +#include +#include + + +namespace lib { + + using std::string; + + + /** + * Action token implemented by double dispatch to a handler function, + * as defined in the "receiver" interface (parameter \c REC). + * The token is typically part of a DSL and can be applied + * to a concrete receiver subclass. + * @note the #VERB macro simplifies definition of actual tokens + */ + template + class VerbToken; + + template + class VerbToken + { + typedef RET (REC::*Handler) (ARGS...); + + Handler handler_; + Literal token_; + + public: + RET + applyTo (REC& receiver, ARGS&&... args) + { + return (receiver.*handler_)(std::forward(args)...); + } + + operator string() + { + return string(token_); + } + + VerbToken(Handler handlerFunction, Literal token) + : handler_(handlerFunction) + , token_(token) + { } + }; + +#define VERB(RECEIVER, FUN) VERB_##FUN (&RECEIVER::FUN, STRINGIFY(FUN)) + + + + + +} // namespace lib +#endif /*LIB_VERB_TOKEN_H*/ diff --git a/tests/library/verb-function-dispatch-test.cpp b/tests/library/verb-function-dispatch-test.cpp index 090477909..5800d2811 100644 --- a/tests/library/verb-function-dispatch-test.cpp +++ b/tests/library/verb-function-dispatch-test.cpp @@ -22,12 +22,10 @@ #include "lib/test/run.hpp" +#include "lib/verb-token.hpp" #include "lib/format-string.hpp" -#include "lib/symbol.hpp" -#include "lib/util.hpp" #include -#include #include #include @@ -40,37 +38,6 @@ using std::cout; namespace lib { namespace test{ - template - class VerbToken; - - template - class VerbToken - { - typedef RET (REC::*Handler) (ARGS...); - - Handler handler_; - Literal token_; - - public: - RET - applyTo (REC& receiver, ARGS&&... args) - { - return (receiver.*handler_)(std::forward(args)...); - } - - operator string() - { - return string(token_); - } - - VerbToken(Handler handlerFunction, Literal token) - : handler_(handlerFunction) - , token_(token) - { } - }; - -#define VERB(RECEIVER, FUN) VERB_##FUN (&RECEIVER::FUN, STRINGIFY(FUN)) - class Receiver {