Compare commits

..

2 Commits

6 changed files with 163 additions and 1 deletions
+5
View File
@@ -93,6 +93,11 @@ public:
* @return The module count.
*/
constexpr size_t size() const { return m_modules.size(); }
public:
/**
* @brief Removes unreferenced things from the thing list.
*/
void collect();
private:
std::vector<mod_p> m_modules;
std::vector<thing_p> m_things;
+25
View File
@@ -40,6 +40,31 @@ enum class instruction_t : byte {
*/
Clone,
/**
* @brief Adds two things together on the stack.
*/
Add,
/**
* @brief Subtracts two things together on the stack.
*/
Sub,
/**
* @brief Multiplies two things together on the stack.
*/
Mul,
/**
* @brief Divides two things together on the stack.
*/
Div,
/**
* @brief Modulos two things together on the stack.
*/
Mod,
/**
* @brief Pops the current call frame.
*/
+94
View File
@@ -4,6 +4,8 @@
#include "furvm/context.hpp" // IWYU pragma: keep
#include "furvm/fwd.hpp"
#include <stdexcept>
namespace furvm {
enum class thing_t : std::uint8_t {
@@ -90,6 +92,98 @@ public:
thing(const thing&) = delete;
thing& operator=(const thing&) = delete;
public:
#define x(lType, rType) ((std::uint16_t)((((std::uint8_t)(lType)) << 8) | ((std::uint8_t)(rType))))
/**
* @brief Adds two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator+(const thing_p& lhs, const thing_p& rhs) {
switch (x(lhs->m_type, rhs->m_type)) {
case x(thing_t::Int32, thing_t::Int32): {
auto res = create(lhs->m_context, thing_t::Int32);
res->int32() = lhs->int32() + rhs->int32();
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
/**
* @brief Subtracts two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator-(const thing_p& lhs, const thing_p& rhs) {
switch (x(lhs->m_type, rhs->m_type)) {
case x(thing_t::Int32, thing_t::Int32): {
auto res = create(lhs->m_context, thing_t::Int32);
res->int32() = lhs->int32() - rhs->int32();
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
/**
* @brief Multiplies two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator*(const thing_p& lhs, const thing_p& rhs) {
switch (x(lhs->m_type, rhs->m_type)) {
case x(thing_t::Int32, thing_t::Int32): {
auto res = create(lhs->m_context, thing_t::Int32);
res->int32() = lhs->int32() * rhs->int32();
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
/**
* @brief Divides two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator/(const thing_p& lhs, const thing_p& rhs) {
switch (x(lhs->m_type, rhs->m_type)) {
case x(thing_t::Int32, thing_t::Int32): {
auto res = create(lhs->m_context, thing_t::Int32);
res->int32() = lhs->int32() / rhs->int32();
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
/**
* @brief Modulos two things together.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator%(const thing_p& lhs, const thing_p& rhs) {
switch (x(lhs->m_type, rhs->m_type)) {
case x(thing_t::Int32, thing_t::Int32): {
auto res = create(lhs->m_context, thing_t::Int32);
res->int32() = lhs->int32() % rhs->int32();
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
#undef x
public:
/**
* @brief Returns a new thing.
+9
View File
@@ -1,7 +1,16 @@
#include "furvm/context.hpp"
#include "furvm/thing.hpp" // IWYU pragma: keep
namespace furvm {
context::context() {}
void context::collect() {
for (auto& ref : m_things) {
if (ref->reference_count() != 0) continue;
ref = nullptr;
}
}
} // namespace furvm
+25
View File
@@ -82,6 +82,31 @@ void executor::step() {
case instruction_t::Clone: {
push_thing(std::move(thing::clone(thing())));
} break;
case instruction_t::Add: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs + rhs);
} break;
case instruction_t::Sub: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs - rhs);
} break;
case instruction_t::Mul: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs * rhs);
} break;
case instruction_t::Div: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs / rhs);
} break;
case instruction_t::Mod: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs % rhs);
} break;
case instruction_t::Return: {
pop_frame();
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
+5 -1
View File
@@ -12,7 +12,7 @@ static constexpr std::array<furvm::byte, 6> s_bytecode = {
furvm::byte(furvm::instruction_t::PushB2I),
67,
furvm::byte(furvm::instruction_t::Clone),
furvm::byte(furvm::instruction_t::Drop),
furvm::byte(furvm::instruction_t::Add),
furvm::byte(furvm::instruction_t::Drop),
furvm::byte(furvm::instruction_t::Return),
};
@@ -25,8 +25,12 @@ int main(void) {
auto executor = furvm::executor::create(context);
executor->push_frame(mainModule, 0);
static constexpr std::size_t FPC = 3; // Frames per collection
std::size_t count = 0;
while ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done) {
executor->step();
if ((++count % FPC) == 0) context->collect();
}
return 0;