test program works

This commit is contained in:
SimonFJ20 2024-11-20 14:46:19 +01:00
parent ce91126cb1
commit 2fbccd0bc8
4 changed files with 139 additions and 127 deletions

View File

@ -63,7 +63,7 @@ auto compile_asm(const std::vector<AsmLine>& lines) -> std::vector<uint32_t>
break; break;
} }
case AsmLineType::Loc: { case AsmLineType::Loc: {
locs.insert_or_assign(std::get<Loc>(line.value).value, ip + 1); locs.insert_or_assign(std::get<Loc>(line.value).value, ip);
break; break;
} }
case AsmLineType::Ref: { case AsmLineType::Ref: {
@ -75,9 +75,15 @@ auto compile_asm(const std::vector<AsmLine>& lines) -> std::vector<uint32_t>
} }
} }
for (size_t i = 0; i < output.size(); ++i) { for (size_t i = 0; i < output.size(); ++i) {
if (refs.contains(i)) { if (!refs.contains(i)) {
output.at(i) = static_cast<uint32_t>(locs.at(refs.at(i))); continue;
} }
if (!locs.contains(refs.at(i))) {
std::cerr << std::format(
"error: label \"{}\" used at {} not defined\n", refs.at(i), i);
continue;
}
output.at(i) = static_cast<uint32_t>(locs.at(refs.at(i)));
} }
return output; return output;
} }
@ -92,6 +98,7 @@ int main()
// + a b // + a b
// } // }
// //
// fn main() {
// let result = 0; // let result = 0;
// let i = 0; // let i = 0;
// loop { // loop {
@ -99,12 +106,15 @@ int main()
// break; // break;
// } // }
// result = add(result, 5); // result = add(result, 5);
// i = + i 1;
// }
// result
// } // }
auto program_asm = std::vector<AsmLine> { auto program_asm = std::vector<AsmLine> {
// clang-format off // clang-format off
SourceMap, 0, 0, 0, SourceMap, 0, 0, 0,
PushPtr, R("main"), PushPtr, R("main"),
Pop, Call, 0,
PushPtr, R("_exit"), PushPtr, R("_exit"),
Jump, Jump,
Pop, Pop,
@ -112,15 +122,17 @@ int main()
SourceMap, 19, 2, 5, SourceMap, 19, 2, 5,
Add, Add,
Return, Return,
L("main"),
SourceMap, 28, 5, 1, SourceMap, 28, 5, 1,
PushInt, 0, PushInt, 0,
PushInt, 0,
SourceMap, 44, 6, 1, SourceMap, 44, 6, 1,
PushInt, 0, PushInt, 0,
SourceMap, 55, 7, 1, SourceMap, 55, 7, 1,
L("1"), L("0"),
SourceMap, 66, 8, 5, SourceMap, 66, 8, 5,
LoadLocal, 1, LoadLocal, 2,
PushInt, 0, PushInt, 10,
LessThan, LessThan,
Not, Not,
PushPtr, R("1"), PushPtr, R("1"),
@ -128,22 +140,25 @@ int main()
SourceMap, 87, 9, 9, SourceMap, 87, 9, 9,
PushPtr, R("2"), PushPtr, R("2"),
Jump, Jump,
L("1"),
SourceMap, 104, 11, 5, SourceMap, 104, 11, 5,
LoadLocal, 0, LoadLocal, 1,
PushInt, 5, PushInt, 5,
PushPtr, R("add"), PushPtr, R("add"),
Call, 2, Call, 2,
StoreLocal, 0, StoreLocal, 1,
SourceMap, 133, 12, 5, SourceMap, 133, 12, 5,
LoadLocal, 1, LoadLocal, 2,
PushInt, 1, PushInt, 1,
Add, Add,
StoreLocal, 1, StoreLocal, 2,
PushPtr, R("0"), PushPtr, R("0"),
Jump, Jump,
L("2"), L("2"),
LoadLocal, 1,
StoreLocal, 0,
Pop,
Pop, Pop,
PushNull,
Return, Return,
L("_exit"), L("_exit"),
SourceMap, 147, 15, 1 SourceMap, 147, 15, 1
@ -156,6 +171,5 @@ int main()
.code_coverage = true, .code_coverage = true,
}); });
vm.run_until_done(); vm.run_until_done();
std::cout << std::format("done\n{}\n", vm.stack_repr_string());
vm.print_stack();
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <cstdlib>
#include <format> #include <format>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -50,6 +51,15 @@ struct Ptr {
uint32_t value; uint32_t value;
}; };
// clang-format off
template <ValueType op> struct ValueTypeToType { };
template <> struct ValueTypeToType<ValueType::Null> { using Type = Null; };
template <> struct ValueTypeToType<ValueType::Int> { using Type = Int; };
template <> struct ValueTypeToType<ValueType::Bool> { using Type = Bool; };
template <> struct ValueTypeToType<ValueType::String> { using Type = String; };
template <> struct ValueTypeToType<ValueType::Ptr> { using Type = Ptr; };
// clang-format on
class Value { class Value {
public: public:
Value(Null&& value) Value(Null&& value)
@ -80,120 +90,42 @@ public:
inline auto type() const -> ValueType { return m_type; }; inline auto type() const -> ValueType { return m_type; };
inline auto as_null() -> Null& template <ValueType VT> inline auto as() -> ValueTypeToType<VT>::Type&
{ {
//
try { try {
return std::get<Null>(value); return std::get<typename ValueTypeToType<VT>::Type>(value);
} catch (const std::bad_variant_access& ex) { } catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Null\n", std::cerr << std::format("error: tried to unwrap {} as {}\n",
value_type_to_string(this->m_type)); value_type_to_string(this->m_type), value_type_to_string(VT));
throw; std::exit(1);
}
}
inline auto as_null() const -> const Null&
{
//
try {
return std::get<Null>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Null\n",
value_type_to_string(this->m_type));
throw;
} }
} }
inline auto as_int() -> Int& template <ValueType VT>
inline auto as() const -> const ValueTypeToType<VT>::Type&
{ {
//
try { try {
return std::get<Int>(value); return std::get<typename ValueTypeToType<VT>::Type>(value);
} catch (const std::bad_variant_access& ex) { } catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Int\n", std::cerr << std::format("error: tried to unwrap {} as {}\n",
value_type_to_string(this->m_type)); value_type_to_string(this->m_type), value_type_to_string(VT));
throw; std::exit(1);
}
}
inline auto as_int() const -> const Int&
{
//
try {
return std::get<Int>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Int\n",
value_type_to_string(this->m_type));
throw;
} }
} }
inline auto as_bool() -> Bool& // clang-format off
{ inline auto as_null() -> Null& { return as<ValueType::Null>(); }
// inline auto as_int() -> Int& { return as<ValueType::Int>(); }
try { inline auto as_bool() -> Bool& { return as<ValueType::Bool>(); }
return std::get<Bool>(value); inline auto as_string() -> String& { return as<ValueType::String>(); }
} catch (const std::bad_variant_access& ex) { inline auto as_ptr() -> Ptr& { return as<ValueType::Ptr>(); }
std::cout << std::format("tried to unwrap {} as Bool\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto as_bool() const -> const Bool&
{
//
try {
return std::get<Bool>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Bool\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto as_string() -> String& inline auto as_null() const -> const Null& { return as<ValueType::Null>(); }
{ inline auto as_int() const -> const Int& { return as<ValueType::Int>(); }
// inline auto as_bool() const -> const Bool& { return as<ValueType::Bool>(); }
try { inline auto as_string() const -> const String& { return as<ValueType::String>(); }
return std::get<String>(value); inline auto as_ptr() const -> const Ptr& { return as<ValueType::Ptr>(); }
} catch (const std::bad_variant_access& ex) { // clang-format on
std::cout << std::format("tried to unwrap {} as String\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto as_string() const -> const String&
{
//
try {
return std::get<String>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as String\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto as_ptr() -> Ptr&
{
//
try {
return std::get<Ptr>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Ptr\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto as_ptr() const -> const Ptr&
{
//
try {
return std::get<Ptr>(value);
} catch (const std::bad_variant_access& ex) {
std::cout << std::format("tried to unwrap {} as Ptr\n",
value_type_to_string(this->m_type));
throw;
}
}
inline auto to_string() const -> std::string inline auto to_string() const -> std::string
{ {

View File

@ -4,11 +4,70 @@
#include <cstdlib> #include <cstdlib>
#include <format> #include <format>
#include <iostream> #include <iostream>
#include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
using namespace sliger; using namespace sliger;
inline auto maybe_op_to_string(uint32_t value) -> std::string
{
switch (static_cast<Op>(value)) {
case Op::Nop:
return "Nop";
case Op::PushNull:
return "PushNull";
case Op::PushInt:
return "PushInt";
case Op::PushBool:
return "PushBool";
case Op::PushString:
return "PushString";
case Op::PushPtr:
return "PushPtr";
case Op::Pop:
return "Pop";
case Op::LoadLocal:
return "LoadLocal";
case Op::StoreLocal:
return "StoreLocal";
case Op::Call:
return "Call";
case Op::Return:
return "Return";
case Op::Jump:
return "Jump";
case Op::JumpIfFalse:
return "JumpIfFalse";
case Op::Add:
return "Add";
case Op::Subtract:
return "Subtract";
case Op::Multiply:
return "Multiply";
case Op::Divide:
return "Divide";
case Op::Remainder:
return "Remainder";
case Op::Equal:
return "Equal";
case Op::LessThan:
return "LessThan";
case Op::And:
return "And";
case Op::Or:
return "Or";
case Op::Xor:
return "Xor";
case Op::Not:
return "Not";
case Op::SourceMap:
return "SourceMap";
default:
return std::to_string(value);
}
}
void VM::run_until_done() void VM::run_until_done()
{ {
while (!done()) { while (!done()) {
@ -19,15 +78,15 @@ void VM::run_until_done()
void VM::run_n_instructions(size_t amount) void VM::run_n_instructions(size_t amount)
{ {
for (size_t i = 0; !done() and i < amount; ++i) { for (size_t i = 0; !done() and i < amount; ++i) {
run_instruction(); run_instruction();
} }
} }
void VM::run_instruction() void VM::run_instruction()
{ {
std::cout << "stack:\n"; std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc,
this->print_stack(); maybe_op_to_string(this->program[this->pc]), stack_repr_string());
std::cout << std::format("pc = {}\n", this->pc);
auto op = eat_op(); auto op = eat_op();
switch (op) { switch (op) {
case Op::Nop: case Op::Nop:

View File

@ -156,11 +156,18 @@ public:
return this->stack; return this->stack;
} }
inline void print_stack() const inline auto stack_repr_string() const -> std::string
{ {
for (const auto& value : view_stack()) { auto result = std::string();
std::cout << std::format(" {}\n", value.to_repr_string()); result += "";
const auto& stack = view_stack();
for (size_t i = 0; i < stack.size(); ++i) {
if (i != 0) {
result += " ";
} }
result += stack[stack.size() - i - 1].to_repr_string();
}
return result;
} }
private: private: