this code is a mess and I am losing my mind

This commit does not work and I am so down I don't even bother
committing to conventional commits until I fix this mess.
This commit is contained in:
2026-07-19 21:38:00 +02:00
parent 9f950e45e7
commit a1e43576cc
12 changed files with 133 additions and 12 deletions
+13 -2
View File
@@ -1,23 +1,34 @@
type arr = array $s8 11 type arr = array $s8 10
func println $arr = native println func println $arr = native println
public func main = #main public func main = #main
main: main:
array $arr array $arr
dup
store %0 store %0
lenof
push $s32 1
sub
store %1
push $s32 0 push $s32 0
loop: loop:
dup dup
push $s32 10 load %1
eq eq
jnz #end jnz #end
body: body:
dup dup
load %0 load %0
swap
push $s8 69 push $s8 69
set set
push $s32 1
add
jmp #loop jmp #loop
end: end:
drop drop
+34
View File
@@ -0,0 +1,34 @@
type arr = array $s8 10
func println $arr = native println
public func main = #main
main:
array $arr
store %0
push $s32 1
store %1
push $s32 0
loop:
dup
load %1
eq
jnz #end
body:
dup
load %0
swap
push $s8 69
set
push $s32 1
add
jmp #loop
end:
drop
load %0
call $arr println
ret
+23
View File
@@ -0,0 +1,23 @@
func println $u32 = native println
public func main = #main
main:
push $u32 0
store %0
loop_header:
load %0
push $u32 10
ge
jnz #loop_end
loop_body:
load %0
call $u32 println
load %0
push $u32 1
add
store %0
jmp #loop_header
loop_end:
ret
View File
+1
View File
@@ -37,6 +37,7 @@ struct token {
Set, Set,
Drop, Drop,
Dup, Dup,
Swap,
Clone, Clone,
Ref, Ref,
Add, Add,
+13 -1
View File
@@ -40,6 +40,7 @@ std::unordered_map<enum token::type, instruction> instructions = {
{ token::Set, { furvm::instruction_t::Set } }, { token::Set, { furvm::instruction_t::Set } },
{ token::Drop, { furvm::instruction_t::Drop } }, { token::Drop, { furvm::instruction_t::Drop } },
{ token::Dup, { furvm::instruction_t::Duplicate } }, { token::Dup, { furvm::instruction_t::Duplicate } },
{ token::Swap, { furvm::instruction_t::Swap } },
{ token::Clone, { furvm::instruction_t::Clone } }, { token::Clone, { furvm::instruction_t::Clone } },
{ token::Ref, { furvm::instruction_t::Reference } }, { token::Ref, { furvm::instruction_t::Reference } },
{ token::Add, { furvm::instruction_t::Add } }, { token::Add, { furvm::instruction_t::Add } },
@@ -89,6 +90,7 @@ const char* token_type(enum token::type type) {
case token::Set: return "set"; case token::Set: return "set";
case token::Drop: return "drop"; case token::Drop: return "drop";
case token::Dup: return "dup"; case token::Dup: return "dup";
case token::Swap: return "swap";
case token::Clone: return "clone"; case token::Clone: return "clone";
case token::Ref: return "ref"; case token::Ref: return "ref";
case token::Add: return "add"; case token::Add: return "add";
@@ -384,27 +386,36 @@ struct mod_context {
auto it = types.find(std::string(typeName->value.string)); auto it = types.find(std::string(typeName->value.string));
if (it == types.end()) if (it == types.end())
return { generator_error::UnexpectedToken, "Unknown type "s + std::string(typeName->value.string) }; return { generator_error::UnexpectedToken, "Unknown type "s + std::string(typeName->value.string) };
// TODO: Add support for signed integers
auto value = eat_token(lexer, token::Unsigned); auto value = eat_token(lexer, token::Unsigned);
if (!value) return result.error; if (!value) return result.error;
auto type = it->second; auto type = it->second;
switch (type->type) { switch (type->type) {
case furvm::mod_type::S8: { case furvm::mod_type::S8: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS8)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS8));
mod.bytecode().push_back(value->value.uint & 0xFF);
} break; } break;
case furvm::mod_type::U8: { case furvm::mod_type::U8: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU8)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU8));
mod.bytecode().push_back(value->value.uint & 0xFF);
} break; } break;
case furvm::mod_type::S16: { case furvm::mod_type::S16: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS16)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS16));
mod.bytecode().push_back(value->value.uint & 0xFF);
mod.bytecode().push_back((value->value.uint >> 8) & 0xFF);
} break; } break;
case furvm::mod_type::U16: { case furvm::mod_type::U16: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU16)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU16));
mod.bytecode().push_back(value->value.uint & 0xFF);
mod.bytecode().push_back((value->value.uint >> 8) & 0xFF);
} break; } break;
case furvm::mod_type::S32: { case furvm::mod_type::S32: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS32)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushS32));
mod.bytecode().push_back(value->value.uint & 0xFF);
} break; } break;
case furvm::mod_type::U32: { case furvm::mod_type::U32: {
mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU32)); mod.bytecode().push_back(static_cast<furvm::byte>(furvm::instruction_t::PushU32));
mod.bytecode().push_back(value->value.uint & 0xFF);
} break; } break;
default: default:
return { generator_error::UnexpectedToken, "Unexpected type "s + std::string(typeName->value.string) }; return { generator_error::UnexpectedToken, "Unexpected type "s + std::string(typeName->value.string) };
@@ -417,6 +428,7 @@ struct mod_context {
case token::Set: case token::Set:
case token::Drop: case token::Drop:
case token::Dup: case token::Dup:
case token::Swap:
case token::Clone: case token::Clone:
case token::Ref: case token::Ref:
case token::Add: case token::Add:
@@ -503,7 +515,7 @@ struct mod_context {
mod.bytecode().push_back(0); mod.bytecode().push_back(0);
return { generator_error::Success }; return { generator_error::Success };
} }
std::ptrdiff_t jmpOff = static_cast<std::ptrdiff_t>(offset - mod.bytecode().size() + 1); std::ptrdiff_t jmpOff = static_cast<std::ptrdiff_t>(offset - mod.bytecode().size() - 1);
if (jmpOff < std::numeric_limits<std::int8_t>::min() || if (jmpOff < std::numeric_limits<std::int8_t>::min() ||
jmpOff > std::numeric_limits<std::int8_t>::max()) { jmpOff > std::numeric_limits<std::int8_t>::max()) {
assert(false); // TODO: Further jumps are not implemented assert(false); // TODO: Further jumps are not implemented
+1
View File
@@ -46,6 +46,7 @@ token_r lexer::next_token() {
{ "set", token::Set }, { "set", token::Set },
{ "drop", token::Drop }, { "drop", token::Drop },
{ "dup", token::Dup }, { "dup", token::Dup },
{ "swap", token::Swap },
{ "clone", token::Clone }, { "clone", token::Clone },
{ "ref", token::Ref }, { "ref", token::Ref },
{ "add", token::Add }, { "add", token::Add },
+1 -1
View File
@@ -111,7 +111,7 @@ using function_id = std::uint16_t;
/** /**
* @brief A handle to a furvm function. * @brief A handle to a furvm function.
*/ */
using function_h = handle<function, refcount_header<function_id>>; using function_h = handle<function, generic_header<function_id>>;
// module.hpp // module.hpp
+5
View File
@@ -76,6 +76,11 @@ enum class instruction_t : byte {
*/ */
Duplicate, Duplicate,
/**
* @brief Swaps two top elements of the stack.
*/
Swap,
/** /**
* @brief Clones top element on the stack. * @brief Clones top element on the stack.
*/ */
+26
View File
@@ -502,6 +502,32 @@ public:
if (m_type.type != thing_type::Ref || *m_type.value.typeRef != thing.type()) throw bad_thing_access(); if (m_type.type != thing_type::Ref || *m_type.value.typeRef != thing.type()) throw bad_thing_access();
m_data = thing.m_data; m_data = thing.m_data;
} }
/**
* @brief Self-explainatory.
*
* TODO: Document
*/
void assign(thing&& thing) {
class thing rhs = std::move(thing);
if (true_type() != rhs.true_type()) throw std::runtime_error("thing type mismatch");
// TODO: Move this to another function
switch (true_type().type) {
case thing_type::S8:
case thing_type::S16:
case thing_type::S32:
case thing_type::S64:
case thing_type::U8:
case thing_type::U16:
case thing_type::U32:
case thing_type::U64: std::memcpy(m_data, rhs.m_data, m_size); return;
case thing_type::Ptr:
case thing_type::Ref:
case thing_type::Array: throw std::runtime_error("unimplemented");
case thing_type::Count: break;
}
throw std::runtime_error("unreachable");
}
private: private:
static void copy_list(const thing_type& arrayType, array& dst, const array& src) { static void copy_list(const thing_type& arrayType, array& dst, const array& src) {
if (arrayType.type != thing_type::Array || arrayType.value.array.type == nullptr) if (arrayType.type != thing_type::Array || arrayType.value.array.type == nullptr)
+14 -6
View File
@@ -10,6 +10,7 @@
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <stdexcept> #include <stdexcept>
#include <utility>
#include <vector> #include <vector>
namespace furvm { namespace furvm {
@@ -122,7 +123,7 @@ void executor::store_thing(variable_t variable, thing_h&& thing) {
thing_h executor::load_thing(variable_t variable) const { thing_h executor::load_thing(variable_t variable) const {
const auto& frame = m_frames.top(); const auto& frame = m_frames.top();
return frame.variables[variable]; return { frame.variables[variable] };
} }
void executor::step() { void executor::step() {
@@ -186,10 +187,10 @@ void executor::step() {
push_thing(array->at(index->integer())); push_thing(array->at(index->integer()));
} break; } break;
case instruction_t::Set: { case instruction_t::Set: {
auto index = pop_thing(); auto element = pop_thing();
auto array = pop_thing(); auto index = pop_thing();
auto element = pop_thing(); auto array = pop_thing();
array->at(index->integer()) = std::move(element->clone()); array->at(index->integer()).assign(std::move(element->clone()));
} break; } break;
case instruction_t::Drop: { case instruction_t::Drop: {
pop_thing(); pop_thing();
@@ -197,6 +198,12 @@ void executor::step() {
case instruction_t::Duplicate: { case instruction_t::Duplicate: {
push_thing(thing()); push_thing(thing());
} break; } break;
case instruction_t::Swap: {
auto thing1 = pop_thing();
auto thing2 = pop_thing();
push_thing(std::move(thing1));
push_thing(std::move(thing2));
} break;
case instruction_t::Clone: { case instruction_t::Clone: {
push_thing(std::move(thing()->clone())); push_thing(std::move(thing()->clone()));
} break; } break;
@@ -316,7 +323,8 @@ void executor::step() {
push_frame(frame.mod, *frame.mod->function_at(funcId)); push_frame(frame.mod, *frame.mod->function_at(funcId));
} break; } break;
case instruction_t::Jump: { case instruction_t::Jump: {
frame.position += ((std::int8_t)frame.mod->byte(frame.position)) + 1; std::int8_t offset = static_cast<std::int8_t>(frame.mod->byte(frame.position++));
frame.position += offset;
} break; } break;
case instruction_t::JumpNotZero: { case instruction_t::JumpNotZero: {
byte offset = frame.mod->byte(frame.position++); byte offset = frame.mod->byte(frame.position++);
+2 -2
View File
@@ -75,8 +75,8 @@ int main(int argc, char** argv) {
mod->emplace_function(furvm::function_sig{ { u64Type }, u64Type }, "print").dispatch(); mod->emplace_function(furvm::function_sig{ { u64Type }, u64Type }, "print").dispatch();
#endif #endif
mod->set_native_function("println", [](furvm::executor& executor) { mod->set_native_function("println", [](furvm::executor& executor) {
auto arg = std::move(*executor.load_thing(0)); auto arg = executor.load_thing(0);
print_thing(arg); print_thing(*arg);
std::cout << '\n'; std::cout << '\n';
}); });