Compare commits
2 Commits
0534359503
...
9021ae0089
| Author | SHA1 | Date | |
|---|---|---|---|
|
9021ae0089
|
|||
|
4d935ef75f
|
@@ -93,6 +93,11 @@ public:
|
|||||||
* @return The module count.
|
* @return The module count.
|
||||||
*/
|
*/
|
||||||
constexpr size_t size() const { return m_modules.size(); }
|
constexpr size_t size() const { return m_modules.size(); }
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Removes unreferenced things from the thing list.
|
||||||
|
*/
|
||||||
|
void collect();
|
||||||
private:
|
private:
|
||||||
std::vector<mod_p> m_modules;
|
std::vector<mod_p> m_modules;
|
||||||
std::vector<thing_p> m_things;
|
std::vector<thing_p> m_things;
|
||||||
|
|||||||
@@ -40,6 +40,31 @@ enum class instruction_t : byte {
|
|||||||
*/
|
*/
|
||||||
Clone,
|
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.
|
* @brief Pops the current call frame.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "furvm/context.hpp" // IWYU pragma: keep
|
#include "furvm/context.hpp" // IWYU pragma: keep
|
||||||
#include "furvm/fwd.hpp"
|
#include "furvm/fwd.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
enum class thing_t : std::uint8_t {
|
enum class thing_t : std::uint8_t {
|
||||||
@@ -90,6 +92,98 @@ public:
|
|||||||
|
|
||||||
thing(const thing&) = delete;
|
thing(const thing&) = delete;
|
||||||
thing& operator=(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:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns a new thing.
|
* @brief Returns a new thing.
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
#include "furvm/context.hpp"
|
#include "furvm/context.hpp"
|
||||||
|
|
||||||
|
#include "furvm/thing.hpp" // IWYU pragma: keep
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
context::context() {}
|
context::context() {}
|
||||||
|
|
||||||
|
void context::collect() {
|
||||||
|
for (auto& ref : m_things) {
|
||||||
|
if (ref->reference_count() != 0) continue;
|
||||||
|
ref = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace furvm
|
} // namespace furvm
|
||||||
@@ -82,6 +82,31 @@ void executor::step() {
|
|||||||
case instruction_t::Clone: {
|
case instruction_t::Clone: {
|
||||||
push_thing(std::move(thing::clone(thing())));
|
push_thing(std::move(thing::clone(thing())));
|
||||||
} break;
|
} 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: {
|
case instruction_t::Return: {
|
||||||
pop_frame();
|
pop_frame();
|
||||||
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
|
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
|
||||||
|
|||||||
+5
-1
@@ -12,7 +12,7 @@ static constexpr std::array<furvm::byte, 6> s_bytecode = {
|
|||||||
furvm::byte(furvm::instruction_t::PushB2I),
|
furvm::byte(furvm::instruction_t::PushB2I),
|
||||||
67,
|
67,
|
||||||
furvm::byte(furvm::instruction_t::Clone),
|
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::Drop),
|
||||||
furvm::byte(furvm::instruction_t::Return),
|
furvm::byte(furvm::instruction_t::Return),
|
||||||
};
|
};
|
||||||
@@ -25,8 +25,12 @@ int main(void) {
|
|||||||
auto executor = furvm::executor::create(context);
|
auto executor = furvm::executor::create(context);
|
||||||
executor->push_frame(mainModule, 0);
|
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) {
|
while ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done) {
|
||||||
executor->step();
|
executor->step();
|
||||||
|
if ((++count % FPC) == 0) context->collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user