feat: introduce array and get instruction

This commit is contained in:
2026-07-06 10:53:48 +02:00
parent 81a439b2ad
commit 7c74850aff
4 changed files with 106 additions and 16 deletions
+13
View File
@@ -25,6 +25,19 @@ enum class instruction_t : byte {
*/
PushConstant,
/**
* @brief Pushes a new array onto the stack.
*
* Type is the next 4 bytes in little-endian.
* If the type is dynamic the array's size will be popped off of the stack.
*/
Array,
/**
* @brief Pushes an element from an array onto the stack.
*/
Get,
/**
* @brief Pops top element from the stack.
*/
+25 -10
View File
@@ -283,24 +283,39 @@ public:
if (m_type->t != type_t::Array) throw bad_thing_access();
if (m_type->array.size > 0) throw std::runtime_error("cannot resize a static array");
auto& list = get<array_t>();
if (newSize < 0 || newSize == list.size) return;
auto& array = get<array_t>();
if (newSize < 0 || newSize == array.dynamic.size) return;
std::size_t innerSize = compute_size_na(*m_type->array.type);
std::byte* newData = new std::byte[innerSize * newSize];
std::memcpy(newData, list.data, innerSize * std::min(list.size, newSize));
list.size = newSize;
delete[] list.data;
list.data = newData;
std::memcpy(newData, array.dynamic.data, innerSize * std::min(array.dynamic.size, newSize));
array.dynamic.size = newSize;
delete[] array.dynamic.data;
array.dynamic.data = newData;
}
thing at(long_t index) const {
if (m_type->t != type_t::Array) throw bad_thing_access();
auto& list = get<array_t>();
if (index < 0 || index >= list.size) throw std::out_of_range("index out of range");
thing res = { std::make_shared<type>(m_type->array.type), m_modules, m_allocator };
res.get<reference_t>() = list.data; // TODO: Account for padding, alignment and stuff
std::size_t elementSize = compute_size_na(*m_type->array.type);
thing res = { std::make_shared<class type>(*m_type->array.type), m_modules, m_allocator };
if (m_type->array.size == 0) {
auto& array = get<array_t>();
if (index < 0 || index >= array.dynamic.size) throw std::out_of_range("index out of range");
res.get<reference_t>() = array.dynamic.data + (index * elementSize);
return std::move(res);
}
std::byte* data = reinterpret_cast<array_t*>(m_data)->data;
if (index < 0 || index >= m_type->array.size) throw std::out_of_range("index out of range");
res.get<reference_t>() = data + (index * elementSize);
return std::move(res);
}
std::size_t size() const {
if (m_type->t != type_t::Array) throw std::runtime_error("not an array");
if (m_type->array.size == 0) return get<array_t>().dynamic.size;
return m_type->array.size;
}
public:
static type_p resolve_type(const type_p& initType, const mod_container& modules) {
type_p rsv = initType;