diff --git a/CMakeLists.txt b/CMakeLists.txt index a8187a8..60715b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,6 +220,10 @@ if(BUILD_TESTING) target_link_libraries(c_linkage_test ${LIBS}) add_test(NAME C_Linkage_Test COMMAND c_linkage_test) + add_executable(integer_literal_test unittests/integer_literal_test.cpp) + target_link_libraries(integer_literal_test ${LIBS}) + add_test(NAME Integer_Literal_Test COMMAND integer_literal_test) + if (MULTITHREAD_SUPPORT_ENABLED) add_executable(multithreaded_test unittests/multithreaded_test.cpp) target_link_libraries(multithreaded_test ${LIBS}) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 0621a7f..7850a00 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -104,7 +104,7 @@ namespace chaiscript Int_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Int, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(int(atoi(t_ast_node_text.c_str())))) { } - Int_AST_Node(const std::string &t_ast_node_text = "", const Boxed_Value &t_bv = const_var(0), int t_id = AST_Node_Type::Int, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Int_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, int t_id = AST_Node_Type::Int, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(t_bv) { } virtual ~Int_AST_Node() {} @@ -122,7 +122,7 @@ namespace chaiscript Float_AST_Node(const std::string &t_ast_node_text = "", int t_id = AST_Node_Type::Float, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(const_var(double(atof(t_ast_node_text.c_str())))) { } - Float_AST_Node(const std::string &t_ast_node_text = "", const Boxed_Value &t_bv = const_var(0), int t_id = AST_Node_Type::Float, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : + Float_AST_Node(const std::string &t_ast_node_text, const Boxed_Value &t_bv, int t_id = AST_Node_Type::Float, const std::shared_ptr &t_fname=std::shared_ptr(), int t_start_line = 0, int t_start_col = 0, int t_end_line = 0, int t_end_col = 0) : AST_Node(t_ast_node_text, t_id, t_fname, t_start_line, t_start_col, t_end_line, t_end_col), m_value(t_bv) { } virtual ~Float_AST_Node() {} diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 8f5c2b3..37698d2 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -490,6 +490,8 @@ namespace chaiscript } } + + template Boxed_Value buildInt(const IntType &t_type, const std::string &t_val) { @@ -521,6 +523,57 @@ namespace chaiscript std::stringstream ss(t_val.substr(0, i)); ss >> t_type; + std::stringstream testu(t_val.substr(0, i)); + uint64_t u; + testu >> t_type >> u; + + bool unsignedrequired = false; + size_t size = sizeof(int) * 8; + + if ((u >> (sizeof(int) * 8)) > 0) + { + //requires something bigger than int + long_ = true; + } + + static_assert(sizeof(long) == sizeof(uint64_t) || sizeof(long) * 2 == sizeof(uint64_t), "Unexpected sizing of integer types"); + + if ((sizeof(long) < sizeof(uint64_t)) + && (u >> ((sizeof(uint64_t) - sizeof(long)) * 8)) > 0) + { + //requires something bigger than long + longlong_ = true; + } + + if (longlong_) + { + size = sizeof(int64_t) * 8; + } else if (long_) { + size = sizeof(long) * 8; + } + + if ( (u >> (size - 1)) > 0) + { + unsignedrequired = true; + } + + if (unsignedrequired && !unsigned_) + { + if (t_type == std::hex || t_type == std::oct) + { + // with hex and octal we are happy to just make it unsigned + unsigned_ = true; + } else { + // with decimal we must bump it up to the next size + if (long_) + { + longlong_ = true; + } else if (!long_ && !longlong_) { + long_ = true; + } + } + } + if (unsigned_) { if (longlong_) diff --git a/unittests/integer_literal_test.cpp b/unittests/integer_literal_test.cpp new file mode 100644 index 0000000..85efe06 --- /dev/null +++ b/unittests/integer_literal_test.cpp @@ -0,0 +1,90 @@ +// Tests to make sure that the order in which function dispatches occur is correct + +#include + +#define TEST_LITERAL(v) test_literal(v, #v) + +template +bool test_literal(T val, const std::string &str) +{ + chaiscript::ChaiScript chai; + T val2 = chai.eval(str); + std::cout << "Comparing : " << val << " " << val2 << std::endl; + return val == val2; +} + +int main() +{ + if( TEST_LITERAL(0xF) + && TEST_LITERAL(0xFF) + && TEST_LITERAL(0xFFF) + && TEST_LITERAL(0xFFFF) + && TEST_LITERAL(0xFFFFF) + && TEST_LITERAL(0xFFFFFF) + && TEST_LITERAL(0xFFFFFFF) + && TEST_LITERAL(0xFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFFFFFF) + && TEST_LITERAL(0xFFFFFFFFFFFFFFFF) + + + && TEST_LITERAL(01) + && TEST_LITERAL(017) + && TEST_LITERAL(0177) + && TEST_LITERAL(01777) + && TEST_LITERAL(017777) + && TEST_LITERAL(0177777) + && TEST_LITERAL(01777777) + && TEST_LITERAL(017777777) + && TEST_LITERAL(0177777777) + && TEST_LITERAL(01777777777) + && TEST_LITERAL(017777777777) + && TEST_LITERAL(0177777777777) + && TEST_LITERAL(01777777777777) + && TEST_LITERAL(017777777777777) + && TEST_LITERAL(0177777777777777) + && TEST_LITERAL(01777777777777777) + && TEST_LITERAL(017777777777777777) + && TEST_LITERAL(0177777777777777777) + && TEST_LITERAL(01777777777777777777) + && TEST_LITERAL(017777777777777777777) + && TEST_LITERAL(0177777777777777777777) + && TEST_LITERAL(01777777777777777777777) + + && TEST_LITERAL(1) + && TEST_LITERAL(17) + && TEST_LITERAL(177) + && TEST_LITERAL(1777) + && TEST_LITERAL(17777) + && TEST_LITERAL(177777) + && TEST_LITERAL(1777777) + && TEST_LITERAL(17777777) + && TEST_LITERAL(177777777) + && TEST_LITERAL(1777777777) + && TEST_LITERAL(17777777777) + && TEST_LITERAL(177777777777) + && TEST_LITERAL(1777777777777) + && TEST_LITERAL(17777777777777) + && TEST_LITERAL(177777777777777) + && TEST_LITERAL(1777777777777777) + && TEST_LITERAL(17777777777777777) + && TEST_LITERAL(177777777777777777) + && TEST_LITERAL(1777777777777777777) + +) + { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } + + + + + +}