diff --git a/furvm/include/furvm/instruction.hpp b/furvm/include/furvm/instruction.hpp index 59c0cc4..81c2e2e 100644 --- a/furvm/include/furvm/instruction.hpp +++ b/furvm/include/furvm/instruction.hpp @@ -125,6 +125,11 @@ enum class instruction_t : byte { */ Sizeof, + /** + * @brief Pushes a length of popped-off thing onto the stack. + */ + Lengthof, + /** * @brief Pushes a variable onto the stack. * diff --git a/furvm/include/furvm/thing.hpp b/furvm/include/furvm/thing.hpp index 3d8c368..1c3256b 100644 --- a/furvm/include/furvm/thing.hpp +++ b/furvm/include/furvm/thing.hpp @@ -453,7 +453,7 @@ public: return { *m_type.value.array.type, data + (index * elementSize), m_allocator }; } - std::size_t size() const { + thing_type::u64 length() const { if (m_type.type != thing_type::Array) throw bad_thing_access(); return m_type.value.array.size == 0 ? get().dynamic.size : m_type.value.array.size; } diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 73d46b8..ed40b88 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -245,13 +245,19 @@ void executor::step() { break; case thing_type::Ptr: size->get() = static_cast(sizeof(void*)); break; case thing_type::Array: - size->get() = static_cast( - (thing->type().value.array.size == 0) ? thing->get::array>().dynamic.size - : thing->type().value.array.size); + /* TODO: Return actual memory size of the array + * By the memory size I mean the length times sizeof single element. + */ + size->get() = thing->length(); break; default: throw std::runtime_error("unreachable"); } } break; + case instruction_t::Lengthof: { + auto thing = pop_thing(); + auto length = push_thing({ (struct thing_type){ thing_type::U64 }, m_context->thing_alloc() }); + length->get() = thing->length(); + } break; case instruction_t::Load: { variable_t variable = static_cast(frame.mod->byte(frame.position)) | (static_cast(frame.mod->byte(frame.position + 1)) << 8); diff --git a/furvm/src/main.cpp b/furvm/src/main.cpp index 0054bb2..f86259a 100644 --- a/furvm/src/main.cpp +++ b/furvm/src/main.cpp @@ -24,7 +24,7 @@ static void print_thing(const furvm::thing& thing) { case thing_type::U64: std::cout << thing.get(); break; case furvm::thing_type::Array: std::cout << "{ "; - for (thing_type::u64 i = 0; i < thing.size(); ++i) { + for (thing_type::u64 i = 0; i < thing.length(); ++i) { if (i > 0) std::cout << ", "; print_thing(thing.at(i)); } @@ -58,7 +58,7 @@ int main(int argc, char** argv) { 0, 0, 0, - static_cast(furvm::instruction_t::Pointerof), + static_cast(furvm::instruction_t::Lengthof), static_cast(furvm::instruction_t::Call), 1, 0, @@ -68,8 +68,9 @@ int main(int argc, char** argv) { auto mod = context->emplace("main", s_bytecode, s_bytecode + sizeof(s_bytecode)); auto charType = mod->emplace_type(furvm::mod_type::S8); auto arrayType = mod->emplace_type(charType.id(), 10); + auto u64Type = mod->emplace_type(furvm::mod_type::U64); auto mainFunc = mod->emplace_function("main", furvm::function_sig{}, 0); - mod->emplace_function(furvm::function_sig{ { arrayType } }, "print").dispatch(); + mod->emplace_function(furvm::function_sig{ { u64Type } }, "print").dispatch(); #endif mod->set_native_function("print", [](furvm::executor& executor) { print_thing(*executor.load_thing(0));