diff --git a/furvm/include/furvm/function.hpp b/furvm/include/furvm/function.hpp index 879b81d..2b3fb93 100644 --- a/furvm/include/furvm/function.hpp +++ b/furvm/include/furvm/function.hpp @@ -12,6 +12,7 @@ namespace furvm { enum class function_t : std::uint8_t { Normal = 0, /**< A normal bytecode function. */ Native, /**< A native function implemented through furvm API. */ + Import, /**< A function imported from another module. */ }; using native_function = std::function; @@ -117,6 +118,26 @@ public: if (m_type != function_t::Native) throw std::runtime_error("function type mismatch"); return m_value.native; } + + /** + * @brief Returns a module of imported function. + * + * @return A handle to the module. + */ + module_handle imported_module() const { + if (m_type != function_t::Import) throw std::runtime_error("function type mismatch"); + return m_value.imp.mod; + } + + /** + * @brief Returns a module of imported function. + * + * @return A handle to the module. + */ + function_handle imported_function() const { + if (m_type != function_t::Import) throw std::runtime_error("function type mismatch"); + return m_value.imp.function; + } private: function_handle m_id; function_t m_type; @@ -125,6 +146,10 @@ private: union value { std::size_t position = 0; native_function native; + struct { + module_handle mod; + function_handle function; + } imp; value() = default; @@ -134,6 +159,9 @@ private: value(const native_function& native) : native(native) {} + value(module_handle mod, function_handle function) + : imp({ mod, function }) {} + ~value() {} value(value&& other) = delete; @@ -145,4 +173,4 @@ private: } // namespace furvm -#endif // FURVM_FUNCTION_HPP \ No newline at end of file +#endif // FURVM_FUNCTION_HPP diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 2adf9f6..4a6cb78 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -118,6 +118,10 @@ void executor::step() { switch (function->type()) { case function_t::Normal: push_frame(function); break; case function_t::Native: function->native()(*this); break; + case function_t::Import: { + const mod_p& impMod = m_context->m_modules.at(function->imported_module()); + push_frame(impMod->function_at(function->imported_function())); + } break; } } break; case instruction_t::Return: { @@ -134,4 +138,4 @@ void executor::step() { } } -} // namespace furvm \ No newline at end of file +} // namespace furvm diff --git a/furvm/src/main.cpp b/furvm/src/main.cpp index 22ad1c1..87ebe72 100644 --- a/furvm/src/main.cpp +++ b/furvm/src/main.cpp @@ -49,4 +49,4 @@ int main(void) { return 0; } -#endif // LUBFURVM \ No newline at end of file +#endif // LUBFURVM