Boost logo

Proto :

Subject: [proto] Recursive functions in a mini language
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-08-06 19:29:54


I had asked boost-users for suggestions on how to define mutually
recursive functions in a DSEL. Here is the original thread.
http://lists.boost.org/boost-users/2010/07/60488.php

I am thinking about a solution inspired by Spirit subrules, that looks
as follows :

#include <boost/fusion/container/vector.hpp>
#include <boost/proto/proto.hpp>
#include <vector>
#include <iostream>

using namespace std;

namespace mpl=boost::mpl;
namespace proto=boost::proto;
namespace fusion=boost::fusion;

template<typename>
struct arg{};

proto::terminal<arg<mpl::int_<0> > >::type const _1 = {{}};
proto::terminal<arg<mpl::int_<1> > >::type const _2 = {{}};
proto::terminal<arg<mpl::int_<2> > >::type const _3 = {{}};

template<typename>
struct func {};

#define DECLARE_FUNC(n, x) \
proto::terminal<func<mpl::int_<n> > >::type const x = {{}};

struct _declare_module {};
proto::terminal<_declare_module>::type const declare_module = {{}};

struct _map {};
proto::terminal<_map>::type const map = {{}};

int main()
{
  int i = 41;

  DECLARE_FUNC(0, det_inverse);
  DECLARE_FUNC(1, negmul);
  DECLARE_FUNC(2, vmul);
  DECLARE_FUNC(3, vadd);
  DECLARE_FUNC(4, precondition);
  DECLARE_FUNC(5, fib);

  BOOST_AUTO(preconditioner,(
             declare_module[
                            vadd = _1+_2,
                            negmul = -vmul(_1,_2),
                            det_inverse = 1/(_1*_3-_2*_2),
                            vmul = _1*_2,
                            fib = fib(_1-1) + fib(_1-2),
                            precondition = vmul(map(det_inverse, _1,_2,_3), _1)
                            ]
                             ));

  std::vector<int> a, b, c;

  preconditioner->*precondition(a,b,c);

  proto::display_expr((preconditioner->*precondition)(a,b,c));

  return 0;
}

Basically, the user is forced to declare all the functions using
unique identifiers beforehand. He then declares a module containing
the definitions of the function. He can then call the functions as
module->*func(...). I imagine this can be made to work by parsing the
module and executing the correct function based on the type. I would
like to ask people's opinions on this forum. Do you guys see any
problems? Are there more elegant approaches?

Thanks,
Manjunath


Proto list run by eric at boostpro.com