diff --git a/furvm/include/furvm/instruction.hpp b/furvm/include/furvm/instruction.hpp index 7d0a9ed..99b1317 100644 --- a/furvm/include/furvm/instruction.hpp +++ b/furvm/include/furvm/instruction.hpp @@ -56,6 +56,7 @@ struct instruction { PushU32, PushConstant, Array, + Slice, Get, Set, Drop, diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 308e173..e1a9862 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -38,6 +38,8 @@ thing_type executor::thing_type_impl(mod_h mod, mod_type type) const { return { static_cast(type.type), { mod_to_thing_type(mod, *mod->type_at(type.value.array.typeId)), type.value.array.size } }; } + case thing_type::Slice: + return { thing_type::Slice, mod_to_thing_type(mod, *mod->type_at(type.value.slice.typeId)) }; case thing_type::Count: break; } throw std::runtime_error("invalid thing type"); @@ -64,6 +66,7 @@ bool executor::compare_thing_types(const thing_type& lhs, const thing_type& rhs) case thing_type::Array: return lhs.value.array.size == rhs.value.array.size && compare_thing_types(*lhs.value.array.type, *rhs.value.array.type); + case thing_type::Slice: return compare_thing_types(*lhs.value.slice.type, *rhs.value.slice.type); case thing_type::Count: break; } throw std::runtime_error("unreachable"); @@ -83,7 +86,7 @@ void executor::push_frame(const mod_h& mod, function function) { args.reserve(signature.params.size()); for (const auto& param : signature.params) { auto arg = pop_thing(); - if (compare_thing_types(arg.type(), *mod_to_thing_type(mod, *param))) + if (!compare_thing_types(arg.type(), *mod_to_thing_type(mod, *param))) throw std::runtime_error("function argument type mismatch"); args.emplace_back(std::move(arg)); } @@ -265,6 +268,12 @@ void executor::step() { array.resize(size); } } break; + case instruction_t::Slice: { + auto length = pop_thing(); + auto start = pop_thing(); + auto array = pop_thing(); + push_thing(array.slice(start.integer(), length.integer())); + } break; case instruction_t::Get: { auto index = pop_thing(); auto array = pop_thing(); diff --git a/furvm/src/instruction.cpp b/furvm/src/instruction.cpp index d97ba26..2bc572f 100644 --- a/furvm/src/instruction.cpp +++ b/furvm/src/instruction.cpp @@ -83,6 +83,8 @@ const instruction_argument_t instruction::s_arguments[instruction::Count] = { instruction_argument::Constant, // Array: instruction_argument::Type, + // Slice: + instruction_argument::None, // Get: instruction_argument::None, // Set: