From 36bb3ffefa64e62c84e5873174ead3bbb4376e0a Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 13 Mar 2024 19:04:22 -0400 Subject: [PATCH] types --- CMakeLists.txt | 2 +- include/lilfbtf/fwddecl.h | 1 + include/lilfbtf/type.h | 106 ++++++++++++++++++++++++++++++++++---- src/type.cpp | 23 ++++++--- tests/src/main.cpp | 3 ++ tests/src/tests4.cpp | 72 +++++++++++++------------- 6 files changed, 154 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9040884..e7c1c5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(lilfbtf5 VERSION 0.1.19) +project(lilfbtf5 VERSION 0.1.20) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/lilfbtf/fwddecl.h b/include/lilfbtf/fwddecl.h index 50de4b9..3a87e98 100644 --- a/include/lilfbtf/fwddecl.h +++ b/include/lilfbtf/fwddecl.h @@ -42,6 +42,7 @@ namespace fb using function_id = blt::u32; using arg_c_t = blt::size_t; using func_t_call_t = std::function)>; + using func_t_init_t = std::function; using function_name = const std::string&; using type_name = const std::string&; } diff --git a/include/lilfbtf/type.h b/include/lilfbtf/type.h index 518e262..1033036 100644 --- a/include/lilfbtf/type.h +++ b/include/lilfbtf/type.h @@ -21,10 +21,79 @@ #include #include +#include #include +#include namespace fb { + template + class associative_array + { + private: + K size_; + T* data_; + + void expand() + { + K new_size = static_cast(size_ == 0 ? 16 : blt::mem::next_byte_allocation(size_)); + T* new_data = static_cast(std::malloc(new_size * sizeof(T))); + if constexpr (init) + { + for (blt::size_t i = size_; i < new_size; i++) + new(&new_size[i]) T(); + } + for (blt::size_t i = 0; i < size_; i++) + new(&new_data[i]) T(std::move(data_[i])); + std::free(data_); + data_ = new_data; + size_ = new_size; + } + + public: + associative_array(): size_(0), data_(nullptr) + {} + + T& operator[](K index) + { + return data_[index]; + } + + const T& operator[](K index) const + { + return data_[index]; + } + + void insert(K index, const T& t) + { + while (index >= size_) + expand(); + data_[index] = t; + } + + void insert(K index, T&& t) + { + while (index >= size_) + expand(); + data_[index] = std::move(t); + } + + [[nodiscard]] inline T* data() + { + return data_; + } + + [[nodiscard]] inline K size() const + { + return size_; + } + + ~associative_array() + { + std::free(data_); + } + }; + class type_engine_t { private: @@ -36,19 +105,22 @@ namespace fb blt::hashmap_t name_to_function; std::vector function_to_name; - // TODO: we don't need a hashmap for this. // Also a bad idea to store references, however these functions should be declared statically so this isn't as big of an issue. - blt::hashmap_t> functions; - // function names -> type_id - blt::hashmap_t function_outputs; - // function names -> list of type_id for parameters where index 0 = arg 1 - blt::hashmap_t> function_inputs; + associative_array> functions; + // function id -> list of type_id for parameters where index 0 = arg 1 + associative_array> function_inputs; + + associative_array> terminal_initializer; + associative_array, true> terminals; + associative_array, true> non_terminals; public: type_engine_t() = default; type_id register_type(type_name type_name); - function_id register_function(function_name func_name, func_t_call_t& func); + function_id register_function(function_name func_name, type_id output, func_t_call_t& func); + + function_id register_terminal_function(function_name func_name, type_id output, func_t_call_t& func, func_t_init_t& initializer); inline type_id get_type_id(type_name name) { return name_to_type[name]; } @@ -56,9 +128,25 @@ namespace fb inline type_id get_function_id(function_name name) { return name_to_function[name]; } - type_engine_t& associate_output(function_name func_name, type_name type_name); + type_engine_t& associate_input(function_name func_name, const std::vector& types); - type_engine_t& associate_input(function_name func_name, type_name); + inline func_t_call_t& get_function(function_id id) + { return functions[id]; } + + inline func_t_call_t& get_function(function_name name) + { return get_function(get_function_id(name)); } + + inline func_t_init_t& get_function_initializer(function_id id) + { return terminal_initializer[id]; } + + inline func_t_init_t& get_function_initializer(function_name name) + { return get_function_initializer(get_function_id(name)); } + + inline std::vector& get_terminals(type_id type) + { return terminals[type]; } + + inline std::vector& get_non_terminals(type_id type) + { return non_terminals[type]; } }; } diff --git a/src/type.cpp b/src/type.cpp index 8bba3f1..ed0f9c4 100644 --- a/src/type.cpp +++ b/src/type.cpp @@ -28,23 +28,32 @@ namespace fb return id; } - function_id type_engine_t::register_function(function_name func_name, func_t_call_t& func) + function_id type_engine_t::register_function(function_name func_name, type_id output, func_t_call_t& func) { function_id id = function_to_name.size(); name_to_function[func_name] = id; - functions.insert({id, func}); + functions.insert(id, func); + non_terminals[output].push_back(id); return id; } - type_engine_t& type_engine_t::associate_output(function_name func_name, type_name type_name) + type_engine_t& type_engine_t::associate_input(function_name func_name, const std::vector& types) { - function_outputs[func_name] = get_type_id(type_name); + auto id = get_function_id(func_name); + std::vector type_ids; + for (const auto& v : types) + type_ids.push_back(get_type_id(v)); + function_inputs[id] = std::move(type_ids); return *this; } - type_engine_t& type_engine_t::associate_input(function_name func_name, type_name) + function_id type_engine_t::register_terminal_function(function_name func_name, type_id output, func_t_call_t& func, func_t_init_t& initializer) { - - return *this; + function_id id = function_to_name.size(); + name_to_function[func_name] = id; + functions.insert(id, func); + terminals[output].push_back(id); + terminal_initializer.insert(id, initializer); + return id; } } \ No newline at end of file diff --git a/tests/src/main.cpp b/tests/src/main.cpp index 91bf4de..76e9250 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -47,6 +47,9 @@ int main(int argc, const char** argv) auto args = parser.parse_args(argc, argv); + std::hash hash; + BLT_TRACE0_STREAM << hash(500) << "\n"; + if (args.contains("--tests")) { //fb::test2(); diff --git a/tests/src/tests4.cpp b/tests/src/tests4.cpp index 91cd786..ec20922 100644 --- a/tests/src/tests4.cpp +++ b/tests/src/tests4.cpp @@ -360,7 +360,7 @@ namespace fb using any_t = any_t_base<8>; //using any_t = any_t_variant; - class func_t; + class func_t_old; class func_variant_t; @@ -368,20 +368,20 @@ namespace fb class func_any_t; - using func_t_call_t = std::function)>; + using func_t_call_t_old = std::function)>; using func_variant_t_call_t = std::function)>; using func_union_t_call_t = std::function)>; using func_any_t_call_t = std::function)>; - class func_t + class func_t_old { private: blt::size_t argc_ = 0; - const func_t_call_t& func; + const func_t_call_t_old& func; protected: any_t value; public: - explicit func_t(blt::size_t argc, const func_t_call_t& func): + explicit func_t_old(blt::size_t argc, const func_t_call_t_old& func): argc_(argc), func(func) {} @@ -393,7 +393,7 @@ namespace fb return value; } - inline func_t& setValue(any_t val) + inline func_t_old& setValue(any_t val) { this->value = val; return *this; @@ -404,7 +404,7 @@ namespace fb func(*this, args); }; - ~func_t() = default; + ~func_t_old() = default; }; class func_variant_t @@ -509,10 +509,10 @@ namespace fb ~func_any_t() = default; }; - const func_t_call_t add_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() + args[1].any_cast()); }; - const func_t_call_t sub_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() - args[1].any_cast()); }; - const func_t_call_t mul_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() * args[1].any_cast()); }; - const func_t_call_t div_f = [](func_t& us, blt::span args) { + const func_t_call_t_old add_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() + args[1].any_cast()); }; + const func_t_call_t_old sub_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() - args[1].any_cast()); }; + const func_t_call_t_old mul_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() * args[1].any_cast()); }; + const func_t_call_t_old div_f = [](func_t_old& us, blt::span args) { auto dim = args[1].any_cast(); if (dim == 0) us.setValue(0); @@ -520,20 +520,20 @@ namespace fb us.setValue(args[0].any_cast() + dim); }; - const func_t_call_t value_f = [](func_t&, blt::span) {}; - const func_t_call_t if_f = [](func_t& us, blt::span args) { + const func_t_call_t_old value_f = [](func_t_old&, blt::span) {}; + const func_t_call_t_old if_f = [](func_t_old& us, blt::span args) { if (args[0].any_cast()) us.setValue(args[1].any_cast()); else us.setValue(args[2].any_cast()); }; - const func_t_call_t equals_b_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() == args[1].any_cast()); }; - const func_t_call_t equals_n_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() == args[1].any_cast()); }; - const func_t_call_t less_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() < args[1].any_cast()); }; - const func_t_call_t greater_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() > args[1].any_cast()); }; - const func_t_call_t not_f = [](func_t& us, blt::span args) { us.setValue(!args[0].any_cast()); }; - const func_t_call_t and_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() && args[1].any_cast()); }; - const func_t_call_t or_f = [](func_t& us, blt::span args) { us.setValue(args[0].any_cast() || args[1].any_cast()); }; + const func_t_call_t_old equals_b_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() == args[1].any_cast()); }; + const func_t_call_t_old equals_n_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() == args[1].any_cast()); }; + const func_t_call_t_old less_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() < args[1].any_cast()); }; + const func_t_call_t_old greater_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() > args[1].any_cast()); }; + const func_t_call_t_old not_f = [](func_t_old& us, blt::span args) { us.setValue(!args[0].any_cast()); }; + const func_t_call_t_old and_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() && args[1].any_cast()); }; + const func_t_call_t_old or_f = [](func_t_old& us, blt::span args) { us.setValue(args[0].any_cast() || args[1].any_cast()); }; const func_variant_t_call_t add_variant_f = [](func_variant_t& us, blt::span args) { @@ -671,41 +671,41 @@ namespace fb }; - func_t make_type(type_t type) + func_t_old make_type(type_t type) { switch (type) { case type_t::ADD: - return func_t{2, add_f}; + return func_t_old{2, add_f}; case type_t::SUB: - return func_t{2, sub_f}; + return func_t_old{2, sub_f}; case type_t::MUL: - return func_t{2, mul_f}; + return func_t_old{2, mul_f}; case type_t::DIV: - return func_t{2, div_f}; + return func_t_old{2, div_f}; case type_t::IF: - return func_t{3, if_f}; + return func_t_old{3, if_f}; case type_t::EQUAL_B: - return func_t{2, equals_b_f}; + return func_t_old{2, equals_b_f}; case type_t::EQUAL_N: - return func_t{2, equals_n_f}; + return func_t_old{2, equals_n_f}; case type_t::LESS: - return func_t{2, less_f}; + return func_t_old{2, less_f}; case type_t::GREATER: - return func_t{2, greater_f}; + return func_t_old{2, greater_f}; case type_t::NOT: - return func_t{1, not_f}; + return func_t_old{1, not_f}; case type_t::AND: - return func_t{2, and_f}; + return func_t_old{2, and_f}; case type_t::OR: - return func_t{2, or_f}; + return func_t_old{2, or_f}; case type_t::VALUE: - return func_t{0, value_f}.setValue(random_value()); + return func_t_old{0, value_f}.setValue(random_value()); case type_t::END: break; } BLT_WARN("How did we get here? input %d", static_cast(type)); - return func_t{0, value_f}.setValue(random_value()); + return func_t_old{0, value_f}.setValue(random_value()); } func_variant_t make_type_variant(type_t type) @@ -826,7 +826,7 @@ namespace fb private: struct node_t { - func_t type; + func_t_old type; type_t enum_type; node_t** children = nullptr;