+1
-1
@@ -68,7 +68,7 @@ int main(void) {
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
furvmMod->set_native_function("print",
|
furvmMod->set_native_function("print",
|
||||||
[](furvm::executor& executor) { std::cout << executor.load_thing(0)->get<furvm::int_t>() << '\n'; });
|
[](furvm::executor& executor) { std::cout << executor.load_thing(0)->integer() << '\n'; });
|
||||||
|
|
||||||
furvm::executor_h executor = context->emplace_executor(context);
|
furvm::executor_h executor = context->emplace_executor(context);
|
||||||
executor->push_frame(furvmMod, *furvmMod->function_at("main"));
|
executor->push_frame(furvmMod, *furvmMod->function_at("main"));
|
||||||
|
|||||||
@@ -27,13 +27,31 @@ struct thing_type {
|
|||||||
std::uint64_t value;
|
std::uint64_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using byte_t = std::int8_t; /**< A 1-byte integer. */
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A 1-byte integer thing type.
|
||||||
|
*/
|
||||||
|
static constexpr thing_type ByteType = { thing_type_t::Primitive, sizeof(byte_t) };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A 2-byte integer thing type.
|
||||||
|
*/
|
||||||
|
static constexpr thing_type ShortType = { thing_type_t::Primitive, sizeof(short_t) };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A 4-byte integer thing type.
|
* @brief A 4-byte integer thing type.
|
||||||
*/
|
*/
|
||||||
static constexpr thing_type IntType = { thing_type_t::Primitive, sizeof(int_t) };
|
static constexpr thing_type IntType = { thing_type_t::Primitive, sizeof(int_t) };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An 8-byte integer thing type.
|
||||||
|
*/
|
||||||
|
static constexpr thing_type LongType = { thing_type_t::Primitive, sizeof(long_t) };
|
||||||
|
|
||||||
template <template <typename> typename Allocator>
|
template <template <typename> typename Allocator>
|
||||||
class thing final {
|
class thing final {
|
||||||
friend class executor;
|
friend class executor;
|
||||||
@@ -238,24 +256,36 @@ public:
|
|||||||
* @return A boolean result of the comparison in a thing form.
|
* @return A boolean result of the comparison in a thing form.
|
||||||
*/
|
*/
|
||||||
thing greater_equals(const thing& rhs) const { return binary_op(rhs, std::greater_equal<>{}); }
|
thing greater_equals(const thing& rhs) const { return binary_op(rhs, std::greater_equal<>{}); }
|
||||||
private:
|
public:
|
||||||
// TODO: Change to `to_long` after introducing long type.
|
/**
|
||||||
int_t to_int() const {
|
* @brief Returns a largest integer value of the thing.
|
||||||
|
*
|
||||||
|
* @return The integer value.
|
||||||
|
*/
|
||||||
|
long_t integer() const {
|
||||||
if (m_type.type != thing_type_t::Primitive) throw bad_thing_access();
|
if (m_type.type != thing_type_t::Primitive) throw bad_thing_access();
|
||||||
switch (m_type.value) {
|
switch (m_type.value) {
|
||||||
|
case sizeof(byte_t): return get<byte_t>();
|
||||||
|
case sizeof(short_t): return get<short_t>();
|
||||||
case sizeof(int_t): return get<int_t>();
|
case sizeof(int_t): return get<int_t>();
|
||||||
|
case sizeof(long_t): return get<long_t>();
|
||||||
default: throw std::runtime_error("unreachable");
|
default: throw std::runtime_error("unreachable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 {
|
||||||
if (type().type == thing_type_t::Primitive && rhs.type().type == thing_type_t::Primitive) {
|
if (type().type == thing_type_t::Primitive && rhs.type().type == thing_type_t::Primitive) {
|
||||||
std::size_t size = std::max(type().value, rhs.type().value);
|
std::size_t size = std::max(type().value, rhs.type().value);
|
||||||
|
|
||||||
|
long_t result = op(integer(), rhs.integer());
|
||||||
|
|
||||||
thing res(thing_type{ thing_type_t::Primitive, size }, m_allocator);
|
thing res(thing_type{ thing_type_t::Primitive, size }, m_allocator);
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case sizeof(int_t): res.get<int_t>() = op(to_int(), rhs.to_int()); break;
|
case sizeof(byte_t): res.get<byte_t>() = result; break;
|
||||||
|
case sizeof(short_t): res.get<short_t>() = result; break;
|
||||||
|
case sizeof(int_t): res.get<int_t>() = result; break;
|
||||||
|
case sizeof(long_t): res.get<long_t>() = result; break;
|
||||||
default: throw std::runtime_error("unreachable");
|
default: throw std::runtime_error("unreachable");
|
||||||
}
|
}
|
||||||
return std::move(res);
|
return std::move(res);
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ int main(void) {
|
|||||||
furvm::mod_h furlangModule = context->emplace_module("furlang");
|
furvm::mod_h furlangModule = context->emplace_module("furlang");
|
||||||
furvm::function_h printFunc = furlangModule->emplace_function("print", 1, "print");
|
furvm::function_h printFunc = furlangModule->emplace_function("print", 1, "print");
|
||||||
furlangModule->set_native_function("print",
|
furlangModule->set_native_function("print",
|
||||||
[](furvm::executor& executor) { std::cout << executor.load_thing(0)->get<furvm::int_t>() << '\n'; });
|
[](furvm::executor& executor) { std::cout << executor.load_thing(0)->integer() << '\n'; });
|
||||||
|
|
||||||
furvm::mod_h mainModule = context->emplace_module("main", s_bytecode.begin(), s_bytecode.end());
|
furvm::mod_h mainModule = context->emplace_module("main", s_bytecode.begin(), s_bytecode.end());
|
||||||
furvm::function_h mainFunc = mainModule->emplace_function("main", 0, 0);
|
furvm::function_h mainFunc = mainModule->emplace_function("main", 0, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user