allow starting type

main
Brett 2024-03-14 15:39:14 -04:00
parent d39b2d4650
commit 2cc0814800
3 changed files with 48 additions and 9 deletions

View File

@ -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)

View File

@ -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<type_id> starting_type = {});
std::pair<blt::unsafe::any_t, type_id> evaluate();
};
}

View File

@ -28,11 +28,21 @@ 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<type_id> starting_type)
{
using detail::node_t;
tree_t tree(types);
{
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<node_t>(func, tree.alloc);
} else
{
auto& non_terminals = types.get_all_non_terminals();
auto selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
@ -41,6 +51,7 @@ namespace fb
func_init.value()(func);
tree.root = tree.alloc.template emplace<node_t>(func, tree.alloc);
}
}
std::stack<std::pair<node_t*, blt::size_t>> stack;
stack.emplace(tree.root, 0);
while (!stack.empty())
@ -118,5 +129,31 @@ namespace fb
return tree;
}
std::pair<blt::unsafe::any_t, type_id> tree_t::evaluate()
{
using detail::node_t;
std::stack<node_t*> nodes;
std::stack<node_t*> 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()};
}
}