Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src / asm / bytecode.cpp
diff options
context:
space:
mode:
1 files changed, 120 insertions, 0 deletions
-rw-r--r--spasm/src/asm/bytecode.cpp120
diff --git a/spasm/src/asm/bytecode.cpp b/spasm/src/asm/bytecode.cpp
new file mode 100644
index 0000000..70e16c9
--- /dev/null
+++ b/spasm/src/asm/bytecode.cpp
@@ -0,0 +1,120 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "bytecode.hpp"
+
+namespace SpasmImpl
+{
+namespace ASM
+{
+Bytecode_Stream::~Bytecode_Stream() {}
+
+Bytecode_File::Bytecode_File(const std::string& filename)
+ : _bytecode(filename.c_str(), std::ios_base::out | std::ios_base::binary)
+{
+}
+
+void Bytecode_File::push_byte(Bytecode_Stream::byte byte)
+{
+ _bytecode.put(byte);
+}
+
+void Bytecode_File::push_opcode(Bytecode_Stream::Opcode_t opcode)
+{
+ push_byte(opcode);
+}
+
+union DoubleToBits {
+ double as_double;
+ int64_t as_bits;
+};
+
+int64_t to_bits(double d)
+{
+ DoubleToBits v;
+ v.as_double = d;
+ return v.as_bits;
+};
+
+void Bytecode_File::push_integer(int64_t number, int size)
+{
+ for (int i = 0; i < size; ++i)
+ push_byte((number >> (i << 3)) & 0xff);
+}
+
+void Bytecode_File::push_double(double number)
+{
+ auto bits = to_bits(number);
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ push_byte((bits >> (i << 3)) & 0xff);
+}
+
+void Bytecode_Memory::push_byte(Bytecode_Stream::byte byte)
+{
+ _bytecode.push_back(byte);
+}
+
+void Bytecode_Memory::push_opcode(Bytecode_Stream::Opcode_t opcode)
+{
+ push_byte(opcode);
+}
+
+void Bytecode_Memory::push_integer(int64_t number, int size)
+{
+ for (int i = 0; i < size; ++i)
+ push_byte((number >> (i << 3)) & 0xff);
+}
+
+void Bytecode_Memory::push_double(double number)
+{
+ auto bits = to_bits(number);
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ push_byte((bits >> (i << 3)) & 0xff);
+}
+
+void Bytecode_Memory::set_location(size_t index, size_t location)
+{
+ if (location <= 0xff)
+ {
+ _bytecode[index] = (byte)location;
+ }
+ else
+ {
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ _bytecode.at(index + i) = ((location >> (i << 3)) & 0xff);
+ }
+}
+
+void Bytecode_Memory::push_location(size_t location)
+{
+ if (location <= 0xff)
+ {
+ push_byte((byte)location);
+ }
+ else
+ {
+ for (size_t i = 0; i < sizeof(size_t); ++i)
+ _bytecode.push_back((location >> (i << 3)) & 0xff);
+ }
+}
+
+void Bytecode_Memory::push_string(const char* s, size_t length, int size)
+{
+ push_integer(int64_t(length), size);
+ _bytecode.insert(_bytecode.end(), s, s + length);
+}
+
+const Bytecode_Memory::Bytecode& Bytecode_Memory::bytecode() const
+{
+ return _bytecode;
+}
+
+size_t Bytecode_Memory::size() const
+{
+ return _bytecode.size();
+}
+
+} // namespace ASM
+} // namespace SpasmImpl