#pragma once #include #include #include #include #include #include #include "aisa/coroutine.h" namespace aisa { using regnum_t = std::uint_fast64_t; using regval_t = std::uint64_t; template struct EvalState { CRTP & crtp() noexcept { return static_cast(*this); } task async_load_reg(regnum_t rn) { while (true) { if (auto rv = crtp().load_reg(rn); rv.has_value()) co_return *rv; co_await suspend(); } } }; struct Step { const std::optional> predicate; const std::vector source_regs; const std::vector destination_regs; std::optional predicate_reg() const { if (predicate.has_value()) return predicate->first; return {}; } std::optional expected_predicate_val() const { if (predicate.has_value()) return predicate->second; return {}; } template task evaluate(State &state) const { if (predicate.has_value()) { std::cout << "checking predicate...\n"; std::cout << "\texpect " << predicate->second << "\n"; regval_t pval = co_await state.async_load_reg(predicate->first); std::cout << "\tgot " << pval << "\n"; if (pval != predicate->second) { std::cout << "\tpredicate skipped\n"; co_return; } else { std::cout << "\tpredicate not skipped\n"; } } std::cout << "reading sources...\n"; std::vector source_vals; source_vals.reserve(source_regs.size()); for (unsigned int i = 0; i < source_regs.size(); ++i) { std::cout << "\tgetting source " << i << "...\n"; source_vals.emplace_back(co_await state.async_load_reg(source_regs[i])); std::cout << "\t\tgot " << source_vals.back() << "\n"; } std::cout << "sources:"; for (unsigned int i = 0; i < source_regs.size(); ++i) std::cout << " " << source_regs[i] << "=" << source_vals[i]; std::cout << "\n"; std::cout << "done with evaluate\n"; } }; }