feat: introduce pointerof operation
Introduce pointerof operation and do some side-quests along the way. Refs: #34 Closes: #17
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user