C++でcompile time Schemeをつくってみる計画

こんなことばかりしてるとSchemeが病的に好きな人みたいに思われそうですが、特にそういうこともありません(それどころかSchemeでまともなプログラムを組んだこともない始末)。
それはともかく、Generic ProgrammingとかModern C++ Designとか読んでたら非常にむらむらしてたのでなんかつくってみた。変数ルックアップのとこだけ。

//boost/preprocessorでなんとかならんのかな
#define LIST0() nil
#define LIST1(l1) Cons<l1,LIST0()>
#define LIST2(l1,l2) Cons<l1,LIST1(l2)>
#define LIST3(l1,l2,l3) Cons<l1,LIST2(l2,l3)>
#define LIST4(l1,l2,l3,l4) Cons<l1,LIST3(l2,l3,l4)>
#define LIST5(l1,l2,l3,l4,l5) Cons<l1,LIST4(l2,l3,l4,l5)>

//data types

template<int n>
struct int_value {
  enum {value=n;};
};
template<char c>
struct symbol {};

struct nil {};

template<typename CA,typename CD>
struct Cons {
  typedef CA car;
  typedef CD cdr;
};


template<typename Args,typename Body>
struct lambda {
  typedef typename Body body;
  typedef typename Args args;
};

//environment
#define DECLARE_ENV(name) \
template<typename P> \
struct name { \
  typedef P parent; \
  template<typename Sym> struct lookup { \
    typedef typename parent::lookup<Sym>::result result; \
  };

#define BIND_SYMBOL(sym,val) \
  template<> struct lookup< symbol<sym> > { \
    typedef typename val result; \
  };
#define END_ENV() \
};


//eval constant
template<typename S,class Env>
struct Evaluator {
  typedef S result;
};

//eval symbol
template<char c,class Env>
struct Evaluator<symbol<c>,Env> {
  typedef typename Env::lookup<symbol<c> >::result result;
};

//eval list
template<typename F,typename Arglist,typename Env>
struct Evaluator<Cons<F,Arglist>,Env> {
};

//to dynamic world
template<typename T>
struct to_dynamic {
};

template<int n>
struct to_dynamic<int_value<n> > {
  static int value() {
    return n;
  }
};

DECLARE_ENV(e1)
  BIND_SYMBOL('x',int_value<100>);
  BIND_SYMBOL('y',int_value<200>);
  BIND_SYMBOL('z',LIST3(int_value<200>,int_value<100>,int_value<300>));
END_ENV()

DECLARE_ENV(e2)
  BIND_SYMBOL('x',int_value<111>);
  BIND_SYMBOL('a',int_value<999>);
END_ENV()


#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {
  typedef e1<nil> env;
  typedef e2<env> env2;
  cout << to_dynamic<Evaluator<symbol<'x'>,env >::result>::value() << endl; //100
  cout << to_dynamic<Evaluator<symbol<'x'>,env2 >::result>::value() << endl; //111
  cout << to_dynamic<Evaluator<int_value<999>,nil>::result>::value() << endl; //999
}