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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -37,6 +37,7 @@ struct token {
|
|||||||
Set,
|
Set,
|
||||||
Drop,
|
Drop,
|
||||||
Dup,
|
Dup,
|
||||||
|
Swap,
|
||||||
Clone,
|
Clone,
|
||||||
Ref,
|
Ref,
|
||||||
Add,
|
Add,
|
||||||
|
|||||||
+13
-1
@@ -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
|
||||||
|
|||||||
@@ -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 },
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user