mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2026-10-22 07:02:37 +00:00
Coroutine generator becomes a part of the core EightBit library.
This commit is contained in:
1 parent
f837836072
commit
7af8a19e2f
12 files changed
+16
-66
No files matched your search
@@ -185,7 +185,6 @@
|
||||
<ClInclude Include="array_t.h" />
|
||||
<ClInclude Include="byte_t.h" />
|
||||
<ClInclude Include="checker_t.h" />
|
||||
<ClInclude Include="co_generator_t.h" />
|
||||
<ClInclude Include="cycles_t.h" />
|
||||
<ClInclude Include="cycle_t.h" />
|
||||
<ClInclude Include="element_t.h" />
|
||||
|
||||
@@ -100,9 +100,6 @@
|
||||
<ClInclude Include="processor_test_suite_t.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="co_generator_t.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="checker_t.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
|
||||
#include <coroutine>
|
||||
#include <utility>
|
||||
|
||||
// from https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html
|
||||
|
||||
template<typename T>
|
||||
struct co_generator_t final {
|
||||
|
||||
struct promise_type;
|
||||
using handle_type = std::coroutine_handle<promise_type>;
|
||||
|
||||
struct promise_type {
|
||||
T value_;
|
||||
std::exception_ptr exception_;
|
||||
|
||||
co_generator_t get_return_object() {
|
||||
return co_generator_t(handle_type::from_promise(*this));
|
||||
}
|
||||
std::suspend_always initial_suspend() { return {}; }
|
||||
std::suspend_always final_suspend() noexcept { return {}; }
|
||||
void unhandled_exception() { exception_ = std::current_exception(); }
|
||||
template<std::convertible_to<T> From> // C++20 concept
|
||||
std::suspend_always yield_value(From&& from) {
|
||||
value_ = std::forward<From>(from);
|
||||
return {};
|
||||
}
|
||||
void return_void() {}
|
||||
};
|
||||
|
||||
handle_type h_;
|
||||
|
||||
co_generator_t(handle_type h) : h_(h) {}
|
||||
~co_generator_t() { h_.destroy(); }
|
||||
explicit operator bool() {
|
||||
fill();
|
||||
return !h_.done();
|
||||
}
|
||||
T operator()() {
|
||||
fill();
|
||||
full_ = false;
|
||||
return std::move(h_.promise().value_);
|
||||
}
|
||||
|
||||
private:
|
||||
bool full_ = false;
|
||||
|
||||
void fill() {
|
||||
if (!full_) {
|
||||
h_();
|
||||
if (h_.promise().exception_)
|
||||
std::rethrow_exception(h_.promise().exception_);
|
||||
full_ = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // USE_COROUTINES
|
||||
@@ -4,9 +4,7 @@
|
||||
opcode_test_suite_t::opcode_test_suite_t(const std::string path) noexcept
|
||||
: parser_t(path) {}
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
co_generator_t<test_t> opcode_test_suite_t::generator() {
|
||||
EightBit::co_generator_t<test_t> opcode_test_suite_t::generator() {
|
||||
for (const auto element : *this)
|
||||
co_yield test_t(element);
|
||||
}
|
||||
#endif
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <co_generator_t.h>
|
||||
|
||||
#include "parser_t.h"
|
||||
#include "test_t.h"
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
#include "co_generator_t.h"
|
||||
#endif
|
||||
|
||||
class opcode_test_suite_t final : public parser_t {
|
||||
private:
|
||||
[[nodiscard]] auto array() const noexcept { return raw().get_array(); }
|
||||
@@ -20,7 +18,5 @@ public:
|
||||
[[nodiscard]] auto begin() const noexcept { return array().begin(); }
|
||||
[[nodiscard]] auto end() const noexcept { return array().end(); }
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
co_generator_t<test_t> generator();
|
||||
#endif
|
||||
EightBit::co_generator_t<test_t> generator();
|
||||
};
|
||||
@@ -1,18 +1,14 @@
|
||||
#include "stdafx.h"
|
||||
#include "processor_test_suite_t.h"
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
#include <filesystem>
|
||||
#endif
|
||||
|
||||
processor_test_suite_t::processor_test_suite_t(std::string location) noexcept
|
||||
: m_location(location) {
|
||||
}
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
co_generator_t<opcode_test_suite_t> processor_test_suite_t::generator() {
|
||||
EightBit::co_generator_t<opcode_test_suite_t> processor_test_suite_t::generator() {
|
||||
std::filesystem::path directory = location();
|
||||
for (const auto& entry : std::filesystem::directory_iterator{ directory })
|
||||
co_yield opcode_test_suite_t(entry.path().string());
|
||||
}
|
||||
#endif
|
||||
@@ -3,9 +3,7 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
#include "co_generator_t.h"
|
||||
#endif
|
||||
#include <co_generator_t.h>
|
||||
|
||||
#include "opcode_test_suite_t.h"
|
||||
|
||||
@@ -18,7 +16,5 @@ public:
|
||||
|
||||
std::string_view location() const noexcept { return m_location; }
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
co_generator_t<opcode_test_suite_t> generator();
|
||||
#endif
|
||||
EightBit::co_generator_t<opcode_test_suite_t> generator();
|
||||
};
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <mos6502.h>
|
||||
#include <Disassembly.h>
|
||||
#include <Symbols.h>
|
||||
#include <co_generator_t.h>
|
||||
|
||||
#include "simdjson/simdjson.h"
|
||||
|
||||
#define USE_COROUTINES
|
||||
@@ -26,8 +26,6 @@ int main() {
|
||||
checker_t checker(runner);
|
||||
checker.initialise();
|
||||
|
||||
#ifdef USE_COROUTINES
|
||||
|
||||
processor_test_suite_t m6502_tests(directory);
|
||||
auto opcode_generator = m6502_tests.generator();
|
||||
while (opcode_generator) {
|
||||
@@ -58,39 +56,6 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::filesystem::path location = directory;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator{ location }) {
|
||||
|
||||
const auto& path = entry.path();
|
||||
|
||||
std::cout << "Processing: " << path.filename() << "\n";
|
||||
opcode_test_suite_t opcode(path.string());
|
||||
opcode.load();
|
||||
|
||||
for (const auto opcode_test_element : opcode) {
|
||||
|
||||
const auto test = test_t(opcode_test_element);
|
||||
checker.check(test);
|
||||
|
||||
if (checker.invalid()) {
|
||||
++invalid_opcode_count;
|
||||
if (checker.unimplemented())
|
||||
++unimplemented_opcode_count;
|
||||
if (checker.undocumented())
|
||||
++undocumented_opcode_count;
|
||||
std::cout << "** Failed: " << test.name() << "\n";
|
||||
for (const auto& message : checker.messages())
|
||||
std::cout << "**** " << message << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const auto finish_time = std::chrono::steady_clock::now();
|
||||
const auto elapsed_time = finish_time - start_time;
|
||||
const auto seconds = std::chrono::duration_cast<std::chrono::duration<double>>(elapsed_time).count();
|
||||
|
||||
Reference in new issue
Block a user