From eec25e3aea63998af75ea8dc5e23c8c2917db2e7 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Sun, 14 Jun 2026 23:49:29 +0200 Subject: [PATCH] feat(furvm): introduce jump and jump not zero instructions --- furvm/include/furvm/instruction.hpp | 15 +++++++++++++++ furvm/src/executor.cpp | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/furvm/include/furvm/instruction.hpp b/furvm/include/furvm/instruction.hpp index 2a73ea7..6c70574 100644 --- a/furvm/include/furvm/instruction.hpp +++ b/furvm/include/furvm/instruction.hpp @@ -86,6 +86,21 @@ enum class instruction_t : byte { */ Call, + /** + * @brief Jumps to an instruction relative to the current instruction. + * + * Jumps to an instruction relative to the current instruction with offset denoted by next byte. + */ + Jump, + + /** + * @brief Jumps to an instruction relative to the current instruction if top thing on the stack is not zero. + * + * Jumps to an instruction relative to the current instruction with offset denoted by next byte if the top thing on + * the stack is not zero (is true). + */ + JumpNotZero, + /** * @brief Pops the current call frame. */ diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index e4b5f28..ae10e70 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -139,11 +139,13 @@ void executor::step() { case instruction_t::Load: { variable_t variable = static_cast(frame.mod->byte(frame.position)) | (static_cast(frame.mod->byte(frame.position + 1)) << 8); + frame.position += 2; push_thing(load_thing(variable)); } break; case instruction_t::Store: { variable_t variable = static_cast(frame.mod->byte(frame.position)) | (static_cast(frame.mod->byte(frame.position + 1)) << 8); + frame.position += 2; store_thing(variable, std::move(pop_thing())); } break; case instruction_t::Call: { @@ -161,6 +163,14 @@ void executor::step() { } break; } } break; + case instruction_t::Jump: { + frame.position += frame.mod->byte(frame.position++); + } break; + case instruction_t::JumpNotZero: { + byte offset = frame.mod->byte(frame.position++); + auto cond = pop_thing(); + if (cond->int32() != 0) frame.position += offset; + } break; case instruction_t::Return: { pop_frame(); if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;