diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 81a2b810..047124ce 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -107,8 +107,7 @@ namespace chaiscript { Compiled, Const_Var_Decl, Const_Assign_Decl, - Enum, - Enum_Access + Enum }; enum class Operator_Precedence { @@ -129,7 +128,7 @@ namespace chaiscript { namespace { /// Helper lookup to get the name of each node type constexpr const char *ast_node_type_to_string(AST_Node_Type ast_node_type) noexcept { - constexpr const char *const ast_node_types[] = {"Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Assign_Decl", "Array_Call", "Dot_Access", "Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Noop", "Class", "Binary", "Arg", "Global_Decl", "Constant", "Compiled", "Const_Var_Decl", "Const_Assign_Decl", "Enum", "Enum_Access"}; + constexpr const char *const ast_node_types[] = {"Id", "Fun_Call", "Unused_Return_Fun_Call", "Arg_List", "Equation", "Var_Decl", "Assign_Decl", "Array_Call", "Dot_Access", "Lambda", "Block", "Scopeless_Block", "Def", "While", "If", "For", "Ranged_For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Noop", "Class", "Binary", "Arg", "Global_Decl", "Constant", "Compiled", "Const_Var_Decl", "Const_Assign_Decl", "Enum"}; return ast_node_types[static_cast(ast_node_type)]; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 9159af8a..86d06b55 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -897,12 +897,12 @@ namespace chaiscript { Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { const auto &enum_name = this->children[0]->text; - std::set valid_values; + std::vector valid_values; for (size_t i = 1; i < this->children.size(); i += 2) { const auto &val_name = this->children[i]->text; const int val_int = Boxed_Number(this->children[i + 1]->eval(t_ss)).get_as(); - valid_values.insert(val_int); + valid_values.push_back(val_int); dispatch::Dynamic_Object dobj(enum_name); dobj.get_attr("value") = Boxed_Value(val_int); @@ -910,13 +910,13 @@ namespace chaiscript { t_ss->add_global_const(const_var(dobj), enum_name + "::" + val_name); } - auto shared_valid = std::make_shared>(std::move(valid_values)); + auto shared_valid = std::make_shared>(std::move(valid_values)); t_ss->add( std::make_shared( enum_name, fun([shared_valid, enum_name](dispatch::Dynamic_Object &t_obj, int t_val) { - if (shared_valid->count(t_val) == 0) { + if (std::find(shared_valid->begin(), shared_valid->end(), t_val) == shared_valid->end()) { throw exception::eval_error("Value " + std::to_string(t_val) + " is not valid for enum '" + enum_name + "'"); } t_obj.get_attr("value") = Boxed_Value(t_val); @@ -950,26 +950,6 @@ namespace chaiscript { } }; - template - struct Enum_Access_AST_Node final : AST_Node_Impl { - Enum_Access_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::Enum_Access, std::move(t_loc), std::move(t_children)) - , m_key(this->children[0]->text + "::" + this->children[1]->text) { - } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - try { - return t_ss.get_object(m_key, m_loc); - } catch (std::exception &) { - throw exception::eval_error("Can not find enum value: " + m_key); - } - } - - private: - const std::string m_key; - mutable std::atomic_uint_fast32_t m_loc = {0}; - }; - template struct If_AST_Node final : AST_Node_Impl { If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index e4e08b63..12ef9e86 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2452,14 +2452,17 @@ namespace chaiscript { build_match>(prev_stack_top); } else if (!m_match_stack.empty() && m_match_stack.back()->identifier == AST_Node_Type::Id && Symbol("::")) { has_more = true; + const auto enum_name = m_match_stack.back()->text; + const auto start_loc = m_match_stack.back()->location; + m_match_stack.pop_back(); + if (!Id(true)) { throw exception::eval_error("Expected identifier after '::'", File_Position(m_position.line, m_position.col), *m_filename); } - if (std::distance(m_match_stack.begin() + static_cast(prev_stack_top), m_match_stack.end()) != 2) { - throw exception::eval_error("Incomplete enum access", File_Position(m_position.line, m_position.col), *m_filename); - } - build_match>(prev_stack_top); + const auto val_name = m_match_stack.back()->text; + m_match_stack.pop_back(); + m_match_stack.push_back(make_node>(enum_name + "::" + val_name, start_loc.start.line, start_loc.start.column)); } else if (Symbol(".")) { has_more = true; if (!(Id(true))) {