VM basics (#5)

Co-authored-by: Andre Wagner <WagnerAndre@JohnDeere.com>
Reviewed-on: https://192.168.5.48/andre/tyche/pulls/5
This commit was merged in pull request #5.
This commit is contained in:
2026-04-30 13:34:49 -05:00
parent 71390b0f84
commit b835dbb36e
24 changed files with 366 additions and 47 deletions

View File

@@ -1,152 +0,0 @@
#include "bytearray.hh"
#include <cstring>
#include <cstdio>
namespace tyche {
void ByteArray::set_byte(uint32_t addr, uint8_t byte)
{
if (data_.size() < (addr + 1))
data_.resize(addr + 1, 0);
data_.at(addr) = byte;
}
void ByteArray::set_int8(uint32_t addr, int8_t value)
{
set_byte(addr, (uint8_t) value);
}
void ByteArray::set_int16(uint32_t addr, int16_t value)
{
set_byte(addr, (uint8_t) (value));
set_byte(addr+1, (uint8_t) (value >> 8));
}
void ByteArray::set_int32(uint32_t addr, int32_t value)
{
set_byte(addr, (uint8_t) (value));
set_byte(addr+1, (uint8_t) (value >> 8));
set_byte(addr+2, (uint8_t) (value >> 16));
set_byte(addr+3, (uint8_t) (value >> 24));
}
void ByteArray::set_uint16(uint32_t addr, uint16_t value)
{
set_byte(addr, (uint8_t) (value));
set_byte(addr+1, (uint8_t) (value >> 8));
}
void ByteArray::set_uint32(uint32_t addr, uint32_t value)
{
set_byte(addr, (uint8_t) (value));
set_byte(addr+1, (uint8_t) (value >> 8));
set_byte(addr+2, (uint8_t) (value >> 16));
set_byte(addr+3, (uint8_t) (value >> 24));
}
void ByteArray::set_float(uint32_t addr, float value)
{
uint32_t bits;
std::memcpy(&bits, &value, 4);
set_byte(addr, (uint8_t) (bits));
set_byte(addr+1, (uint8_t) (bits >> 8));
set_byte(addr+2, (uint8_t) (bits >> 16));
set_byte(addr+3, (uint8_t) (bits >> 24));
}
void ByteArray::set_string(uint32_t addr, std::string const& str)
{
for (uint8_t c: str)
set_byte(addr++, c);
set_byte(addr, 0);
}
void ByteArray::set_bytearray(uint32_t addr, ByteArray const& bytearray)
{
for (uint8_t byte: bytearray.data())
set_byte(addr++, byte);
}
uint8_t ByteArray::get_byte(uint32_t addr) const
{
return data_.at(addr);
}
uint16_t ByteArray::get_uint16(uint32_t addr) const
{
return (uint32_t) get_byte(addr)
| (uint32_t) get_byte(addr+1) << 8;
}
uint32_t ByteArray::get_uint32(uint32_t addr) const
{
return (uint32_t) get_byte(addr)
| (uint32_t) get_byte(addr+1) << 8
| (uint32_t) get_byte(addr+2) << 16
| (uint32_t) get_byte(addr+3) << 24;
}
int8_t ByteArray::get_int8(uint32_t addr) const
{
return std::bit_cast<int8_t>(get_byte(addr));
}
int16_t ByteArray::get_int16(uint32_t addr) const
{
return (uint16_t) get_byte(addr)
| (uint16_t) get_byte(addr+1) << 8;
}
int32_t ByteArray::get_int32(uint32_t addr) const
{
return std::bit_cast<int32_t>((uint32_t) get_byte(addr)
| (uint32_t) get_byte(addr+1) << 8
| (uint32_t) get_byte(addr+2) << 16
| (uint32_t) get_byte(addr+3) << 24);
}
float ByteArray::get_float(uint32_t addr) const
{
uint32_t bits = (uint32_t) get_byte(addr)
| (uint32_t) get_byte(addr+1) << 8
| (uint32_t) get_byte(addr+2) << 16
| (uint32_t) get_byte(addr+3) << 24;
float value;
std::memcpy(&value, &bits, 4);
return value;
}
std::pair<std::string, size_t> ByteArray::get_string(uint32_t addr) const
{
std::string data;
while (char c = (char) get_byte(addr++))
data += c;
return { data, data.size() + 1 };
}
void ByteArray::append_bytearray(ByteArray const& bytearray)
{
data_.insert(data_.end(), bytearray.data().begin(), bytearray.data().end());
}
std::string ByteArray::hexdump() const
{
auto to_hex = [](uint32_t value, size_t n_chars) -> std::string {
char buf[15];
snprintf(buf, sizeof buf, (std::string("%0") + std::to_string(n_chars) + "X").c_str(), value);
return { buf };
};
std::string out;
for (size_t i = 0; i < data_.size(); ++i) {
if (i % 16 == 0)
out += to_hex(i, 4) + " | ";
out += to_hex(data_.at(i), 2) + " ";
if (i % 16 == 15)
out += "\n";
}
return out + "\n";
}
}

View File

@@ -1,61 +0,0 @@
#ifndef TYCHE_BYTEARRAY_HH
#define TYCHE_BYTEARRAY_HH
#include <cstdint>
#include <stdexcept>
#include <string>
#include <vector>
namespace tyche {
class ByteArray {
public:
ByteArray() = default;
explicit ByteArray(std::vector<uint8_t> data) : data_(std::move(data)) {}
void set_byte(uint32_t addr, uint8_t byte);
void set_uint16(uint32_t addr, uint16_t value);
void set_uint32(uint32_t addr, uint32_t value);
void set_int8(uint32_t addr, int8_t value);
void set_int16(uint32_t addr, int16_t value);
void set_int32(uint32_t addr, int32_t value);
void set_float(uint32_t addr, float value);
void set_string(uint32_t addr, std::string const& str);
void set_bytearray(uint32_t addr, ByteArray const& bytearray);
void append_byte(uint8_t byte) { set_byte(data_.size(), byte); }
void append_uint16(uint16_t value) { set_uint16(data_.size(), value); }
void append_uint32(uint32_t value) { set_uint32(data_.size(), value); }
void append_int8(int8_t value) { set_int8(data_.size(), value); }
void append_int16(int16_t value) { set_int16(data_.size(), value); }
void append_int32(int32_t value) { set_int32(data_.size(), value); }
void append_float(float value) { set_float(data_.size(), value); }
void append_string(std::string const& str) { set_string(data_.size(), str); }
void append_bytearray(ByteArray const& bytearray);
[[nodiscard]] uint8_t get_byte(uint32_t addr) const;
[[nodiscard]] uint16_t get_uint16(uint32_t addr) const;
[[nodiscard]] uint32_t get_uint32(uint32_t addr) const;
[[nodiscard]] int8_t get_int8(uint32_t addr) const;
[[nodiscard]] int16_t get_int16(uint32_t addr) const;
[[nodiscard]] int32_t get_int32(uint32_t addr) const;
[[nodiscard]] float get_float(uint32_t addr) const;
[[nodiscard]] std::pair<std::string, size_t> get_string(uint32_t addr) const;
[[nodiscard]] std::vector<uint8_t> const& data() const { return data_; }
[[nodiscard]] size_t size() const { return data_.size(); }
[[nodiscard]] std::string hexdump() const;
private:
std::vector<uint8_t> data_ {};
};
class BytecodeParsingError : public std::runtime_error {
public:
explicit BytecodeParsingError(std::string const& str) : std::runtime_error(str.c_str()) {}
};
}
#endif //TYCHE_BYTEARRAY_HH

View File

@@ -1,7 +1,7 @@
#include "bytecode.hh"
#include "../common/overloaded.hh"
namespace tyche {
namespace tyche::bc {
Bytecode::Bytecode(ByteArray ba)
: byte_array_(std::move(ba))

View File

@@ -1,10 +1,10 @@
#ifndef TYCHE_BYTECODE_HH
#define TYCHE_BYTECODE_HH
#include "bytearray.hh"
#include "../common/bytearray.hh"
#include "bytecodeprototype.hh"
namespace tyche {
namespace tyche::bc {
class Bytecode {
public:

View File

@@ -6,9 +6,9 @@
#include <variant>
#include <vector>
#include "constant.hh"
#include "bytearray.hh"
#include "../common/bytearray.hh"
namespace tyche {
namespace tyche::bc {
struct BytecodePrototype {
struct Function {

View File

@@ -4,7 +4,7 @@
#include <string>
#include <variant>
namespace tyche {
namespace tyche::bc {
using ConstantValue = std::variant<float, std::string>;

View File

@@ -3,11 +3,12 @@
#include <cstring>
#include <functional>
#include "bytearray.hh"
#include "../common/bytearray.hh"
#include "bytecodeprototype.hh"
#include "bytecode.hh"
using namespace tyche;
using namespace tyche::bc;
TEST(ByteArray, ByteArray)
{