diff --git a/furvm/include/furvm/type.hpp b/furvm/include/furvm/type.hpp index 6e18d46..d4d52d3 100644 --- a/furvm/include/furvm/type.hpp +++ b/furvm/include/furvm/type.hpp @@ -5,6 +5,7 @@ #include "furvm/handle.hpp" // IWYU pragma: keep #include +#include namespace furvm { @@ -29,11 +30,17 @@ struct array_type { * Size of the array. If size is equal to zero, then the array becomes dynamic. */ std::size_t size; + + bool operator==(const array_type& rhs) const { return type == rhs.type && size == rhs.size; } + bool operator!=(const array_type& rhs) const { return !this->operator==(rhs); } }; struct import_type { mod_id mod; type_id type; + + bool operator==(const import_type& rhs) const { return mod == rhs.mod && type == rhs.type; } + bool operator!=(const import_type& rhs) const { return !this->operator==(rhs); } }; struct type { @@ -108,6 +115,18 @@ struct type { return *this; } + + bool operator==(const type& rhs) const { + if (t != rhs.t) return false; + switch (t) { + case type_t::Primitive: return primitive == rhs.primitive; + case type_t::Array: return array == rhs.array; + case type_t::Import: return imp == rhs.imp; + } + throw std::runtime_error("unreachable"); + } + + bool operator!=(const type& rhs) const { return !this->operator==(rhs); } }; using byte_t = std::int8_t; /**< A 1-byte integer. */ diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index c74cb57..1cdec80 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -21,10 +21,14 @@ void executor::push_frame(const mod_h& mod, function function) { function = *modInst->function_at(function.imp().function); } + auto signature = function.signature(); std::vector args; - args.reserve(function.signature().params.size()); - while (args.size() < args.capacity()) - args.push_back(pop_thing()); + args.reserve(signature.params.size()); + for (const auto& param : signature.params) { + auto arg = pop_thing(); + if (arg->type().type != param) throw std::runtime_error("function argument type mismatch"); + args.push_back(std::move(arg)); + } switch (function.type()) { case function_t::Normal: {