From 29b57bfa7c2c7b3297e88c66ad9e45a5979844a8 Mon Sep 17 00:00:00 2001
From: Roland Reichwein <mail@reichwein.it>
Date: Tue, 13 Oct 2020 21:36:07 +0200
Subject: New Ops implementation for assembler

---
 intel.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 66 insertions(+), 3 deletions(-)

diff --git a/intel.cpp b/intel.cpp
index dfcaa75..471dcbf 100644
--- a/intel.cpp
+++ b/intel.cpp
@@ -6,6 +6,7 @@
 #include "minicc.h"
 
 #include <algorithm>
+#include <any>
 #include <array>
 #include <deque>
 #include <functional>
@@ -146,7 +147,7 @@ namespace {
   throw std::runtime_error("Unknown command: "s + sl[0].value);
  }
 
- std::unordered_map<std::string, std::function<InstructionCodeList(const std::vector<Token>&)>> ops{
+ std::unordered_map<std::string, std::function<InstructionCodeList(const std::vector<Token>&)>> ops_old{
 
   // Integer Addition
   {"add", [](const std::vector<Token>& sl) -> InstructionCodeList {
@@ -318,6 +319,68 @@ namespace {
 
 } // namespace
 
+
+class Op
+{
+public:
+ virtual ~Op(){};
+ virtual std::vector<uint8_t> getMachineCode() = 0;
+ virtual size_t size() = 0; ///< returns size in bytes
+ virtual bool optimize() = 0; ///< returns true if changed
+};
+
+using AsmArgs = std::vector<std::any>; // 0th element is mnemonic
+using FactoryFunction = std::function<std::shared_ptr<Op>(AsmArgs&)>;
+
+std::unordered_map<std::string, FactoryFunction> ops;
+
+bool registerOp(const std::string& mnemonic, FactoryFunction f)
+{
+ if (ops.contains(mnemonic)) {
+  std::cout << "Warning: mnemonic |" << mnemonic << "| already registered." << std::endl;
+  return false;
+ }
+
+ std::cout << "Registering mnemonic |" << mnemonic << "|." << std::endl;
+
+ ops[mnemonic] = f;
+
+ return true;
+}
+
+class OpSimple: public Op
+{
+public:
+ OpSimple(std::vector<uint8_t> machine_code): machine_code(machine_code) {}
+
+ std::vector<uint8_t> getMachineCode() override
+ {
+  return machine_code;
+ }
+
+ size_t size() override
+ {
+  return machine_code.size();
+ }
+
+ bool optimize() override ///< returns true if changed
+ {
+  return false;
+ }
+
+protected:
+ std::vector<uint8_t> machine_code;
+};
+
+class Op_nop: public OpSimple
+{
+public:
+ Op_nop() : OpSimple({ 0x90 }) {}
+
+};
+
+bool registered { registerOp("nop", [](AsmArgs& args) -> std::shared_ptr<Op>{ return std::make_shared<Op_nop>(); }) };
+
 class Assembler {
 
  std::unordered_map<std::string, size_t> labels; ///< labels with their positions in instruction list
@@ -404,8 +467,8 @@ class Assembler {
     labels[t[0].value] = insn_list.size();
    } else if (t.size() >= 1 && t[0].type == "instruction") { // instruction
     std::string instruction{ t[0].value };
-    auto it = ops.find(instruction);
-    if (it == ops.end())
+    auto it = ops_old.find(instruction);
+    if (it == ops_old.end())
      throw std::runtime_error("Unknown instruction: "s + instruction);
 
     InstructionCodeList codes = it->second(t);
-- 
cgit v1.2.3