refactor: replace type_p with type_ref in thing
Damn, this was such a great call. Closes: #46
This commit is contained in:
@@ -28,19 +28,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Constructs a thing.
|
* @brief Constructs a thing.
|
||||||
*
|
*
|
||||||
* @param type Thing type.
|
* @param type Thing type reference.
|
||||||
* @param allocator Allocator for the thing's data.
|
* @param allocator Allocator for the thing's data.
|
||||||
*/
|
*/
|
||||||
thing(const type& type, const mod_container& modules = nullptr, const allocator_type& allocator = {})
|
thing(const type_ref& type, const mod_container& modules = nullptr, const allocator_type& allocator = {})
|
||||||
: thing(std::make_shared<class type>(type), modules, allocator) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Constructs a thing.
|
|
||||||
*
|
|
||||||
* @param type Thing type.
|
|
||||||
* @param allocator Allocator for the thing's data.
|
|
||||||
*/
|
|
||||||
thing(const type_p& type, const mod_container& modules = nullptr, const allocator_type& allocator = {})
|
|
||||||
: m_type(type), m_size(compute_size(resolve_type(type, modules))), m_modules(modules), m_allocator(allocator) {
|
: m_type(type), m_size(compute_size(resolve_type(type, modules))), m_modules(modules), m_allocator(allocator) {
|
||||||
// TODO: Account for alignment
|
// TODO: Account for alignment
|
||||||
m_data = m_allocator.allocate(m_size);
|
m_data = m_allocator.allocate(m_size);
|
||||||
@@ -94,15 +85,16 @@ public:
|
|||||||
* @return A clone of this thing.
|
* @return A clone of this thing.
|
||||||
*/
|
*/
|
||||||
thing clone() const {
|
thing clone() const {
|
||||||
auto type = resolve_type(m_type, m_modules);
|
auto type = resolve_type(m_type, m_modules);
|
||||||
|
if (m_size == 0) {
|
||||||
|
return reference();
|
||||||
|
}
|
||||||
|
|
||||||
thing res(type, m_modules, m_allocator);
|
thing res(type, m_modules, m_allocator);
|
||||||
switch (type->t) {
|
switch (type->t) {
|
||||||
case type_t::Primitive:
|
case type_t::Primitive:
|
||||||
case type_t::Reference: {
|
|
||||||
std::memcpy(res.m_data, m_data, m_size);
|
|
||||||
} break;
|
|
||||||
case type_t::Array: {
|
case type_t::Array: {
|
||||||
copy_list(type, res.get<array_t>(), get<array_t>());
|
copy_list(*type.type, res.get<array_t>(), get<array_t>());
|
||||||
} break;
|
} break;
|
||||||
case type_t::Import:
|
case type_t::Import:
|
||||||
default: throw std::runtime_error("unreachable");
|
default: throw std::runtime_error("unreachable");
|
||||||
@@ -111,18 +103,18 @@ public:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns the thing's type.
|
* @brief Returns the thing's type reference.
|
||||||
*
|
*
|
||||||
* @return The type.
|
* @return The type reference.
|
||||||
*/
|
|
||||||
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; }
|
auto type() { return m_type; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the thing's type reference.
|
||||||
|
*
|
||||||
|
* @return The type reference.
|
||||||
|
*/
|
||||||
|
constexpr auto type() const { return m_type; }
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns a raw data pointer.
|
* @brief Returns a raw data pointer.
|
||||||
@@ -266,18 +258,9 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thing reference() const {
|
thing reference() const { return { m_type, m_data, m_modules, m_allocator }; }
|
||||||
thing res = { std::make_shared<class type>(m_type), m_modules, m_allocator };
|
|
||||||
res.get<reference_t>() = m_data;
|
|
||||||
return std::move(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
thing resolve() const {
|
constexpr bool is_reference() const { return m_size == 0; }
|
||||||
thing rsv = { resolve_type(m_type, m_modules), m_data, m_allocator };
|
|
||||||
while (rsv.type()->t == type_t::Reference)
|
|
||||||
rsv = { rsv.m_type->reference, rsv.get<reference_t>(), std::move(rsv.m_allocator) };
|
|
||||||
return rsv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(long_t newSize) {
|
void resize(long_t newSize) {
|
||||||
if (m_type->t != type_t::Array) throw bad_thing_access();
|
if (m_type->t != type_t::Array) throw bad_thing_access();
|
||||||
@@ -297,18 +280,18 @@ public:
|
|||||||
if (m_type->t != type_t::Array) throw bad_thing_access();
|
if (m_type->t != type_t::Array) throw bad_thing_access();
|
||||||
|
|
||||||
std::size_t elementSize = compute_size_na(*m_type->array.type);
|
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) {
|
if (m_type->array.size == 0) {
|
||||||
auto& array = get<array_t>();
|
auto& array = get<array_t>();
|
||||||
if (index < 0 || index >= array.dynamic.size) throw std::out_of_range("index out of range");
|
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 { { m_type.mod, m_type->array.type },
|
||||||
return std::move(res);
|
array.dynamic.data + (index * elementSize),
|
||||||
|
m_modules,
|
||||||
|
m_allocator };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::byte* data = reinterpret_cast<array_t*>(m_data)->data;
|
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");
|
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 { { m_type.mod, m_type->array.type }, data + (index * elementSize), m_modules, m_allocator };
|
||||||
return std::move(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t size() const {
|
std::size_t size() const {
|
||||||
@@ -317,10 +300,12 @@ public:
|
|||||||
return m_type->array.size;
|
return m_type->array.size;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static type_p resolve_type(const type_p& initType, const mod_container& modules) {
|
static type_ref resolve_type(const type_ref& initType, const mod_container& modules) {
|
||||||
type_p rsv = initType;
|
type_ref rsv = initType;
|
||||||
while (rsv->t == type_t::Import)
|
while (rsv->t == type_t::Import) {
|
||||||
rsv = *modules->at(initType->imp.mod)->type_at(initType->imp.type);
|
auto mod = modules->at(initType->imp.mod);
|
||||||
|
rsv = type_ref{ mod, mod->type_at(initType->imp.type) };
|
||||||
|
}
|
||||||
return rsv;
|
return rsv;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -350,8 +335,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (innerType->t) {
|
switch (innerType->t) {
|
||||||
case type_t::Primitive:
|
case type_t::Primitive: std::memcpy(dst.data, src.data, size); break;
|
||||||
case type_t::Reference: std::memcpy(dst.data, src.data, size); break;
|
|
||||||
case type_t::Array:
|
case type_t::Array:
|
||||||
for (std::size_t i = 0; i < size; ++i) {
|
for (std::size_t i = 0; i < size; ++i) {
|
||||||
copy_list(*innerType->array.type,
|
copy_list(*innerType->array.type,
|
||||||
@@ -366,7 +350,6 @@ private:
|
|||||||
static std::size_t compute_size_na(const type_p& type) {
|
static std::size_t compute_size_na(const type_p& type) {
|
||||||
switch (type->t) {
|
switch (type->t) {
|
||||||
case type_t::Primitive: return type->primitive;
|
case type_t::Primitive: return type->primitive;
|
||||||
case type_t::Reference: return sizeof(reference_t);
|
|
||||||
case type_t::Array: {
|
case type_t::Array: {
|
||||||
if (type->array.size == 0) return sizeof(array_t);
|
if (type->array.size == 0) return sizeof(array_t);
|
||||||
return compute_size_na(*type->array.type) * type->array.size;
|
return compute_size_na(*type->array.type) * type->array.size;
|
||||||
@@ -377,23 +360,24 @@ private:
|
|||||||
throw std::runtime_error("unreachable");
|
throw std::runtime_error("unreachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::size_t compute_size_na(const type_ref& type) { return compute_size_na(*type.type); }
|
||||||
|
|
||||||
// NOTE: Align to 4 bytes
|
// NOTE: Align to 4 bytes
|
||||||
static std::size_t compute_size(const type_p& type) { return (compute_size_na(type) + 3) & ~3; }
|
static std::size_t compute_size(const type_p& type) { return (compute_size_na(type) + 3) & ~3; }
|
||||||
|
static std::size_t compute_size(const type_ref& type) { return compute_size(*type.type); }
|
||||||
private:
|
private:
|
||||||
thing(const type_p& type, std::byte* data, const allocator_type& allocator = {})
|
thing(const type_ref& type, std::byte* data, const mod_container& modules, const allocator_type& allocator = {})
|
||||||
: m_type(type), m_size(0), m_data(data), m_allocator(allocator) {}
|
: m_type(type), m_size(0), m_data(data), m_modules(modules), m_allocator(allocator) {}
|
||||||
private:
|
private:
|
||||||
template <typename Op>
|
template <typename Op>
|
||||||
thing binary_op(const thing& rhs, const Op& op) const {
|
thing binary_op(const thing& rhs, const Op& op) const {
|
||||||
const thing lhsRsv = resolve();
|
if (m_type->t == type_t::Primitive && rhs.type()->t == type_t::Primitive) {
|
||||||
const thing rhsRsv = rhs.resolve();
|
type_ref type = m_type->primitive >= rhs.type()->primitive ? m_type : rhs.type();
|
||||||
|
std::size_t size = std::max(m_type->primitive, rhs.type()->primitive);
|
||||||
|
|
||||||
if (lhsRsv.type().t == type_t::Primitive && rhsRsv.type().t == type_t::Primitive) {
|
long_t result = op(integer(), rhs.integer());
|
||||||
std::size_t size = std::max(lhsRsv.type().primitive, rhsRsv.type().primitive);
|
|
||||||
|
|
||||||
long_t result = op(lhsRsv.integer(), rhsRsv.integer());
|
thing res(type, m_modules, m_allocator);
|
||||||
|
|
||||||
thing res({ size }, m_modules, m_allocator);
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case sizeof(byte_t): res.get<byte_t>() = result; break;
|
case sizeof(byte_t): res.get<byte_t>() = result; break;
|
||||||
case sizeof(short_t): res.get<short_t>() = result; break;
|
case sizeof(short_t): res.get<short_t>() = result; break;
|
||||||
@@ -407,7 +391,7 @@ private:
|
|||||||
throw std::runtime_error("unexpected operation");
|
throw std::runtime_error("unexpected operation");
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
type_p m_type;
|
type_ref m_type;
|
||||||
std::size_t m_size;
|
std::size_t m_size;
|
||||||
std::byte* m_data;
|
std::byte* m_data;
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,12 @@ namespace furvm {
|
|||||||
|
|
||||||
enum class type_t : std::uint32_t {
|
enum class type_t : std::uint32_t {
|
||||||
Primitive = 0,
|
Primitive = 0,
|
||||||
Reference,
|
|
||||||
Array,
|
Array,
|
||||||
|
|
||||||
Import,
|
Import,
|
||||||
};
|
};
|
||||||
|
|
||||||
using primitive_type = std::uint64_t;
|
using primitive_type = std::uint64_t;
|
||||||
using reference_type = type_p;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Array type.
|
* @brief Array type.
|
||||||
@@ -41,21 +39,17 @@ struct import_type {
|
|||||||
struct type {
|
struct type {
|
||||||
type_t t;
|
type_t t;
|
||||||
union {
|
union {
|
||||||
primitive_type primitive;
|
primitive_type primitive{};
|
||||||
reference_type reference;
|
|
||||||
array_type array;
|
array_type array;
|
||||||
import_type imp;
|
import_type imp;
|
||||||
};
|
};
|
||||||
|
|
||||||
type(type_t type)
|
type(type_t type)
|
||||||
: t(type), primitive(0) {}
|
: t(type) {}
|
||||||
|
|
||||||
type(primitive_type primitive)
|
type(primitive_type primitive)
|
||||||
: t(type_t::Primitive), primitive(primitive) {}
|
: t(type_t::Primitive), primitive(primitive) {}
|
||||||
|
|
||||||
type(const reference_type& reference)
|
|
||||||
: t(type_t::Reference), reference(reference) {}
|
|
||||||
|
|
||||||
type(const type_h& type, std::size_t size = 0)
|
type(const type_h& type, std::size_t size = 0)
|
||||||
: t(type_t::Array), array(array_type{ type, size }) {}
|
: t(type_t::Array), array(array_type{ type, size }) {}
|
||||||
|
|
||||||
@@ -67,7 +61,6 @@ struct type {
|
|||||||
|
|
||||||
~type() {
|
~type() {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case type_t::Reference: reference.~reference_type(); break;
|
|
||||||
case type_t::Array: array.~array_type(); break;
|
case type_t::Array: array.~array_type(); break;
|
||||||
case type_t::Import: imp.~import_type(); break;
|
case type_t::Import: imp.~import_type(); break;
|
||||||
default: break;
|
default: break;
|
||||||
@@ -78,7 +71,6 @@ struct type {
|
|||||||
: t(other.t) {
|
: t(other.t) {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case type_t::Primitive: primitive = other.primitive; break;
|
case type_t::Primitive: primitive = other.primitive; break;
|
||||||
case type_t::Reference: reference = std::move(other.reference); break;
|
|
||||||
case type_t::Array: array = std::move(other.array); break;
|
case type_t::Array: array = std::move(other.array); break;
|
||||||
case type_t::Import: imp = std::move(other.imp); break;
|
case type_t::Import: imp = std::move(other.imp); break;
|
||||||
}
|
}
|
||||||
@@ -89,7 +81,6 @@ struct type {
|
|||||||
t = other.t;
|
t = other.t;
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case type_t::Primitive: primitive = other.primitive; break;
|
case type_t::Primitive: primitive = other.primitive; break;
|
||||||
case type_t::Reference: reference = std::move(other.reference); break;
|
|
||||||
case type_t::Array: array = std::move(other.array); break;
|
case type_t::Array: array = std::move(other.array); break;
|
||||||
case type_t::Import: imp = std::move(other.imp); break;
|
case type_t::Import: imp = std::move(other.imp); break;
|
||||||
}
|
}
|
||||||
@@ -101,7 +92,6 @@ struct type {
|
|||||||
: t(other.t) {
|
: t(other.t) {
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case type_t::Primitive: primitive = other.primitive; break;
|
case type_t::Primitive: primitive = other.primitive; break;
|
||||||
case type_t::Reference: reference = other.reference; break;
|
|
||||||
case type_t::Array: array = other.array; break;
|
case type_t::Array: array = other.array; break;
|
||||||
case type_t::Import: imp = other.imp; break;
|
case type_t::Import: imp = other.imp; break;
|
||||||
}
|
}
|
||||||
@@ -112,7 +102,6 @@ struct type {
|
|||||||
t = other.t;
|
t = other.t;
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case type_t::Primitive: primitive = other.primitive; break;
|
case type_t::Primitive: primitive = other.primitive; break;
|
||||||
case type_t::Reference: reference = other.reference; break;
|
|
||||||
case type_t::Array: array = other.array; break;
|
case type_t::Array: array = other.array; break;
|
||||||
case type_t::Import: imp = other.imp; break;
|
case type_t::Import: imp = other.imp; break;
|
||||||
}
|
}
|
||||||
@@ -126,8 +115,6 @@ using short_t = std::int16_t; /**< A 2-byte integer. */
|
|||||||
using int_t = std::int32_t; /**< A 4-byte integer. */
|
using int_t = std::int32_t; /**< A 4-byte integer. */
|
||||||
using long_t = std::int64_t; /**< An 8-byte integer. */
|
using long_t = std::int64_t; /**< An 8-byte integer. */
|
||||||
|
|
||||||
using reference_t = std::byte*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Array type's data layout.
|
* @brief Array type's data layout.
|
||||||
*/
|
*/
|
||||||
@@ -159,6 +146,17 @@ inline static type intType = { sizeof(int_t) }; // NOLINT
|
|||||||
*/
|
*/
|
||||||
inline static type longType = { sizeof(long_t) }; // NOLINT
|
inline static type longType = { sizeof(long_t) }; // NOLINT
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reference to a type.
|
||||||
|
*/
|
||||||
|
struct type_ref {
|
||||||
|
mod_h mod;
|
||||||
|
type_h type;
|
||||||
|
|
||||||
|
class type* operator->() { return &**type; }
|
||||||
|
const class type* operator->() const { return &**type; }
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace furvm
|
} // namespace furvm
|
||||||
|
|
||||||
#endif // FURVM_TYPE_HPP
|
#endif // FURVM_TYPE_HPP
|
||||||
|
|||||||
+16
-14
@@ -83,6 +83,10 @@ thing_h executor::load_thing(variable_t variable) const {
|
|||||||
return frame.variables[variable];
|
return frame.variables[variable];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static type_ref get_type_ref(const mod_h& mod, type_id id) {
|
||||||
|
return { mod, mod->type_at(id) };
|
||||||
|
}
|
||||||
|
|
||||||
void executor::step() {
|
void executor::step() {
|
||||||
if ((m_flags & executor_flags::Suspended) == executor_flags::Suspended) return;
|
if ((m_flags & executor_flags::Suspended) == executor_flags::Suspended) return;
|
||||||
|
|
||||||
@@ -92,7 +96,7 @@ void executor::step() {
|
|||||||
switch (instr) {
|
switch (instr) {
|
||||||
case instruction_t::NoOperation: break;
|
case instruction_t::NoOperation: break;
|
||||||
case instruction_t::PushB2I: {
|
case instruction_t::PushB2I: {
|
||||||
push_thing({ *m_context->at("core")->type_at(2), m_context, m_context->thing_alloc() })->get<int_t>() =
|
push_thing({ get_type_ref(m_context->at("core"), 2), m_context, m_context->thing_alloc() })->get<int_t>() =
|
||||||
frame.mod->byte(frame.position++);
|
frame.mod->byte(frame.position++);
|
||||||
} break;
|
} break;
|
||||||
case instruction_t::Array: {
|
case instruction_t::Array: {
|
||||||
@@ -102,8 +106,8 @@ void executor::step() {
|
|||||||
(static_cast<type_id>(frame.mod->byte(frame.position + 3)) << 24);
|
(static_cast<type_id>(frame.mod->byte(frame.position + 3)) << 24);
|
||||||
frame.position += 4;
|
frame.position += 4;
|
||||||
|
|
||||||
auto type = furvm::thing<>::resolve_type(*frame.mod->type_at(typeId), m_context);
|
auto type = furvm::thing<>::resolve_type(get_type_ref(frame.mod, typeId), m_context);
|
||||||
if (type == nullptr || type->t != type_t::Array || *type->array.type == nullptr)
|
if (*type.type == nullptr || type->t != type_t::Array || *type->array.type == nullptr)
|
||||||
throw std::runtime_error("invalid array type");
|
throw std::runtime_error("invalid array type");
|
||||||
|
|
||||||
auto array = push_thing({ type, m_context, m_context->thing_alloc() });
|
auto array = push_thing({ type, m_context, m_context->thing_alloc() });
|
||||||
@@ -190,29 +194,27 @@ void executor::step() {
|
|||||||
push_thing(lhs->greater_equals(*rhs));
|
push_thing(lhs->greater_equals(*rhs));
|
||||||
} break;
|
} break;
|
||||||
case instruction_t::Pointerof: {
|
case instruction_t::Pointerof: {
|
||||||
auto thing = pop_thing()->resolve();
|
auto thing = pop_thing();
|
||||||
auto ptr = push_thing({ *m_context->at("core")->type_at(4), m_context, m_context->thing_alloc() });
|
auto ptr = push_thing({ get_type_ref(m_context->at("core"), 4), m_context, m_context->thing_alloc() });
|
||||||
switch (furvm::thing<>::resolve_type(thing.type(), m_context)->t) {
|
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::Primitive: ptr->get<std::uintptr_t>() = reinterpret_cast<std::uintptr_t>(thing->raw()); break;
|
||||||
case type_t::Array:
|
case type_t::Array:
|
||||||
ptr->get<std::uintptr_t>() = reinterpret_cast<std::uintptr_t>(thing.get<array_t>().data);
|
ptr->get<std::uintptr_t>() = reinterpret_cast<std::uintptr_t>(thing->get<array_t>().data);
|
||||||
break;
|
break;
|
||||||
case type_t::Reference:
|
|
||||||
case type_t::Import:
|
case type_t::Import:
|
||||||
default: throw std::runtime_error("unreachable");
|
default: throw std::runtime_error("unreachable");
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case instruction_t::Sizeof: {
|
case instruction_t::Sizeof: {
|
||||||
auto thing = pop_thing()->resolve();
|
auto thing = pop_thing();
|
||||||
auto size = push_thing({ *m_context->at("core")->type_at(3), m_context, m_context->thing_alloc() });
|
auto size = push_thing({ get_type_ref(m_context->at("core"), 3), m_context, m_context->thing_alloc() });
|
||||||
auto type = furvm::thing<>::resolve_type(thing.type(), m_context);
|
auto type = furvm::thing<>::resolve_type(thing->type(), m_context);
|
||||||
switch (type->t) {
|
switch (type->t) {
|
||||||
case type_t::Primitive: size->get<long_t>() = static_cast<long_t>(type->primitive); break;
|
case type_t::Primitive: size->get<long_t>() = static_cast<long_t>(type->primitive); break;
|
||||||
case type_t::Array:
|
case type_t::Array:
|
||||||
size->get<long_t>() =
|
size->get<long_t>() =
|
||||||
(type->array.size == 0) ? thing.get<array_t>().dynamic.size : static_cast<long_t>(type->array.size);
|
(type->array.size == 0) ? thing->get<array_t>().dynamic.size : static_cast<long_t>(type->array.size);
|
||||||
break;
|
break;
|
||||||
case type_t::Reference:
|
|
||||||
case type_t::Import:
|
case type_t::Import:
|
||||||
default: throw std::runtime_error("unreachable");
|
default: throw std::runtime_error("unreachable");
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -11,16 +11,15 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
static void print_thing(const furvm::thing<furvm::thing_allocator>& thing) {
|
static void print_thing(const furvm::thing<furvm::thing_allocator>& thing) {
|
||||||
auto rsv = thing.resolve();
|
switch (thing.type()->t) {
|
||||||
switch (rsv.type()->t) {
|
|
||||||
case furvm::type_t::Primitive: {
|
case furvm::type_t::Primitive: {
|
||||||
std::cout << rsv.integer();
|
std::cout << thing.integer();
|
||||||
} break;
|
} break;
|
||||||
case furvm::type_t::Array: {
|
case furvm::type_t::Array: {
|
||||||
std::cout << "{ ";
|
std::cout << "{ ";
|
||||||
for (furvm::long_t i = 0; i < rsv.size(); ++i) {
|
for (furvm::long_t i = 0; i < thing.size(); ++i) {
|
||||||
if (i > 0) std::cout << ", ";
|
if (i > 0) std::cout << ", ";
|
||||||
print_thing(rsv.at(i));
|
print_thing(thing.at(i));
|
||||||
}
|
}
|
||||||
std::cout << " }\n";
|
std::cout << " }\n";
|
||||||
} break;
|
} break;
|
||||||
@@ -52,6 +51,7 @@ int main(int argc, char** argv) {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
static_cast<furvm::byte>(furvm::instruction_t::Reference),
|
||||||
static_cast<furvm::byte>(furvm::instruction_t::Call),
|
static_cast<furvm::byte>(furvm::instruction_t::Call),
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ std::ostream& mod::serialize(std::ostream& os) const {
|
|||||||
auto type = *m_types.at(id);
|
auto type = *m_types.at(id);
|
||||||
switch (type->t) {
|
switch (type->t) {
|
||||||
case type_t::Primitive: detail::serialize(os, type->primitive); break;
|
case type_t::Primitive: detail::serialize(os, type->primitive); break;
|
||||||
case type_t::Reference: throw std::runtime_error("reference type serialization is unimplemented");
|
|
||||||
case type_t::Array: {
|
case type_t::Array: {
|
||||||
detail::serialize(os, type->array.size);
|
detail::serialize(os, type->array.size);
|
||||||
detail::serialize(os, type->array.type.id());
|
detail::serialize(os, type->array.type.id());
|
||||||
@@ -134,7 +133,6 @@ mod mod::load(std::istream& is) {
|
|||||||
detail::load(is, primitive);
|
detail::load(is, primitive);
|
||||||
mod.emplace_type(id, std::make_shared<class type>(primitive)).dispatch();
|
mod.emplace_type(id, std::make_shared<class type>(primitive)).dispatch();
|
||||||
} break;
|
} break;
|
||||||
case type_t::Reference: throw std::runtime_error("reference type serialization is unimplemented");
|
|
||||||
case type_t::Array: {
|
case type_t::Array: {
|
||||||
std::size_t size = 0;
|
std::size_t size = 0;
|
||||||
detail::load(is, size);
|
detail::load(is, size);
|
||||||
|
|||||||
Reference in New Issue
Block a user