Merge branch 'furvm' into ssa

This commit is contained in:
2026-06-15 17:40:26 +02:00
5 changed files with 215 additions and 3 deletions
+45
View File
@@ -65,6 +65,36 @@ enum class instruction_t : byte {
*/ */
Mod, Mod,
/**
* @brief Compares two top-most things from the stack for equality.
*/
Equals,
/**
* @brief Compares two top-most things from the stack for inequality.
*/
NotEquals,
/**
* @brief Compares if the first top-most thing is less than the second top-most thing.
*/
LessThan,
/**
* @brief Compares if the first top-most thing is greater than the second top-most thing.
*/
GreaterThan,
/**
* @brief Compares if the first top-most thing is less than or equal to the second top-most thing.
*/
LessEqual,
/**
* @brief Compares if the first top-most thing is greater than or equal to the second top-most thing.
*/
GreaterEqual,
/** /**
* @brief Pushes a variable onto the stack. * @brief Pushes a variable onto the stack.
* *
@@ -86,6 +116,21 @@ enum class instruction_t : byte {
*/ */
Call, Call,
/**
* @brief Jumps to an instruction relative to the current instruction.
*
* Jumps to an instruction relative to the current instruction with offset denoted by next byte.
*/
Jump,
/**
* @brief Jumps to an instruction relative to the current instruction if top thing on the stack is not zero.
*
* Jumps to an instruction relative to the current instruction with offset denoted by next byte if the top thing on
* the stack is not zero (is true).
*/
JumpNotZero,
/** /**
* @brief Pops the current call frame. * @brief Pops the current call frame.
*/ */
+54 -1
View File
@@ -135,6 +135,59 @@ public:
* @return Shared pointer to result thing. * @return Shared pointer to result thing.
*/ */
friend thing_p operator%(const thing_p& lhs, const thing_p& rhs); friend thing_p operator%(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares two things for equality.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator==(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares two things for equality.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator!=(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is less than the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator<(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is greater than the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator>(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is less than or equal to the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator<=(const thing_p& lhs, const thing_p& rhs);
/**
* @brief Compares if the left thing is greater than or equal to the right thing.
*
* @param lhs Left-hand-side thing.
* @param rhs Right-hand-side thing.
* @return Shared pointer to result thing.
*/
friend thing_p operator>=(const thing_p& lhs, const thing_p& rhs);
public: public:
/** /**
* @brief Returns a new thing. * @brief Returns a new thing.
@@ -208,4 +261,4 @@ private:
} // namespace furvm } // namespace furvm
#endif // FURVM_THING_HPP #endif // FURVM_THING_HPP
+40
View File
@@ -136,14 +136,46 @@ void executor::step() {
auto lhs = pop_thing(); auto lhs = pop_thing();
push_thing(lhs % rhs); push_thing(lhs % rhs);
} break; } break;
case instruction_t::Equals: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs == rhs);
} break;
case instruction_t::NotEquals: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs != rhs);
} break;
case instruction_t::LessThan: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs < rhs);
} break;
case instruction_t::GreaterThan: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs > rhs);
} break;
case instruction_t::LessEqual: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs <= rhs);
} break;
case instruction_t::GreaterEqual: {
auto rhs = pop_thing();
auto lhs = pop_thing();
push_thing(lhs >= rhs);
} break;
case instruction_t::Load: { case instruction_t::Load: {
variable_t variable = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) | 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); (static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
frame.position += 2;
push_thing(load_thing(variable)); push_thing(load_thing(variable));
} break; } break;
case instruction_t::Store: { case instruction_t::Store: {
variable_t variable = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) | 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); (static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
frame.position += 2;
store_thing(variable, std::move(pop_thing())); store_thing(variable, std::move(pop_thing()));
} break; } break;
case instruction_t::Call: { case instruction_t::Call: {
@@ -161,6 +193,14 @@ void executor::step() {
} break; } break;
} }
} break; } break;
case instruction_t::Jump: {
frame.position += frame.mod->byte(frame.position++);
} break;
case instruction_t::JumpNotZero: {
byte offset = frame.mod->byte(frame.position++);
auto cond = pop_thing();
if (cond->int32() != 0) frame.position += offset;
} break;
case instruction_t::Return: { case instruction_t::Return: {
pop_frame(); pop_frame();
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done; if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
+9 -1
View File
@@ -17,6 +17,10 @@ function::function(function&& other) noexcept
case function_t::Native: { case function_t::Native: {
new (&m_value.native) native_function(std::move(other.m_value.native)); new (&m_value.native) native_function(std::move(other.m_value.native));
} break; } break;
case function_t::Import: {
m_value.imp.mod = other.m_value.imp.mod;
m_value.imp.function = other.m_value.imp.function;
} break;
} }
other.m_value.position = 0; other.m_value.position = 0;
} }
@@ -34,10 +38,14 @@ function& function::operator=(function&& other) noexcept {
case function_t::Native: { case function_t::Native: {
new (&m_value.native) native_function(std::move(other.m_value.native)); new (&m_value.native) native_function(std::move(other.m_value.native));
} break; } break;
case function_t::Import: {
m_value.imp.mod = other.m_value.imp.mod;
m_value.imp.function = other.m_value.imp.function;
} break;
} }
other.m_value.position = 0; other.m_value.position = 0;
return *this; return *this;
} }
} // namespace furvm } // namespace furvm
+67 -1
View File
@@ -141,6 +141,72 @@ thing_p operator%(const thing_p& lhs, const thing_p& rhs) {
} }
} }
thing_p operator==(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() == rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p operator!=(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() != rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p operator<(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() < rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p operator>(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() > rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p operator<=(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() <= rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p operator>=(const thing_p& lhs, const thing_p& rhs) {
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
auto res = thing::create(lhs->m_context, thing_t::Int32);
res->int32() = static_cast<std::int32_t>(lhs->int32() >= rhs->int32());
return res;
}
default: throw std::runtime_error("unexpected operator");
}
}
thing_p thing::clone(const thing_p& thing) { thing_p thing::clone(const thing_p& thing) {
thing_handle id = thing->m_context->m_things.size(); thing_handle id = thing->m_context->m_things.size();
if (!thing->m_context->m_deadThings.empty()) { if (!thing->m_context->m_deadThings.empty()) {
@@ -174,4 +240,4 @@ const std::int32_t& thing::int32() const {
} // namespace furvm } // namespace furvm
// NOLINTEND(cppcoreguidelines-no-malloc) // NOLINTEND(cppcoreguidelines-no-malloc)