From 53ef92dbc4ee6ea4c63e52d729c48f77695a6304 Mon Sep 17 00:00:00 2001
From: Adrian Conlon <adrian.conlon@gmail.com>
Date: Mon, 3 Jan 2022 00:50:41 +0000
Subject: [PATCH] So I can compare implementations, add a non-coroutine variant
 of the HarteTest suite.

---
 M6502/HarteTest_6502/opcode_test_suite_t.cpp  |  9 +++++
 M6502/HarteTest_6502/opcode_test_suite_t.h    |  7 ++++
 .../HarteTest_6502/processor_test_suite_t.cpp | 10 ++++++
 M6502/HarteTest_6502/processor_test_suite_t.h |  8 +++++
 M6502/HarteTest_6502/stdafx.h                 |  4 +++
 M6502/HarteTest_6502/tests.cpp                | 33 +++++++++++++++++++
 6 files changed, 71 insertions(+)

diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.cpp b/M6502/HarteTest_6502/opcode_test_suite_t.cpp
index 8c9000c..77944bd 100644
--- a/M6502/HarteTest_6502/opcode_test_suite_t.cpp
+++ b/M6502/HarteTest_6502/opcode_test_suite_t.cpp
@@ -4,6 +4,7 @@
 opcode_test_suite_t::opcode_test_suite_t(const std::string path) noexcept
 : parser_t(path) {}
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 EightBit::co_generator_t<test_t> opcode_test_suite_t::generator() {
 	for (const auto element : *this)
@@ -14,4 +15,12 @@ void opcode_test_suite_t::generator(boost::coroutines2::coroutine<test_t>::push_
 	for (const auto element : *this)
 		sink(test_t(element));
 }
+#endif
+#else
+std::vector<test_t> opcode_test_suite_t::generate() {
+	std::vector<test_t> returned;
+	for (const auto element : *this)
+		returned.push_back(test_t(element));
+	return returned;
+}
 #endif
\ No newline at end of file
diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.h b/M6502/HarteTest_6502/opcode_test_suite_t.h
index eed3a7a..36c42b1 100644
--- a/M6502/HarteTest_6502/opcode_test_suite_t.h
+++ b/M6502/HarteTest_6502/opcode_test_suite_t.h
@@ -2,11 +2,14 @@
 
 #include <string>
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 #   include <co_generator_t.h>
 #else
 #	include <boost/coroutine2/all.hpp>
 #endif
+#   include <vector>
+#endif
 
 #include "parser_t.h"
 #include "test_t.h"
@@ -22,9 +25,13 @@ public:
     [[nodiscard]] auto begin() const noexcept { return array().begin(); }
     [[nodiscard]] auto end() const noexcept { return array().end(); }
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
     [[nodiscard]] EightBit::co_generator_t<test_t> generator();
 #else
     void generator(boost::coroutines2::coroutine<test_t>::push_type& sink);
 #endif
+#else
+    std::vector<test_t> generate();
+#endif
 };
diff --git a/M6502/HarteTest_6502/processor_test_suite_t.cpp b/M6502/HarteTest_6502/processor_test_suite_t.cpp
index 29f6918..bc38c7c 100644
--- a/M6502/HarteTest_6502/processor_test_suite_t.cpp
+++ b/M6502/HarteTest_6502/processor_test_suite_t.cpp
@@ -7,6 +7,7 @@ processor_test_suite_t::processor_test_suite_t(std::string location) noexcept
 : m_location(location) {
 }
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 EightBit::co_generator_t<opcode_test_suite_t> processor_test_suite_t::generator() {
     std::filesystem::path directory = location();
@@ -20,3 +21,12 @@ void processor_test_suite_t::generator(boost::coroutines2::coroutine<opcode_test
         sink(opcode_test_suite_t(entry.path().string()));
 }
 #endif
+#else
+std::vector<opcode_test_suite_t> processor_test_suite_t::generate() {
+    std::vector<opcode_test_suite_t> returned;
+    std::filesystem::path directory = location();
+    for (const auto& entry : std::filesystem::directory_iterator{ directory })
+        returned.push_back(opcode_test_suite_t(entry.path().string()));
+    return returned;
+}
+#endif
diff --git a/M6502/HarteTest_6502/processor_test_suite_t.h b/M6502/HarteTest_6502/processor_test_suite_t.h
index 309388f..3d64cdc 100644
--- a/M6502/HarteTest_6502/processor_test_suite_t.h
+++ b/M6502/HarteTest_6502/processor_test_suite_t.h
@@ -3,11 +3,15 @@
 #include <string>
 #include <string_view>
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 #	include <co_generator_t.h>
 #else
 #	include <boost/coroutine2/all.hpp>
 #endif
+#else
+#	include <vector>
+#endif
 
 #include "opcode_test_suite_t.h"
 
@@ -20,9 +24,13 @@ public:
 
 	std::string_view location() const noexcept { return m_location; }
 
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 	[[nodiscard]] EightBit::co_generator_t<opcode_test_suite_t> generator();
 #else
 	void generator(boost::coroutines2::coroutine<opcode_test_suite_t>::push_type& sink);
 #endif
+#else
+	std::vector<opcode_test_suite_t> generate();
+#endif
 };
diff --git a/M6502/HarteTest_6502/stdafx.h b/M6502/HarteTest_6502/stdafx.h
index a792a1e..98bfa8a 100644
--- a/M6502/HarteTest_6502/stdafx.h
+++ b/M6502/HarteTest_6502/stdafx.h
@@ -22,11 +22,15 @@
 #include <Disassembly.h>
 #include <Symbols.h>
 
+#define USE_COROUTINES
+
+#ifdef USE_COROUTINES
 #if __cplusplus >= 202002L
 #	include <co_generator_t.h>
 #else
 #	include <boost/coroutine2/all.hpp>
 #	include <boost/bind.hpp>
 #endif
+#endif
 
 #include "simdjson/simdjson.h"
diff --git a/M6502/HarteTest_6502/tests.cpp b/M6502/HarteTest_6502/tests.cpp
index abc3a04..f8c1403 100644
--- a/M6502/HarteTest_6502/tests.cpp
+++ b/M6502/HarteTest_6502/tests.cpp
@@ -30,6 +30,8 @@ int main() {
     checker_t checker(runner);
     checker.initialise();
 
+#ifdef USE_COROUTINES
+
 #if __cplusplus >= 202002L
 
     processor_test_suite_t m6502_tests(directory);
@@ -91,6 +93,37 @@ int main() {
         }
     }
 
+#endif
+
+#else
+
+    processor_test_suite_t m6502_tests(directory);
+    auto opcodes = m6502_tests.generate();
+    for (auto& opcode : opcodes) {
+
+        const auto path = std::filesystem::path(opcode.path());
+        std::cout << "Processing: " << path.filename() << "\n";
+        opcode.load();
+
+        auto tests = opcode.generate();
+        for (auto& test : tests) {
+
+            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();