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) 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_ADDRSAN "Enable the address sanitizer" OFF)
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)

View File

@ -123,7 +123,9 @@ namespace fb
public: public:
explicit tree_t(type_engine_t& types); 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,18 +28,29 @@ namespace fb
{} {}
tree_t tree_t::make_tree(type_engine_t& types, random& engine, 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; using detail::node_t;
tree_t tree(types); tree_t tree(types);
{ {
auto& non_terminals = types.get_all_non_terminals(); if (starting_type)
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); auto& non_terminals = types.get_non_terminals(starting_type.value());
if (const auto& func_init = types.get_function_initializer(selection.second)) auto selection = non_terminals[engine.random_long(0, non_terminals.size() - 1)];
func_init.value()(func); func_t func(types.get_function_argc(selection), types.get_function(selection), starting_type.value(), selection);
tree.root = tree.alloc.template emplace<node_t>(func, tree.alloc); 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)];
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<node_t>(func, tree.alloc);
}
} }
std::stack<std::pair<node_t*, blt::size_t>> stack; std::stack<std::pair<node_t*, blt::size_t>> stack;
stack.emplace(tree.root, 0); stack.emplace(tree.root, 0);
@ -118,5 +129,31 @@ namespace fb
return tree; 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()};
}
} }