// Copyright (c) 2018-2025 Jean-Louis Leroy // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include using namespace boost::openmethod::aliases; using std::cout; using std::string; struct Node { virtual ~Node() { } }; struct Plus : Node { Plus( shared_virtual_ptr left, shared_virtual_ptr right) : left(left), right(right) { } shared_virtual_ptr left, right; }; struct Times : Node { Times( shared_virtual_ptr left, shared_virtual_ptr right) : left(left), right(right) { } shared_virtual_ptr left, right; }; struct Variable : Node { explicit Variable(int value) : value(value) { } int value; }; // ============================================================================= // add behavior to existing classes, without changing them BOOST_OPENMETHOD_CLASSES(Node, Plus, Times, Variable); // ----------------------------------------------------------------------------- // evaluate BOOST_OPENMETHOD(value, (virtual_ptr), int); BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr node), int) { return value(node->left) + value(node->right); } BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr node), int) { return value(node->left) * value(node->right); } BOOST_OPENMETHOD_OVERRIDE(value, (virtual_ptr node), int) { return node->value; } // ----------------------------------------------------------------------------- // render as Forth BOOST_OPENMETHOD(as_forth, (virtual_ptr), string); BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr node), string) { return as_forth(node->left) + " " + as_forth(node->right) + " +"; } BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr node), string) { return as_forth(node->left) + " " + as_forth(node->right) + " *"; } BOOST_OPENMETHOD_OVERRIDE(as_forth, (virtual_ptr node), string) { return std::to_string(node->value); } // ----------------------------------------------------------------------------- // render as Lisp BOOST_OPENMETHOD(as_lisp, (virtual_ptr), string); BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr node), string) { return "(plus " + as_lisp(node->left) + " " + as_lisp(node->right) + ")"; } BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr node), string) { return "(times " + as_lisp(node->left) + " " + as_lisp(node->right) + ")"; } BOOST_OPENMETHOD_OVERRIDE(as_lisp, (virtual_ptr node), string) { return std::to_string(node->value); } // ----------------------------------------------------------------------------- auto main() -> int { boost::openmethod::initialize(); shared_virtual_ptr node = make_shared_virtual( make_shared_virtual(2), make_shared_virtual( make_shared_virtual(3), make_shared_virtual(4))); cout << as_forth(node) << " = " << as_lisp(node) << " = " << value(node) << "\n"; // output: // 2 3 4 + * = (times 2 (plus 3 4)) = 14 return 0; }