diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e722b..c1fce15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(lilfbtf5 VERSION 0.1.25) +project(lilfbtf5 VERSION 0.1.26) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/lilfbtf/type.h b/include/lilfbtf/type.h index 9669682..9005563 100644 --- a/include/lilfbtf/type.h +++ b/include/lilfbtf/type.h @@ -126,7 +126,7 @@ namespace fb associative_array, true> function_inputs; associative_array function_argc; - associative_array> function_initializer; + blt::hashmap_t> function_initializer; associative_array, true> terminals; associative_array, true> non_terminals; std::vector> all_non_terminals; @@ -164,10 +164,14 @@ namespace fb [[nodiscard]] inline const func_t_call_t& get_function(function_name name) const { return get_function(get_function_id(name)); } - [[nodiscard]] inline const func_t_init_t& get_function_initializer(function_id id) const - { return function_initializer[id]; } + [[nodiscard]] inline std::optional> get_function_initializer(function_id id) const + { + if (!function_initializer.contains(id)) + return {}; + return function_initializer.at(id); + } - [[nodiscard]] inline const func_t_init_t& get_function_initializer(function_name name) const + [[nodiscard]] inline std::optional> get_function_initializer(function_name name) const { return get_function_initializer(get_function_id(name)); } // output type -> list of functions that output that type and take arguments themselves diff --git a/src/tree.cpp b/src/tree.cpp index 2ffc3ec..3380107 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -37,6 +37,8 @@ namespace fb auto& non_terminals = types.get_all_non_terminals(); auto selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)]; func_t func(types.get_function_argc(selection.second), types.get_function(selection.second), selection.first, selection.second); + if (const auto& func_init = types.get_function_initializer(selection.second)) + func_init.value()(func); tree.root = tree.alloc.template emplace(func, tree.alloc); } std::stack> stack; @@ -64,6 +66,8 @@ namespace fb { function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)]; func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); node->children[i] = tree.alloc.template emplace(func, tree.alloc); has_one_non_terminal = true; continue; @@ -73,6 +77,8 @@ namespace fb { function_id selection = terminals[engine.random_long(0, terminals.size() - 1)]; func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); node->children[i] = tree.alloc.template emplace(func, tree.alloc); continue; } @@ -82,6 +88,8 @@ namespace fb // use full() method function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)]; func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); node->children[i] = tree.alloc.template emplace(func, tree.alloc); } else { @@ -91,12 +99,16 @@ namespace fb // use non-terminals function_id selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)]; func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); node->children[i] = tree.alloc.template emplace(func, tree.alloc); } else { // use terminals function_id selection = terminals[engine.random_long(0, terminals.size() - 1)]; func_t func(types.get_function_argc(selection), types.get_function(selection), type_category, selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); node->children[i] = tree.alloc.template emplace(func, tree.alloc); } }