diff --git a/CMakeLists.txt b/CMakeLists.txt index c1fce15..1aca375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(lilfbtf5 VERSION 0.1.26) +project(lilfbtf5 VERSION 0.1.27) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/lilfbtf/tree.h b/include/lilfbtf/tree.h index f7a2f16..8515e63 100644 --- a/include/lilfbtf/tree.h +++ b/include/lilfbtf/tree.h @@ -123,7 +123,9 @@ namespace fb public: explicit tree_t(type_engine_t& types); - static tree_t make_tree(type_engine_t& types, random& engine, blt::size_t min_height, blt::size_t max_height); + static tree_t make_tree(type_engine_t& types, random& engine, blt::size_t min_height, blt::size_t max_height, std::optional starting_type = {}); + + std::pair evaluate(); }; } diff --git a/src/tree.cpp b/src/tree.cpp index 3380107..0658078 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -28,18 +28,29 @@ namespace fb {} tree_t tree_t::make_tree(type_engine_t& types, random& engine, - blt::size_t min_height, blt::size_t max_height) + blt::size_t min_height, blt::size_t max_height, std::optional starting_type) { using detail::node_t; tree_t tree(types); { - 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); + if (starting_type) + { + auto& non_terminals = types.get_non_terminals(starting_type.value()); + auto selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)]; + func_t func(types.get_function_argc(selection), types.get_function(selection), starting_type.value(), selection); + if (const auto& func_init = types.get_function_initializer(selection)) + func_init.value()(func); + tree.root = tree.alloc.template emplace(func, tree.alloc); + } else + { + 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; stack.emplace(tree.root, 0); @@ -118,5 +129,31 @@ namespace fb return tree; } + std::pair tree_t::evaluate() + { + using detail::node_t; + std::stack nodes; + std::stack node_stack; + + nodes.push(root); + + while (!nodes.empty()) + { + auto* top = nodes.top(); + node_stack.push(top); + nodes.pop(); + for (blt::size_t i = 0; i < top->type.argc(); i++) + nodes.push(top->children[i]); + } + + while (!node_stack.empty()) + { + node_stack.top()->evaluate(); + node_stack.pop(); + } + + return {root->type.getValue(), root->type.getType()}; + } + } \ No newline at end of file