forked from KPGPMC/furlang
feat(furvm): add operation instructions
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -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),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user