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;
}
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;
}
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) {
if (refs.contains(i)) {
output.at(i) = static_cast<uint32_t>(locs.at(refs.at(i)));
if (!refs.contains(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;
}
@ -92,19 +98,23 @@ int main()
// + a b
// }
//
// let result = 0;
// let i = 0;
// loop {
// if i >= 10 {
// break;
// fn main() {
// let result = 0;
// let i = 0;
// loop {
// if i >= 10 {
// break;
// }
// result = add(result, 5);
// i = + i 1;
// }
// result = add(result, 5);
// result
// }
auto program_asm = std::vector<AsmLine> {
// clang-format off
SourceMap, 0, 0, 0,
PushPtr, R("main"),
Pop,
Call, 0,
PushPtr, R("_exit"),
Jump,
Pop,
@ -112,15 +122,17 @@ int main()
SourceMap, 19, 2, 5,
Add,
Return,
L("main"),
SourceMap, 28, 5, 1,
PushInt, 0,
PushInt, 0,
SourceMap, 44, 6, 1,
PushInt, 0,
SourceMap, 55, 7, 1,
L("1"),
L("0"),
SourceMap, 66, 8, 5,
LoadLocal, 1,
PushInt, 0,
LoadLocal, 2,
PushInt, 10,
LessThan,
Not,
PushPtr, R("1"),
@ -128,22 +140,25 @@ int main()
SourceMap, 87, 9, 9,
PushPtr, R("2"),
Jump,
L("1"),
SourceMap, 104, 11, 5,
LoadLocal, 0,
LoadLocal, 1,
PushInt, 5,
PushPtr, R("add"),
Call, 2,
StoreLocal, 0,
StoreLocal, 1,
SourceMap, 133, 12, 5,
LoadLocal, 1,
LoadLocal, 2,
PushInt, 1,
Add,
StoreLocal, 1,
StoreLocal, 2,
PushPtr, R("0"),
Jump,
L("2"),
LoadLocal, 1,
StoreLocal, 0,
Pop,
Pop,
PushNull,
Return,
L("_exit"),
SourceMap, 147, 15, 1
@ -156,6 +171,5 @@ int main()
.code_coverage = true,
});
vm.run_until_done();
vm.print_stack();
std::cout << std::format("done\n{}\n", vm.stack_repr_string());
}

View File

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

View File

@ -4,11 +4,70 @@
#include <cstdlib>
#include <format>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
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()
{
while (!done()) {
@ -19,15 +78,15 @@ void VM::run_until_done()
void VM::run_n_instructions(size_t amount)
{
for (size_t i = 0; !done() and i < amount; ++i) {
run_instruction();
}
}
void VM::run_instruction()
{
std::cout << "stack:\n";
this->print_stack();
std::cout << std::format("pc = {}\n", this->pc);
std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc,
maybe_op_to_string(this->program[this->pc]), stack_repr_string());
auto op = eat_op();
switch (op) {
case Op::Nop:

View File

@ -156,11 +156,18 @@ public:
return this->stack;
}
inline void print_stack() const
inline auto stack_repr_string() const -> std::string
{
for (const auto& value : view_stack()) {
std::cout << std::format(" {}\n", value.to_repr_string());
auto result = std::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: