#include namespace S { //S-Expressions template struct Atom {const static int name = Name;}; #define name(N,S) template<> struct Atom<-N> {const static int name = -N; char* str = #S;}; Atom<-N> typedef S; name( 1,NIL) name( 2,CONS) name( 3,ATOM) name( 4,T) name( 5,F) name( 6,CAR) name( 7,CDR) name( 8,LAMBDA) name( 9,LABEL) name(10,QUOTE) name(11,COND) name(12,EQ) name(13,EQUAL) name(14,LIST) #undef name // cons template struct Cons {}; // bool to Symbolic Bool conversion template struct ToSbool {}; template<> struct ToSbool { T typedef value; }; template<> struct ToSbool { F typedef value; }; // Sybolic Bool to bool conversion template struct ToBool {}; template<> struct ToBool { const static bool value = true; }; template<> struct ToBool { const static bool value = false; }; } namespace M { //M-Expressions // atom template struct Atom { S::F typedef value; }; template struct Atom > { S::T typedef value; }; // car template struct Car {}; template struct Car > { A typedef value; }; // cdr template struct Cdr {}; template struct Cdr > { D typedef value; }; // eq template struct Eq {}; template struct Eq, S::Atom > { S::F typedef value; }; template struct Eq, S::Atom > { S::T typedef value; }; // equal template struct Equal { S::F typedef value; }; template struct Equal, S::Cons > { typename Equal::value typedef EA; typename Equal::value typedef ED; typename S::ToSbool< S::ToBool::value && S::ToBool::value >::value typedef value; }; template struct Equal, S::Atom > { typename Eq, S::Atom >::value typedef value; }; // eval (prototype) template struct Eval {}; // evlist template struct Evlist {}; template struct Evlist { S::NIL typedef value; }; template struct Evlist, E> { S::Cons::value, typename Evlist::value> typedef value; }; // assoc template struct Assoc {}; template struct Assoc, R> > { V typedef value; }; template struct Assoc, R> > { typename Assoc::value typedef value; }; // evcond template struct Evcond {}; template struct Evcond >, R>, E> { typename Eval::value typedef value; }; template struct Evcond >, R>, E> { typename Evcond::value typedef value; }; template struct Evcond >, R>, E> { typename Evcond::value, S::Cons >, R>, E>::value typedef value; }; // pairlist template struct Pairlist {}; template struct Pairlist { E typedef value; }; template struct Pairlist, S::Cons, E> { S::Cons, typename Pairlist::value> typedef value; }; // eval template struct Eval, E> { typename Assoc, E>::value typedef value; }; template struct Eval, E> { typename Car::value typedef value; }; template struct Eval, E> { typename Atom::value, E>::value>::value typedef value; }; template struct Eval, E> { typename Evcond::value typedef value; }; template struct Eval, E> { typename Eq< typename Eval::value, E>::value, typename Eval::value>::value, E>::value >::value typedef value; }; template struct Eval, E> { typename Equal< typename Eval::value, E>::value, typename Eval::value>::value, E>::value >::value typedef value; }; template struct Eval, E> { typename Car< typename Eval::value, E>::value >::value typedef value; }; template struct Eval, E> { typename Cdr< typename Eval::value, E>::value >::value typedef value; }; template struct Eval, E> { S::Cons< typename Eval::value, E>::value, typename Eval::value>::value, E>::value > typedef value; }; template struct Eval, E> { typename Evlist::value typedef value; }; template struct Eval, R>, E> { typename Eval, E>::value, R>, E>::value typedef value; }; template struct Eval > >, R>, E> { typename Eval< Body, typename Pairlist::value, E>::value >::value typedef value; }; template struct Eval, S::Cons > >, R>, E> { typename Eval< S::Cons, S::Cons, Body>, E> >::value typedef value; }; } int main() { /* Human-readable version of the following expression Eval[ ((LABEL Atom0 (LAMBDA (Atom1 Atom2) (COND ((EQUAL Atom1 'NIL) Atom2) (T (CONS (CAR Atom1) (Atom0 (CDR Atom1) Atom2))) ))) '(Atom3 Atom4) '(Atom5 Atom6)); NIL ] */ typename M::Eval< S::Cons< S::Cons< S::LABEL, S::Cons< S::Atom<0>,//concat S::Cons< S::Cons< S::LAMBDA, S::Cons< S::Cons< S::Atom<1>, S::Cons< S::Atom<2>, S::NIL> >, S::Cons< S::Cons< S::COND, S::Cons< S::Cons< S::Cons< S::EQUAL, S::Cons< S::Atom<1>, S::Cons< S::Cons< S::QUOTE, S::Cons< S::NIL, S::NIL> >, S::NIL> > >, S::Cons< S::Atom<2>, S::NIL> >, S::Cons< S::Cons< S::T, S::Cons< S::Cons< S::CONS, S::Cons< S::Cons< S::CAR, S::Cons< S::Atom<1>, S::NIL> >, S::Cons< S::Cons< S::Atom<0>, S::Cons< S::Cons< S::CDR, S::Cons< S::Atom<1>, S::NIL> >, S::Cons< S::Atom<2>, S::NIL> > >, S::NIL> > >, S::NIL> >, S::NIL> > >, S::NIL> > >, S::NIL> > >, S::Cons< S::Cons< S::QUOTE, S::Cons< S::Cons< S::Atom<3>, S::Cons< S::Atom<4>, S::NIL> >, S::NIL> >, S::Cons< S::Cons< S::QUOTE, S::Cons< S::Cons< S::Atom<5>, S::Cons< S::Atom<6>, S::NIL> >, S::NIL> >, S::NIL> > >, S::NIL >::value typedef X; //X is the result of the computation X::print_by_error; //print_by_error doesn't exist, so a compiler with good feedback will represent the type "X" in an error return 0; }