feat: introduce pointerof operation

Introduce pointerof operation and do some side-quests along the way.

Refs: #34
Closes: #17
This commit is contained in:
2026-07-05 14:54:16 +02:00
parent 9690ac3617
commit 642d57622a
13 changed files with 290 additions and 141 deletions
+5
View File
@@ -102,6 +102,11 @@ enum class instruction_t : byte {
*/
GreaterEqual,
/**
* @brief Pushes a pointer of popped-off thing onto the stack.
*/
Pointerof,
/**
* @brief Pushes a variable onto the stack.
*
+10 -3
View File
@@ -114,6 +114,13 @@ public:
* @return The type.
*/
constexpr auto type() const { return *m_type; }
/**
* @brief Returns the thing's type.
*
* @return The shared pointer to the type.
*/
auto type() { return m_type; }
public:
/**
* @brief Returns a raw data pointer.
@@ -265,7 +272,7 @@ public:
thing resolve() const {
thing rsv = { resolve_type(m_type, m_modules), m_data, m_allocator };
while (rsv.type().t == type_t::Reference)
while (rsv.type()->t == type_t::Reference)
rsv = { rsv.m_type->reference, rsv.get<reference_t>(), std::move(rsv.m_allocator) };
return rsv;
}
@@ -342,8 +349,8 @@ private:
private:
template <typename Op>
thing binary_op(const thing& rhs, const Op& op) const {
thing lhsRsv = resolve();
thing rhsRsv = rhs.resolve();
const thing lhsRsv = resolve();
const thing rhsRsv = rhs.resolve();
if (lhsRsv.type().t == type_t::Primitive && rhsRsv.type().t == type_t::Primitive) {
std::size_t size = std::max(lhsRsv.type().primitive, rhsRsv.type().primitive);
+13
View File
@@ -162,6 +162,19 @@ void executor::step() {
auto lhs = pop_thing();
push_thing(lhs->greater_equals(*rhs));
} break;
case instruction_t::Pointerof: {
auto thing = pop_thing()->resolve();
auto ptr = push_thing({ *m_context->at("core")->type_at(4), m_context, m_context->thing_alloc() });
switch (furvm::thing<>::resolve_type(thing.type(), m_context)->t) {
case type_t::Primitive: ptr->get<std::uintptr_t>() = reinterpret_cast<std::uintptr_t>(thing.raw()); break;
case type_t::List:
ptr->get<std::uintptr_t>() = reinterpret_cast<std::uintptr_t>(thing.get<list_t>().data);
break;
case type_t::Reference:
case type_t::Import:
default: throw std::runtime_error("unreachable");
}
} break;
case instruction_t::Load: {
variable_t variable = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);