// // Pixie C++ typer // // This code (when compiled) will emit EDN data for a given C++ type. This includes C functions // So calling this: // PixieChecker::DumpType() // will emit this in the compiled program: // {:type :function :arity 1 :returns {:type :float :size 8} :arguments [{:type :pointer :of-type {:type :int :size 1 :signed? true}} ]} #include #include "boost/type_traits.hpp" namespace PixieChecker { template std::string GetType(); template struct GenericChecker; template < typename T > std::string to_string( const T& n ) { std::ostringstream stm ; stm << n ; return stm.str() ; } // Function Checker template struct FunctionTyper { static std::string getType() { return "{:type :function :arity :unknown}"; } }; template struct FunctionTyper<0, T> { static std::string getType() { return "{:type :function :arity 0 :returns " + GetType::result_type>() + " :arguments []}"; } }; template struct FunctionTyper<1, T> { static std::string getType() { return "{:type :function :arity 1 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + " ]}"; } }; template struct FunctionTyper<2, T> { static std::string getType() { return "{:type :function :arity 2 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + " ]}"; } }; template struct FunctionTyper<3, T> { static std::string getType() { return "{:type :function :arity 3 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + " ]}"; } }; template struct FunctionTyper<4, T> { static std::string getType() { return "{:type :function :arity 4 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + " ]}"; } }; template struct FunctionTyper<5, T> { static std::string getType() { return "{:type :function :arity 5 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + " ]}"; } }; template struct FunctionTyper<6, T> { static std::string getType() { return "{:type :function :arity 6 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + GetType::arg6_type>() + " " + " ]}"; } }; template struct FunctionTyper<7, T> { static std::string getType() { return "{:type :function :arity 7 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + GetType::arg6_type>() + " " + GetType::arg7_type>() + " " + " ]}"; } }; template struct FunctionTyper<8, T> { static std::string getType() { return "{:type :function :arity 8 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + GetType::arg6_type>() + " " + GetType::arg7_type>() + " " + GetType::arg8_type>() + " " + " ]}"; } }; template struct FunctionTyper<9, T> { static std::string getType() { return "{:type :function :arity 9 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + GetType::arg6_type>() + " " + GetType::arg7_type>() + " " + GetType::arg8_type>() + " " + GetType::arg9_type>() + " " + " ]}"; } }; template struct FunctionTyper<10, T> { static std::string getType() { return "{:type :function :arity 10 :returns " + GetType::result_type>() + " :arguments [" + GetType::arg1_type>() + " " + GetType::arg2_type>() + " " + GetType::arg3_type>() + " " + GetType::arg4_type>() + " " + GetType::arg5_type>() + " " + GetType::arg6_type>() + " " + GetType::arg7_type>() + " " + GetType::arg8_type>() + " " + GetType::arg9_type>() + " " + GetType::arg10_type>() + " " + " ]}"; } }; // End Function Typer // Is Enum template struct GenericCheckerIsEnum { static std::string getType() { return "Shouldn't happen in enum checker"; } }; template struct GenericCheckerIsEnum { static std::string getType() { return GetType(); } }; template struct GenericCheckerIsEnum { static std::string getType() { return "{:type :unknown}"; } }; // End Is Enum // Is Void template struct GenericCheckerIsVoid { static std::string getType() { return "Shouldn't happen in void checker"; } }; template struct GenericCheckerIsVoid { static std::string getType() { return "{:type :void}"; } }; template struct GenericCheckerIsVoid { static std::string getType() { return GenericCheckerIsEnum::type, T>::getType(); } }; // End Is Void // Is Pointer template struct GenericCheckerIsPointer { static std::string getType() { return "Shouldn't happen in pointer checker"; } }; template struct GenericCheckerIsPointer { static std::string getType() { return "{:type :pointer :of-type " + GetType::type>() + "}"; } }; template struct GenericCheckerIsPointer { static std::string getType() { return GenericCheckerIsVoid::type, T>::getType(); } }; // End Is Pointer // Is Function template struct GenericCheckerIsFunction { static std::string getType() { return "Shouldn't happen in function checker"; } }; template struct GenericCheckerIsFunction { static std::string getType() { return FunctionTyper::arity, T>::getType(); } }; template struct GenericCheckerIsFunction { static std::string getType() { return GenericCheckerIsPointer::type, T>::getType(); } }; // End Is Function // Is Float template struct GenericCheckerIsFloat { static std::string getType() { throw 42; } }; template struct GenericCheckerIsFloat { static std::string getType() { return "{:type :float :size " + to_string(sizeof(T)) + "}"; } }; template struct GenericCheckerIsFloat { static std::string getType() { return GenericCheckerIsFunction::type, T>::getType(); } }; // End is Float // IsInt template struct GenericCheckerIsInt { static std::string getType() { return "Shouldn't happen"; } }; template struct GenericCheckerIsInt { static std::string getType() { return "{:type :int :size " + to_string(sizeof(T)) + " :signed? " + (boost::is_signed::value ? "true" : "false") + "}"; } }; template struct GenericCheckerIsInt { static std::string getType() { return GenericCheckerIsFloat::type, T>::getType(); } }; // End is Int // Generic Typer template std::string GetType() { return GenericCheckerIsInt::type, T>::getType(); } // End Generic Typer template void DumpValue(T t) { std::cout << GetType() << std::endl; } template void DumpType() { std::cout << GetType() << std::endl; } }