diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 0c9e0be..732aa7e 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -450,7 +450,6 @@ namespace chaiscript Dispatch_Engine(chaiscript::parser::ChaiScript_Parser_Base &parser) : m_stack_holder(this), m_parser(parser) - { } @@ -1498,7 +1497,7 @@ namespace chaiscript chaiscript::detail::threading::Thread_Storage m_stack_holder; std::reference_wrapper m_parser; - mutable std::atomic_uint_fast32_t m_method_missing_loc; + mutable std::atomic_uint_fast32_t m_method_missing_loc = {0}; State m_state; }; diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index fb850c8..ea42206 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -64,7 +64,9 @@ namespace chaiscript Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled }; - enum class Operator_Precidence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication }; + enum class Operator_Precidence { Ternary_Cond, Logical_Or, + Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, + Equality, Comparison, Shift, Addition, Multiplication, Prefix }; namespace { diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index b3c9280..4ad24bb 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -86,8 +86,6 @@ namespace chaiscript } } - - template struct AST_Node_Impl : AST_Node { @@ -147,8 +145,7 @@ namespace chaiscript Fold_Right_Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children, Boxed_Value t_rhs) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), m_oper(Operators::to_operator(t_oper)), - m_rhs(std::move(t_rhs)), - m_loc(0) + m_rhs(std::move(t_rhs)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -184,7 +181,7 @@ namespace chaiscript private: Operators::Opers m_oper; Boxed_Value m_rhs; - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; @@ -192,8 +189,7 @@ namespace chaiscript struct Binary_Operator_AST_Node : AST_Node_Impl { Binary_Operator_AST_Node(const std::string &t_oper, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(t_oper, AST_Node_Type::Binary, std::move(t_loc), std::move(t_children)), - m_oper(Operators::to_operator(t_oper)), - m_loc(0) + m_oper(Operators::to_operator(t_oper)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -230,7 +226,7 @@ namespace chaiscript private: Operators::Opers m_oper; - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; @@ -258,8 +254,7 @@ namespace chaiscript template struct Id_AST_Node final : AST_Node_Impl { Id_AST_Node(const std::string &t_ast_node_text, Parse_Location t_loc) : - AST_Node_Impl(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)), - m_loc(0) + AST_Node_Impl(t_ast_node_text, AST_Node_Type::Id, std::move(t_loc)) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -272,7 +267,7 @@ namespace chaiscript } private: - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; @@ -514,8 +509,8 @@ namespace chaiscript private: Operators::Opers m_oper; - mutable std::atomic_uint_fast32_t m_loc; - mutable std::atomic_uint_fast32_t m_clone_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; + mutable std::atomic_uint_fast32_t m_clone_loc = {0}; }; template @@ -579,7 +574,7 @@ namespace chaiscript private: - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template @@ -635,8 +630,8 @@ namespace chaiscript } private: - mutable std::atomic_uint_fast32_t m_loc; - mutable std::atomic_uint_fast32_t m_array_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; + mutable std::atomic_uint_fast32_t m_array_loc = {0}; const std::string m_fun_name; }; @@ -850,11 +845,7 @@ namespace chaiscript template struct Ranged_For_AST_Node final : AST_Node_Impl { Ranged_For_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : - AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Ranged_For, std::move(t_loc), std::move(t_children)), - m_range_loc(0), - m_empty_loc(0), - m_front_loc(0), - m_pop_front_loc(0) + AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Ranged_For, std::move(t_loc), std::move(t_children)) { assert(this->children.size() == 3); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ @@ -921,12 +912,11 @@ namespace chaiscript } -private: - mutable std::atomic_uint_fast32_t m_range_loc; - mutable std::atomic_uint_fast32_t m_empty_loc; - mutable std::atomic_uint_fast32_t m_front_loc; - mutable std::atomic_uint_fast32_t m_pop_front_loc; - + private: + mutable std::atomic_uint_fast32_t m_range_loc = {0}; + mutable std::atomic_uint_fast32_t m_empty_loc = {0}; + mutable std::atomic_uint_fast32_t m_front_loc = {0}; + mutable std::atomic_uint_fast32_t m_pop_front_loc = {0}; }; @@ -1004,7 +994,7 @@ private: return void_var(); } - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template @@ -1065,7 +1055,7 @@ private: } private: - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template @@ -1073,7 +1063,8 @@ private: Inline_Map_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Inline_Map, std::move(t_loc), std::move(t_children)) { } - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override + { try { std::map retval; @@ -1094,7 +1085,7 @@ private: } private: - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template @@ -1176,8 +1167,8 @@ private: } private: - Operators::Opers m_oper; - mutable std::atomic_uint_fast32_t m_loc; + Operators::Opers m_oper = Operators::Opers::invalid; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template @@ -1243,7 +1234,7 @@ private: } private: - mutable std::atomic_uint_fast32_t m_loc; + mutable std::atomic_uint_fast32_t m_loc = {0}; }; template diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index b8f23bd..2b384c6 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -199,15 +199,16 @@ namespace chaiscript {"<<", ">>"}, //We share precedence here but then separate them later {"+", "-"}, - {"*", "/", "%"} + {"*", "/", "%"}, + {"++", "--", "-", "+", "!", "~"} }; return operator_matches; } - static const std::array &create_operators() { - static const std::array operators = { { + static const std::array &create_operators() { + static const std::array operators = { { Operator_Precidence::Ternary_Cond, Operator_Precidence::Logical_Or, Operator_Precidence::Logical_And, @@ -218,7 +219,8 @@ namespace chaiscript Operator_Precidence::Comparison, Operator_Precidence::Shift, Operator_Precidence::Addition, - Operator_Precidence::Multiplication + Operator_Precidence::Multiplication, + Operator_Precidence::Prefix } }; return operators; } @@ -230,7 +232,7 @@ namespace chaiscript const std::array, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::vector> &m_operator_matches = create_operator_matches(); - const std::array &m_operators = create_operators(); + const std::array &m_operators = create_operators(); std::shared_ptr m_filename; std::vector> m_match_stack; @@ -358,7 +360,6 @@ namespace chaiscript ChaiScript_Parser(ChaiScript_Parser &&) = default; ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; - /// test a char in an m_alphabet bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast(c)]; } @@ -2175,15 +2176,15 @@ namespace chaiscript /// Reads a unary prefixed expression from input bool Prefix() { const auto prev_stack_top = m_match_stack.size(); - const std::vector prefix_opers{"++", "--", "-", "+", "!", "~", "&"}; + constexpr const std::array prefix_opers{"++", "--", "-", "+", "!", "~"}; for (const auto &oper : prefix_opers) { - bool is_char = oper.size() == 1; - if ((is_char && Char(oper[0])) || (!is_char && Symbol(oper.c_str()))) + bool is_char = strlen(oper) == 1; + if ((is_char && Char(oper[0])) || (!is_char && Symbol(oper))) { if (!Operator(m_operators.size()-1)) { - throw exception::eval_error("Incomplete prefix '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); + throw exception::eval_error("Incomplete prefix '" + std::string(oper) + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } build_match>(prev_stack_top, oper); @@ -2213,7 +2214,7 @@ namespace chaiscript bool retval = false; const auto prev_stack_top = m_match_stack.size(); - if (t_precedence < m_operators.size()) { + if (m_operators[t_precedence] != Operator_Precidence::Prefix) { if (Operator(t_precedence+1)) { retval = true; std::string oper; @@ -2256,14 +2257,16 @@ namespace chaiscript case(Operator_Precidence::Logical_Or) : build_match>(prev_stack_top, oper); break; + case(Operator_Precidence::Prefix) : + assert(false); // cannot reach here because of if() statement at the top + break; // default: // throw exception::eval_error("Internal error: unhandled ast_node", File_Position(m_position.line, m_position.col), *m_filename); } } } - } - else { + } else { return Value(); } diff --git a/releasenotes.md b/releasenotes.md index 551e82f..b433579 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -2,7 +2,7 @@ Notes: ======= Current Version: 6.0.0 -### Changes since 5.8.3 +### Changes since 5.8.5 *6.0.0 is a massive rework compared to 5.x. It now requires a C++14 enabled compiler* @@ -38,6 +38,10 @@ Current Version: 6.0.0 * File location tracking has been rewritten; this currently means error location reporting is not as good as it was * Tracing capability needs to be tested and vetted +### Changes since 5.8.4 +* Fix order of operations for prefix operators +* Make sure atomics are initialized properly + ### Changes since 5.8.3 * Fix case with some numeric conversions mixed with numerics that do not need conversion diff --git a/unittests/compiled_tests.cpp b/unittests/compiled_tests.cpp index ff0e323..f9ce4cf 100644 --- a/unittests/compiled_tests.cpp +++ b/unittests/compiled_tests.cpp @@ -960,7 +960,7 @@ bool FindBitmap(int &ox, int &oy, long) { TEST_CASE("Mismatched numeric types only convert necessary params") { - chaiscript::ChaiScript chai; + chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); chai.add(chaiscript::fun(&FindBitmap), "FindBitmap"); int x = 0; @@ -973,3 +973,13 @@ TEST_CASE("Mismatched numeric types only convert necessary params") } +TEST_CASE("type_conversion to bool") +{ + auto module = std::make_shared(); + struct T { + operator bool() const { return true; } + }; + module->add(chaiscript::type_conversion()); +} + + diff --git a/unittests/multithreaded_test.cpp b/unittests/multithreaded_test.cpp index 990bf7e..ff06620 100644 --- a/unittests/multithreaded_test.cpp +++ b/unittests/multithreaded_test.cpp @@ -16,7 +16,7 @@ int expected_value(int num_iters) return i; } -void do_work(chaiscript::ChaiScript &c, const size_t id) +void do_work(chaiscript::ChaiScript_Basic &c, const size_t id) { try{ std::stringstream ss; diff --git a/unittests/precedence_4.chai b/unittests/precedence_4.chai new file mode 100644 index 0000000..b55c83d --- /dev/null +++ b/unittests/precedence_4.chai @@ -0,0 +1,4 @@ + +var i = 2; + +assert_equal(++i * i, 9)