Coroutine generator becomes a part of the core EightBit library.

This commit is contained in:
Adrian Conlon committed 2021-12-17 09:19:16 +00:00
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>
-61
View File
@@ -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
+1 -3
View File
@@ -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
+3 -7
View File
@@ -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();
};
+1 -2
View File
@@ -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
-35
View File
@@ -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();