2021-09-12 16:01:30 +00:00
|
|
|
#include<iostream>
|
|
|
|
|
|
|
|
namespace S { //S-Expressions
|
|
|
|
template<int Name> 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<typename L, typename R>
|
|
|
|
struct Cons {};
|
|
|
|
// bool to Symbolic Bool conversion
|
|
|
|
template<bool B>
|
|
|
|
struct ToSbool {};
|
|
|
|
template<>
|
|
|
|
struct ToSbool<true> {
|
|
|
|
T typedef value;
|
|
|
|
};
|
|
|
|
template<>
|
|
|
|
struct ToSbool<false> {
|
|
|
|
F typedef value;
|
|
|
|
};
|
|
|
|
// Sybolic Bool to bool conversion
|
|
|
|
template<typename B>
|
|
|
|
struct ToBool {};
|
|
|
|
template<>
|
|
|
|
struct ToBool<T> {
|
|
|
|
const static bool value = true;
|
|
|
|
};
|
|
|
|
template<>
|
|
|
|
struct ToBool<F> {
|
|
|
|
const static bool value = false;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace M { //M-Expressions
|
|
|
|
// atom
|
|
|
|
template<typename E>
|
|
|
|
struct Atom {
|
|
|
|
S::F typedef value;
|
|
|
|
};
|
|
|
|
template<int I>
|
|
|
|
struct Atom<S::Atom<I> > {
|
|
|
|
S::T typedef value;
|
|
|
|
};
|
|
|
|
// car
|
|
|
|
template<typename E>
|
|
|
|
struct Car {};
|
|
|
|
template<typename A, typename D>
|
|
|
|
struct Car<S::Cons<A, D> > {
|
|
|
|
A typedef value;
|
|
|
|
};
|
|
|
|
// cdr
|
|
|
|
template<typename E>
|
|
|
|
struct Cdr {};
|
|
|
|
template<typename A, typename D>
|
|
|
|
struct Cdr<S::Cons<A, D> > {
|
|
|
|
D typedef value;
|
|
|
|
};
|
|
|
|
// eq
|
|
|
|
template<typename E1, typename E2>
|
|
|
|
struct Eq {};
|
|
|
|
template<int I1, int I2>
|
|
|
|
struct Eq<S::Atom<I1>, S::Atom<I2> > {
|
|
|
|
S::F typedef value;
|
|
|
|
};
|
|
|
|
template<int I>
|
|
|
|
struct Eq<S::Atom<I>, S::Atom<I> > {
|
|
|
|
S::T typedef value;
|
|
|
|
};
|
|
|
|
// equal
|
|
|
|
template<typename E1, typename E2>
|
|
|
|
struct Equal {
|
|
|
|
S::F typedef value;
|
|
|
|
};
|
|
|
|
template<typename A1, typename A2, typename D1, typename D2>
|
|
|
|
struct Equal<S::Cons<A1, D1>, S::Cons<A2, D2> > {
|
|
|
|
typename Equal<A1, A2>::value typedef EA;
|
|
|
|
typename Equal<D1, D2>::value typedef ED;
|
|
|
|
typename S::ToSbool<
|
|
|
|
S::ToBool<EA>::value && S::ToBool<ED>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<int I1, int I2>
|
|
|
|
struct Equal<S::Atom<I1>, S::Atom<I2> > {
|
|
|
|
typename Eq<S::Atom<I1>, S::Atom<I2> >::value typedef value;
|
|
|
|
};
|
|
|
|
// eval (prototype)
|
|
|
|
template<typename X, typename E>
|
|
|
|
struct Eval {};
|
|
|
|
// evlist
|
|
|
|
template<typename L, typename E>
|
|
|
|
struct Evlist {};
|
|
|
|
template<typename E>
|
|
|
|
struct Evlist<S::NIL, E> {
|
|
|
|
S::NIL typedef value;
|
|
|
|
};
|
|
|
|
template<typename H, typename R, typename E>
|
|
|
|
struct Evlist<S::Cons<H, R>, E> {
|
|
|
|
S::Cons<typename Eval<H, E>::value, typename Evlist<R, E>::value> typedef value;
|
|
|
|
};
|
|
|
|
// assoc
|
|
|
|
template<typename X, typename E>
|
|
|
|
struct Assoc {};
|
|
|
|
template<typename X, typename V, typename R>
|
|
|
|
struct Assoc<X, S::Cons<S::Cons<X, V>, R> > {
|
|
|
|
V typedef value;
|
|
|
|
};
|
|
|
|
template<typename X, typename WX, typename WV, typename R>
|
|
|
|
struct Assoc<X, S::Cons<S::Cons<WX, WV>, R> > {
|
|
|
|
typename Assoc<X, R>::value typedef value;
|
|
|
|
};
|
|
|
|
// evcond
|
|
|
|
template<typename C, typename E>
|
|
|
|
struct Evcond {};
|
|
|
|
template<typename V, typename R, typename E>
|
|
|
|
struct Evcond<S::Cons<S::Cons<S::T, S::Cons<V, S::NIL> >, R>, E> {
|
|
|
|
typename Eval<V, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename V, typename R, typename E>
|
|
|
|
struct Evcond<S::Cons<S::Cons<S::F, S::Cons<V, S::NIL> >, R>, E> {
|
|
|
|
typename Evcond<R, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename Tr, typename V, typename R, typename E>
|
|
|
|
struct Evcond<S::Cons<S::Cons<Tr, S::Cons<V, S::NIL> >, R>, E> {
|
|
|
|
typename Evcond<S::Cons<S::Cons<typename Eval<Tr, E>::value, S::Cons<V, S::NIL> >, R>, E>::value typedef value;
|
|
|
|
};
|
|
|
|
// pairlist
|
|
|
|
template<typename As, typename Ds, typename E>
|
|
|
|
struct Pairlist {};
|
|
|
|
template<typename Ds, typename E>
|
|
|
|
struct Pairlist<S::NIL, Ds, E> {
|
|
|
|
E typedef value;
|
|
|
|
};
|
|
|
|
template<typename A, typename RA, typename D, typename RD, typename E>
|
|
|
|
struct Pairlist<S::Cons<A, RA>, S::Cons<D, RD>, E> {
|
|
|
|
S::Cons<S::Cons<A, D>, typename Pairlist<RA, RD, E>::value> typedef value;
|
|
|
|
};
|
|
|
|
// eval
|
|
|
|
template<int I, typename E>
|
|
|
|
struct Eval<S::Atom<I>, E> {
|
|
|
|
typename Assoc<S::Atom<I>, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::QUOTE, R>, E> {
|
|
|
|
typename Car<R>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::ATOM, R>, E> {
|
|
|
|
typename Atom<typename Eval<typename Car<R>::value, E>::value>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::COND, R>, E> {
|
|
|
|
typename Evcond<R, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::EQ, R>, E> {
|
|
|
|
typename Eq<
|
|
|
|
typename Eval<typename Car<R>::value, E>::value,
|
|
|
|
typename Eval<typename Car<typename Cdr<R>::value>::value, E>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::EQUAL, R>, E> {
|
|
|
|
typename Equal<
|
|
|
|
typename Eval<typename Car<R>::value, E>::value,
|
|
|
|
typename Eval<typename Car<typename Cdr<R>::value>::value, E>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::CAR, R>, E> {
|
|
|
|
typename Car<
|
|
|
|
typename Eval<typename Car<R>::value, E>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::CDR, R>, E> {
|
|
|
|
typename Cdr<
|
|
|
|
typename Eval<typename Car<R>::value, E>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::CONS, R>, E> {
|
|
|
|
S::Cons<
|
|
|
|
typename Eval<typename Car<R>::value, E>::value,
|
|
|
|
typename Eval<typename Car<typename Cdr<R>::value>::value, E>::value
|
|
|
|
> typedef value;
|
|
|
|
};
|
|
|
|
template<typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::LIST, R>, E> {
|
|
|
|
typename Evlist<R, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<int N, typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::Atom<N>, R>, E> {
|
|
|
|
typename Eval<S::Cons<typename Eval<S::Atom<N>, E>::value, R>, E>::value typedef value;
|
|
|
|
};
|
|
|
|
template<typename Names, typename Body, typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::Cons<S::LAMBDA, S::Cons<Names, S::Cons<Body, S::NIL> > >, R>, E> {
|
|
|
|
typename Eval<
|
|
|
|
Body,
|
|
|
|
typename Pairlist<Names, typename Evlist<R, E>::value, E>::value
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
template<int N, typename Body, typename R, typename E>
|
|
|
|
struct Eval<S::Cons<S::Cons<S::LABEL, S::Cons<S::Atom<N>, S::Cons<Body, S::NIL> > >, R>, E> {
|
|
|
|
typename Eval<
|
|
|
|
S::Cons<Body, R>,
|
|
|
|
S::Cons<S::Cons<S::Atom<N>, Body>, E>
|
|
|
|
>::value typedef value;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
2021-09-12 16:03:43 +00:00
|
|
|
/* Human-readable version of the following expression
|
2021-09-12 16:01:30 +00:00
|
|
|
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
|
2021-09-12 16:03:43 +00:00
|
|
|
>::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
|
2021-09-12 16:01:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|