Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef JNP1_ZAD4_FIBIN_H
- #define JNP1_ZAD4_FIBIN_H
- #include <type_traits>
- #include <cassert>
- // Obsługa Var - konwertuje char* w jednoznaczny napis, sprawdza czy spełnia założenia zadania.
- #define VarType unsigned long long
- static constexpr unsigned long long valueOfChar(const char a) {
- return ('0' <= a && a <= '9') ? a - '0' + 1
- : ('a' <= a && a <= 'z') ? a - 'a' + 11 : a - 'A' + 11;
- }
- static constexpr bool correctName(const char* str) {
- int i = 0;
- for (; str[i] != '\0'; i++) {
- if (('0' <= str[i] && str[i] <= '9') || ('a' <= str[i] && str[i] <= 'z') || ('A' <= str[i] && str[i] <= 'Z')) {
- return false;
- }
- }
- return (0 < i && i < 7);
- }
- static constexpr VarType Var(const char* str) {
- //assert(correctName(str));
- unsigned long long res = 0;
- for (int i = 0; str[i] != '\0'; i++) {
- res = res * 100 + valueOfChar(str[i]);
- }
- return res;
- }
- // Do obsługi typów liczbowych.
- template <unsigned long long x>
- struct Numeric {
- static constexpr unsigned long long value = x;
- };
- // Typy boolowskie(True, False).
- struct True {
- };
- struct False {
- };
- // Fib, przyjmujący jako agrument liczbę.
- template <int>
- struct Fib {
- };
- // Literał Lit.
- template <typename>
- struct Lit {
- };
- // Wyrażenie If.
- template <typename, typename, typename>
- struct If {
- };
- // Wyrażenie Let.
- template <VarType Variable, typename Value, typename Expression>
- struct Let {
- };
- // Odwołanie do zmiennej Ref.
- template <VarType Variable>
- struct Ref {
- };
- // Porównanie Eq.
- template <typename, typename>
- struct Eq;
- // Wyrażenie Lambda.
- template <VarType Variable, typename Body>
- struct Lambda {
- };
- // Wywołanie funkcji Invoke.
- template <typename fun, typename Param>
- struct Invoke {
- };
- // Obliczanie literałów Fib.
- template <>
- struct Lit<True> {
- };
- template <>
- struct Lit<False> {
- };
- template <int N>
- struct Lit<Fib<N> > {
- Numeric<Lit<Fib<N - 1> >::result::value + Lit<Fib<N - 2> >::result::value> typedef result;
- };
- template <>
- struct Lit<Fib<0> > {
- Numeric<0> typedef result;
- };
- template <>
- struct Lit<Fib<1> > {
- Numeric<1> typedef result;
- };
- // Operacje arytmetyczne.
- template <typename T>
- struct Inc1 {
- };
- template <typename T>
- struct Inc10 {
- };
- // Sum<Args...> - suma argumentów Sum
- template <typename...>
- struct Sum {
- };
- // Tworzenie Enviroment - przetrzymuje zmienne od ich nazw, oblicza się w czasie kompilacji.
- struct EmptyEnvironment {
- };
- template <VarType Variable, typename Val, typename NextEnv>
- struct Environment {
- };
- template <VarType Variable, typename Env>
- struct GetEnv {
- };
- template <VarType Variable>
- struct GetEnv<Variable, EmptyEnvironment> {
- };
- template <VarType Variable, typename Value, typename NextEnv>
- struct GetEnv<Variable, Environment<Variable, Value, NextEnv> > {
- Value typedef result;
- };
- template <VarType Variable, VarType Variable2, typename Value2, typename NextEnv>
- struct GetEnv<Variable, Environment<Variable2, Value2, NextEnv> > {
- typename GetEnv<Variable, NextEnv>::result typedef result;
- };
- // Funkcje pomocnicze do Evaluate.
- template <bool>
- struct BoolToLit {
- Lit<False> typedef result;
- };
- template <>
- struct BoolToLit<true> {
- Lit<True> typedef result;
- };
- // Evaluate - obliczane w zależności od zawartości.
- template <typename Expression, typename Environment>
- struct Evaluate {
- Expression typedef result;
- };
- template <int N, typename Environment>
- struct Evaluate<Lit<Fib<N> >, Environment> {
- typename Lit<Fib<N> >::result typedef result;
- };
- template <typename Val, typename Environment>
- struct Evaluate<Inc1<Val>, Environment> {
- Numeric<Evaluate<Val, Environment>::result::value + Lit<Fib<1> >::result::value> typedef result;
- };
- template <typename Val, typename Environment>
- struct Evaluate<Inc10<Val>, Environment> {
- Numeric<Evaluate<Val, Environment>::result::value + Lit<Fib<10> >::result::value> typedef result;
- };
- template <typename Arg, typename Env>
- struct Evaluate<Sum<Arg>, Env> {
- Numeric<Evaluate<Arg, Env>::result::value> typedef result;
- };
- template <typename Arg1, typename Arg2, typename... Args, typename Env>
- struct Evaluate<Sum<Arg1, Arg2, Args...>, Env> {
- Numeric<Evaluate<Arg1,Env>::result::value + Evaluate<Sum<Arg2, Args...>, Env>::result::value> typedef result;
- };
- template <VarType Variable, typename Environment>
- struct Evaluate<Ref<Variable>, Environment> {
- typename GetEnv<Variable, Environment>::result typedef result;
- };
- template <typename Then, typename Else, typename Env>
- struct Evaluate<If<Lit<True>, Then, Else>, Env> {
- typename Then::result typedef result;
- };
- template <typename Then, typename Else, typename Env>
- struct Evaluate<If<Lit<False>, Then, Else>, Env> {
- typename Evaluate<Else, Env>::result typedef result;
- };
- template <typename Condition, typename Then, typename Else, typename Env>
- struct Evaluate<If<Condition, Then, Else>, Env> {
- typename Evaluate<If<typename Evaluate<Condition, Env>::result, Then, Else>, Env>::result typedef result;
- };
- template <VarType Variable, typename Value, typename Expression, typename Env>
- struct Evaluate<Let<Variable, Value, Expression>, Env> {
- typename Evaluate<Expression, Environment<Variable, typename Evaluate<Value,Env>::result, Env> >::result typedef result;
- };
- template <typename LeftVal, typename RightVal, typename Env>
- struct Evaluate<Eq<LeftVal, RightVal>, Env> {
- typename Evaluate<Eq<typename Evaluate<LeftVal, Env>::result, typename Evaluate<RightVal, Env>::result>, Env>::result typedef result;
- };
- template <unsigned long long x, unsigned long long y, typename Env>
- struct Evaluate<Eq<Numeric<x>, Numeric<y> >, Env> {
- typename BoolToLit<x == y>::result typedef result;
- };
- // std::cout <<Fibin<int>::eval<Invoke<Lambda<Var("x"), Ref<Var("x")>>, Lit<Fib<0>>>>() << "\n";
- template <typename fun, VarType Variable, typename Value, typename Env>
- struct Evaluate<Invoke<Lambda<Variable, fun>, Value>, Env> {
- typename Evaluate<Let<Variable, fun, Evaluate<Value,Env>>, Env>::result typedef result;
- };
- // Klasa Fibin.
- template <typename T, bool = std::is_integral<T>::value>
- class Fibin {
- public:
- template <typename Expr>
- static void eval() {
- std::cout << "Fibin doesn't support: " << typeid(T).name() << '\n';
- return;
- }
- };
- template <typename T>
- class Fibin<T, true> {
- public:
- template <typename Expr>
- static T eval() {
- return Evaluate<Expr, EmptyEnvironment>::result::value;
- }
- };
- #endif //JNP1_ZAD4_FIBIN_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement