用皮亚诺公里做了一个C++模板元编程语言

1-不支持负数
2-只能处理100以内的整数
3-只有整型和布尔值两种数据类型
4-有bug
5-支持常见的函数式编程如

i0, i1, ..., i9, i10 --- 表示数字0到10

Succ --- 后继
Pred --- 前驱

Add --- 加
Sub --- 减
Mul --- 乘
Div --- 除

True, False --- 布尔值
And --- 与
Or --- 或
Not --- 非

Equal --- 等于
LessThan --- 小于
LessEqual --- 小于等于
GreaterThan --- 大于
GreaterEqual --- 大于等于

If --- 若Bool为真则值为Expr1否则为Expr2

Pair --- 二元组
Head --- 二元组第一个元素
Tail --- 二元组第二个元素

List --- 列表
Length --- 列表长度
Nth --- 列表第N个元素

Take --- 截取列表前N个元素
Drop --- 舍弃列表前N个元素
Concat --- 链接两个列表

Map --- 函数式map
Filter --- 函数式filter
FoldLeft --- 函数式foldleft

Is_Integer --- 辨别数字
Is_Boolean --- 辨别布尔值
Is_Odd --- 是奇数
Is_Even --- 是偶数
Is_Pair --- 是二元组

Max --- 最大值
Min --- 最小值

6-一些测试用函数
Assert::True() --- 断言Bool为真
Integer::ToInt --- 获得整型值
Boolean::ToBool --- 获得布尔值
DisplayInteger::Display() --- 显示整型值
DisplayBoolean::Display() --- 显示布尔值
DisplayList::Display() --- 显示列表

#pragma once

#include 

namespace raven {

    /*************************************************
                        Peano
    *************************************************/

    // Undefined
    struct Undefined {
        using Pred = Undefined;
    };

    // Zero
    struct Zero {
        using Pred = Zero;
    };

    // Succ
    template <class N>
    struct Succ;

    template <>
    struct Succ < Zero > { 
        using Pred = Zero;
    };

    template <>
    struct Succ < Undefined > {
        using Pred = Undefined;
    };

    template <class N>
    struct Succ < Succ > { 
        using Pred = Succ;
    };

    // Pred
    template <class N>
    struct Pred;

    template<>
    struct Pred < Zero > {
        using Value = Zero;
    };

    template<>
    struct Pred < Undefined > {
        using Value = Undefined;
    };

    template<class N>
    struct Pred < Succ > {
        using Value = N;
    };

    /*************************************************
                        Boolean Logic
    *************************************************/

    // True False
    struct True {
        const static bool ToBool = true;
    };
    struct False {
        const static bool ToBool = false;
    };

    // And
    template <class B1, class B2>
    struct And {
        using Value = False;
    };

    template <>
    struct And < True, True > {
        using Value = True;
    };

    // Or
    template <class B1, class B2>
    struct Or {
        using Value = True;
    };

    template <>
    struct Or < False, False > {
        using Value = False;
    };

    // Not
    template <class B>
    struct Not {
        using Value = False;
    };

    template <>
    struct Not < False > {
        using Value = True;
    };

    /*************************************************
    Operator
    *************************************************/

    // Equal
    template <class T1, class T2>
    struct Equal {
        using Value = False;
    };

    template <class T>
    struct Equal < T, T > {
        using Value = True;
    };

    // Less Than
    template <class N1, class N2>
    struct LessThan {
        using Value = typename LessThan<typename N1::Pred, typename N2::Pred>::Value;
    };

    template <class N>
    struct LessThan < Zero, N > {
        using Value = True;
    };

    template <class N>
    struct LessThan < N, Zero > {
        using Value = False;
    };

    template <>
    struct LessThan < Zero, Zero > {
        using Value = False;
    };

    // Less Equal
    template <class N1, class N2>
    struct LessEqual {
        using Value = typename Or<typename Equal::Value, typename LessThan::Value>::Value;
    };

    // Greater Than
    template <class N1, class N2>
    struct GreaterThan {
        using Value = typename GreaterThan<typename N1::Pred, typename N2::Pred>::Value;
    };

    template <class N>
    struct GreaterThan < Zero, N > {
        using Value = False;
    };

    template <class N>
    struct GreaterThan < N, Zero > {
        using Value = True;
    };

    template <>
    struct GreaterThan < Zero, Zero > {
        using Value = False;
    };

    // Greater Equal
    template <class N1, class N2>
    struct GreaterEqual {
        using Value = typename Or<typename Equal::Value, typename GreaterThan::Value>::Value;
    };

    /*************************************************
    Statement
    *************************************************/

    // If
    template <class B, class S1, class S2>
    struct If;

    template <class S1, class S2>
    struct If < True, S1, S2 > {
        using Value = S1;
    };

    template <class S1, class S2>
    struct If < False, S1, S2 > {
        using Value = S2;
    };

    /*************************************************
                        Calculate
    *************************************************/

    // Add
    template <class N1, class N2>
    struct Add;

    template <class N>
    struct Add < Zero, N > {
        using Value = N;
    };

    template <class N1, class N2>
    struct Add < Succ, N2 > {
        using Value = typename Add>::Value;
    };

    // Mul
    template <class N1, class N2>
    struct Mul;

    template <class N>
    struct Mul < Zero, N > {
        using Value = Zero;
    };

    template <class N1, class N2>
    struct Mul < Succ, N2 > {
        using Value = typename Addtypename Mul::Value>::Value;
    };

    // Sub
    template <class N1, class N2>
    struct Sub {
        using Value = typename Sub<typename N1::Pred, typename N2::Pred>::Value;
    };

    template <class N>
    struct Sub < N, Zero > {
        using Value = N;
    };

    template <class N>
    struct Sub < Zero, N > {
        using Value = Zero;
    };

    template <>
    struct Sub < Zero, Zero > {
        using Value = Zero;
    };

    // Div
    template <class N1, class N2>
    struct Div {
        using Value = typename If<typename GreaterEqual::Value, Succ<typename Div<typename Sub::Value, N2>::Value>, Zero>::Value;
        using Rem = typename If<typename GreaterEqual::Value, typename Div<typename Sub::Value, N2>::Rem, N1>::Value;
    };

    template <class N>
    struct Div < Zero, N > {
        using Value = Zero;
        using Rem = Zero;
    };

    template <class N>
    struct Div < N, Zero > {
        using Value = Undefined;
        using Rem = Undefined;
    };

    // Number
    using i0 = Zero;
    using i1 = Succ < Zero > ;
    using i2 = Succ < i1 > ;
    using i3 = Succ < i2 > ;
    using i4 = Succ < i3 > ;
    using i5 = Succ < i4 > ;
    using i6 = Succ < i5 >;
    using i7 = Succ < i6 >;
    using i8 = Succ < i7 >;
    using i9 = Succ < i8 >;
    using i10 = Succ < i9 >;

    // Decimal
    /*
    template 
    struct Decimal_X {
        using Value = typename Decimal_X::Value, D>::Value, R...>::Value;
    };
    template 
    struct Decimal_X < N, D > {
        using Value = typename Add::Value, D>::Value;
    };

    template 
    struct Decimal {
        using Value = typename Decimal_X::Value;
    };
    */

    /*************************************************
                    Data Struct
    *************************************************/

    // Pair
    struct Nil { 
        using Length = Zero;
    };

    template<class First, class Rest>
    struct Pair { 
        using Head = First;
        using Tail = Rest;
        using Length = Succ < typename Rest::Length > ;
    };

    // Pair Head
    template <class Pair>
    struct Head;

    template <class H, class T>
    struct Head < Pair > {
        using Value = H;
    };

    // Pair Tail
    template <class Pair>
    struct Tail;

    template <class H, class T>
    struct Tail < Pair > {
        using Value = T;
    };

    // List
    template <class Head, class... Tail>
    struct List {
        using Value = Pair < Head, typename List::Value > ;
        using Length = typename Value::Length;
    };

    template<class Head>
    struct List < Head > {
        using Value = Pair < Head, Nil > ;
        using Length = i1;
    };

    // ListToDecimal
    template <class N, class List>
    struct ListToDecimal_X;

    template <class N, class H, class T>
    struct ListToDecimal_X < N, Pair > {
        using Value = typename ListToDecimal_X<typename Add<typename Mul::Value, H>::Value, T>::Value;
    };

    template <class N>
    struct ListToDecimal_X < N, Nil > {
        using Value = N;
    };

    template <class List>
    struct ListToDecimal {
        using Value = typename ListToDecimal_X::Value;
    };
    /*************************************************
                        Algorithm
    *************************************************/

    // List Length
    template <class List>
    struct Length;

    template <class H, class T>
    struct Length < Pair > {
        using Value = Succ < typename Length::Value > ;
    };

    template <>
    struct Length < Nil > {
        using Value = Zero;
    };

    // List Take
    template <class N, class List>
    struct Take {
        using Value = Pair < typename List::Head, typename Take<typename N::Pred, typename List::Tail>::Value > ;
        using Length = typename Value::Length;
    };

    template <class N>
    struct Take < N, Nil > {
        using Value = Nil;
        using Length = Zero;
    };

    template <class List>
    struct Take < Zero, List > {
        using Value = Nil;
        using Length = Zero;
    };

    // List Nth
    template <class N, class List>
    struct Nth;

    template <class H, class T, class N>
    struct Nth < Succ, Pair > {
        using Value = typename Nth::Value;
    };

    template <class N>
    struct Nth < N,Nil > {
        using Value = Nil;
    };

    template <class H, class T>
    struct Nth < Zero, Pair > {
        using Value = H;
    };

    // List Drop
    template <class N, class List>
    struct Drop;

    template <class N, class H, class T>
    struct Drop < Succ, Pair > {
        using Value = typename Drop::Value;
    };

    template <class List>
    struct Drop < Zero, List > {
        using Value = List;
    };

    template <class N>
    struct Drop < N, Nil > {
        using Value = Nil;
    };

    // List Concat
    template <class L1, class L2>
    struct Concat;

    template <class H, class T, class List>
    struct Concat < Pair, List > {
        using Value = Pair < H, typename Concat::Value > ;
    };

    template <class List>
    struct Concat < Nil, List > {
        using Value = List;
    };

    /*************************************************
                        Lambda
    *************************************************/

    template <template <class A> class F, class L>
    struct Map;

    template <template <class A> class F, class H, class T>
    struct Map < F, Pair > {
        using Value = Pair < typename F::Value, typename Map::Value > ;
    };

    template <template<class A> class F>
    struct Map < F, Nil > {
        using Value = Nil;
    };

    template <template <class A, class B> class F, class I, class L>
    struct FoldLeft {
        using Value = typename FoldLefttypename Ftypename L::Head>::Value, typename L::Tail>::Value;
    };

    template <template <class A, class B> class F, class I>
    struct FoldLeft < F, I, Nil > {
        using Value = I;
    };

    template <template <class A> class F, class L>
    struct Filter {
        using Value = typename If<typename F<typename L::Head>::Value, 
                                    Pair<typename L::Head, typename Filtertypename L::Tail>::Value>, 
                                    typename Filtertypename L::Tail>::Value>::Value;
    };

    template <template <class A> class F>
    struct Filter < F, Nil > {
        using Value = Nil;
    };

    /*************************************************
                        Function
    *************************************************/

    // Max
    template <class N1, class N2>
    struct Max {
        using Value = typename If<typename GreaterThan::Value, N1, N2>::Value;
    };

    // Min
    template <class N1, class N2>
    struct Min {
        using Value = typename If<typename LessThan::Value, N1, N2>::Value;
    };

    // Is_Odd
    template <class N>
    struct Is_Odd {
        using Value = typename Equal<typename Div::Rem, i1>::Value;
    };

    // Is_Even
    template <class N>
    struct Is_Even {
        using Value = typename Equal<typename Div::Rem, i0>::Value;
    };

    // Is_Integer
    template <class N>
    struct Is_Integer {
        using Value = False;
    };

    template <class N>
    struct Is_Integer < Succ > {
        using Value = True;
    };

    template <>
    struct Is_Integer < Zero > {
        using Value = True;
    };

    // Is_Boolean
    template <class B>
    struct Is_Boolean {
        using Value = False;
    };

    template <>
    struct Is_Boolean < True > {
        using Value = True;
    };

    template <>
    struct Is_Boolean < False > {
        using Value = True;
    };

    // Is_Nil
    template <class X>
    struct Is_Nil {
        using Value = False;
    };

    template <>
    struct Is_Nil < Nil > {
        using Value = True;
    };

    // Is_Pair
    template <class P>
    struct Is_Pair {
        using Value = False;
    };
    template <class X, class Y>
    struct Is_Pair < Pair > {
        using Value = True;
    };

    /*************************************************
                        Test Tool
    *************************************************/

    // Assert
    template <class E>
    struct Assert {
        inline static void True() { throw 0; }
    };

    template <>
    struct Assert < True > {
        inline static void True() {}
    };

    // Integer
    template <class N>
    struct Integer {
        const static int ToInt = -65536;
    };

    template <>
    struct Integer < Zero > {
        const static int ToInt = 0;
    };

    template <class N>
    struct Integer < Succ > {
        const static int ToInt = Integer::ToInt + 1;
    };

    // Boolean
    template <class B>
    struct Boolean {
        const static bool ToBool = false;
    };

    template <>
    struct Boolean < True > {
        const static bool ToBool = true;
    };

    template <>
    struct Boolean < False > {
        const static bool ToBool = false;
    };

    // Display Integer
    template <class N>
    struct DisplayInteger {
        inline static void Display() {
            std::cout << Integer::ToInt << std::endl;
        }
    };

    // Display Boolean
    template <class B>
    struct DisplayBoolean {
        inline static void Display() {
            if (Boolean::ToBool) std::cout << "true" << std::endl;
            else std::cout << "false" << std::endl;
        }
    };

    // Display List
    template <class P>
    struct DisplayList;

    template <class H, class T>
    struct DisplayList < Pair > {
        inline static void Display() {
            if (Is_Integer::Value::ToBool) {
                std::cout << Integer::ToInt << " ";
            }
            else if (Is_Boolean::Value::ToBool) {
                if (Boolean::ToBool) std::cout << "true ";
                else std::cout << "false ";
            }
            DisplayList::Display();
        }
    };

    template <>
    struct DisplayList < Nil > {
        inline static void Display() {
            std::cout << std::endl;
        }
    };

}

    cout << "[Pred 2]                                    " << Integer<i2::Pred>::ToInt << endl;
    cout << "[Pred 3]                                    " << Integer<Pred<i3>::Value>::ToInt << endl;
    cout << "[And True False]                            " << Boolean<And<True, False>::Value>::ToBool << endl;
    cout << "[Or False False]                            " << Boolean<Or<False, False>::Value>::ToBool << endl;
    cout << "[If True 1+2 3+4]                           " << Integer<If<True, Add<i1, i2>::Value, Add<i3, i4>::Value>::Value>::ToInt << endl;
    cout << "[LessThan 1 2]                              " << Boolean<LessThan<i1, i2>::Value>::ToBool << endl;
    cout << "[GreaterThan 2 1]                           " << Boolean<GreaterThan<i2, i1>::Value>::ToBool << endl;
    cout << "[If (LessThan 1 2) 1 2]                     " << Integer<If<LessThan<i1, i2>::Value, i1, i2>::Value>::ToInt << endl;
    cout << endl;

    cout << "[Length (List 1 2 3 4 5)]                   " << Integer<Length<List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
    cout << "[Head (Pair 3 6)]                           " << Integer<Head<Pair<i3, i6>>::Value>::ToInt << endl;
    cout << "[Tail (Pair 3 6)]                           " << Integer<Tail<Pair<i3, i6>>::Value>::ToInt << endl;
    cout << "[Head (List 1 2 3 4 5)]                     " << Integer<Head<List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
    cout << endl;

    cout << "[take 1 (list 1 2 3 4 5)]                   " << Integer<Take<i1, List<i1, i2, i3, i4, i5>::Value>::Value::Length>::ToInt << endl;
    cout << "[Nth 3 (List 1 2 3 4 5)]                    " << Integer<Nth<i3, List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
    cout << "[Head (Drop 2 (List 1 2 3 4 5))]            " << Integer<Head<Drop<i2, List<i1, i2, i3, i4, i5>::Value>::Value>::Value>::ToInt << endl;
    cout << "[Nth 2 (Concat (List 1 2) (List 3 4)]       " << Integer<Nth<i2, Concat<List<i1, i2>::Value, List<i3, i4>::Value>::Value>::Value>::ToInt << endl;
    cout << "[Nth 2 (Map F (List 1 2 3))]                " << Integer<Nth<i2, Map<F, List<i1, i2, i3>::Value>::Value>::Value>::ToInt << endl;
    cout << endl;

    cout << "[LessThan 1 3]                              " << Boolean<LessThan<i1, i3>::Value>::ToBool << endl;
    cout << "[LessEqual 2 2]                             " << Boolean<LessEqual<i2, i2>::Value>::ToBool << endl;
    cout << "[GreaterThan 1 3]                           " << Boolean<GreaterThan<i1, i3>::Value>::ToBool << endl;
    cout << "[GreaterEqual 3 1]                          " << Boolean<GreaterEqual<i3, i1>::Value>::ToBool << endl;
    cout << "[GreaterEqual 1 2]                          " << Boolean<GreaterEqual<i1, i2>::Value>::ToBool << endl;
    cout << "[GreaterThan 1 2]                           " << Boolean<GreaterThan<i1, i2>::Value>::ToBool << endl;
    cout << "[Equal 1 2]                                 " << Boolean<Equal<i1, i2>::Value>::ToBool << endl;
    cout << "[greaterEqual 1 2]                          " << Boolean<GreaterEqual<i1, i2>::Value>::ToBool << endl;
    cout << "[Or (GreatThan 1 2) (Equal 1 2)]            " << Boolean<Or<GreaterThan<i1, i2>::Value, Equal<i1, i2>::Value>::Value>::ToBool << endl;
    cout << endl;

    cout << "[Add 4 7]                                   " << Integer<Add<i4, i7>::Value>::ToInt << endl;
    cout << "[Sub 4 7]                                   " << Integer<Sub<i4, i7>::Value>::ToInt << endl;
    cout << "[Sub 7 4]                                   " << Integer<Sub<i7, i4>::Value>::ToInt << endl;
    cout << "[Div 8 3]                                   " << Integer<Div<i8, i3>::Value>::ToInt << endl;
    cout << endl;

    cout << "[FoldLeft Add 0 (list 1 2 3 4 5)]           " << Integer<FoldLeft<Add, i0, List<i1, i2, i3, i4, i5>::Value>::Value>::ToInt << endl;
    cout << "[Length (Filter Is_Odd (List 1 2 3 4 5))]   " << Integer<Length<Filter<Is_Odd, List<i1, i2, i3, i4, i5>::Value>::Value>::Value>::ToInt << endl;
    DisplayList<List<i1, True, i3, i4, i5>::Value>::Display();
    cout << endl;

    DisplayInteger<ListToDecimal<List<i2, i2, i3>::Value>::Value>::Display();

你可能感兴趣的:(C++)