forked from KPGPMC/furlang
feat(furvm): add call instruction
This commit is contained in:
@@ -14,7 +14,7 @@ enum class function_t : std::uint8_t {
|
|||||||
Native, /**< A native function implemented through furvm API. */
|
Native, /**< A native function implemented through furvm API. */
|
||||||
};
|
};
|
||||||
|
|
||||||
using native_function = std::function<void(const executor_p&)>;
|
using native_function = std::function<void(executor&)>;
|
||||||
|
|
||||||
class function {
|
class function {
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -65,6 +65,13 @@ enum class instruction_t : byte {
|
|||||||
*/
|
*/
|
||||||
Mod,
|
Mod,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calls a function.
|
||||||
|
*
|
||||||
|
* Calls a function denoted by next two bytes in little-endian from current frame's module.
|
||||||
|
*/
|
||||||
|
Call,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Pops the current call frame.
|
* @brief Pops the current call frame.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ public:
|
|||||||
* @return The byte.
|
* @return The byte.
|
||||||
*/
|
*/
|
||||||
constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); }
|
constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); }
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a function from this module.
|
||||||
|
*
|
||||||
|
* @param id Id of the function.
|
||||||
|
* @return The function.
|
||||||
|
*/
|
||||||
|
constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); }
|
||||||
private:
|
private:
|
||||||
module_handle m_id;
|
module_handle m_id;
|
||||||
bytecode_t m_bytecode;
|
bytecode_t m_bytecode;
|
||||||
|
|||||||
@@ -109,6 +109,17 @@ void executor::step() {
|
|||||||
auto lhs = pop_thing();
|
auto lhs = pop_thing();
|
||||||
push_thing(lhs % rhs);
|
push_thing(lhs % rhs);
|
||||||
} break;
|
} break;
|
||||||
|
case instruction_t::Call: {
|
||||||
|
function_handle funcId = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
|
||||||
|
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
|
||||||
|
frame.position += 2;
|
||||||
|
|
||||||
|
const function_p& function = frame.mod->function_at(funcId);
|
||||||
|
switch (function->type()) {
|
||||||
|
case function_t::Normal: push_frame(function); break;
|
||||||
|
case function_t::Native: function->native()(*this); break;
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
|
|||||||
+6
-4
@@ -11,17 +11,19 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
static constexpr std::array<furvm::byte, 6> s_bytecode = {
|
static constexpr std::array<furvm::byte, 8> 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::Add),
|
furvm::byte(furvm::instruction_t::Add),
|
||||||
furvm::byte(furvm::instruction_t::Drop),
|
furvm::byte(furvm::instruction_t::Call),
|
||||||
|
1,
|
||||||
|
0,
|
||||||
furvm::byte(furvm::instruction_t::Return),
|
furvm::byte(furvm::instruction_t::Return),
|
||||||
};
|
};
|
||||||
|
|
||||||
void print(const furvm::executor_p& exec) {
|
void print(furvm::executor& exec) {
|
||||||
std::cout << exec->pop_thing()->int32() << '\n';
|
std::cout << exec.pop_thing()->int32() << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|||||||
Reference in New Issue
Block a user