mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 18:16:31 +00:00
parse actions
This commit is contained in:
parent
eff378030a
commit
03d68fa562
45
runtime/actions.hpp
Normal file
45
runtime/actions.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "rpc_server.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace sliger::rpc::action {
|
||||||
|
|
||||||
|
struct Action {
|
||||||
|
virtual auto perform_action(
|
||||||
|
std::unique_ptr<sliger::rpc::BufferedWriter> writer) -> void = 0;
|
||||||
|
virtual ~Action() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RunDebug : public Action {
|
||||||
|
public:
|
||||||
|
RunDebug(std::vector<uint32_t> instructions)
|
||||||
|
: instructions(instructions)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
auto perform_action(
|
||||||
|
std::unique_ptr<sliger::rpc::BufferedWriter> writer) -> void;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint32_t> instructions;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto action_from_json(
|
||||||
|
std::unique_ptr<json::Value> value) -> std::unique_ptr<Action>
|
||||||
|
{
|
||||||
|
auto& obj = value->as<sliger::json::Object>();
|
||||||
|
auto type = obj.fields.at("type")->as<sliger::json::String>();
|
||||||
|
|
||||||
|
if (type.value == "run-debug") {
|
||||||
|
sliger::json::ArrayValues values = std::move(
|
||||||
|
obj.fields.at("program")->as<sliger::json::Array>().values);
|
||||||
|
auto instructions = std::vector<uint32_t>();
|
||||||
|
for (auto& v : values) {
|
||||||
|
std::unique_ptr<json::Value> moved = std::move(v);
|
||||||
|
auto value = moved->as<sliger::json::Number>().value;
|
||||||
|
instructions.push_back((uint32_t)value);
|
||||||
|
}
|
||||||
|
auto action = RunDebug(instructions);
|
||||||
|
return std::make_unique<RunDebug>(action);
|
||||||
|
}
|
||||||
|
throw "todo";
|
||||||
|
};
|
||||||
|
}
|
@ -95,7 +95,7 @@ struct Value {
|
|||||||
requires std::derived_from<T, Value>
|
requires std::derived_from<T, Value>
|
||||||
inline auto as() & -> T&
|
inline auto as() & -> T&
|
||||||
{
|
{
|
||||||
return static_cast<T&>(this);
|
return static_cast<T&>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
192
runtime/main.cpp
192
runtime/main.cpp
@ -1,200 +1,14 @@
|
|||||||
#include "arch.hpp"
|
#include "actions.hpp"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "rpc_server.hpp"
|
#include "rpc_server.hpp"
|
||||||
#include "vm.hpp"
|
|
||||||
#include <format>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
enum class AsmLineType {
|
|
||||||
Op,
|
|
||||||
Lit,
|
|
||||||
Loc,
|
|
||||||
Ref,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Loc {
|
|
||||||
explicit Loc(std::string value)
|
|
||||||
: value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ref {
|
|
||||||
explicit Ref(std::string value)
|
|
||||||
: value(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AsmLine {
|
|
||||||
/* clang-format off */
|
|
||||||
AsmLine(sliger::Op value) : type(AsmLineType::Op), value(value) {}
|
|
||||||
AsmLine(uint32_t value) : type(AsmLineType::Lit), value(value) {}
|
|
||||||
AsmLine(Loc value) : type(AsmLineType::Loc), value(value) {}
|
|
||||||
AsmLine(Ref value) : type(AsmLineType::Ref), value(value) {}
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
AsmLineType type;
|
|
||||||
std::variant<sliger::Op, uint32_t, Loc, Ref> value;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto compile_asm(const std::vector<AsmLine>& lines) -> std::vector<uint32_t>
|
|
||||||
{
|
|
||||||
size_t ip = 0;
|
|
||||||
auto output = std::vector<uint32_t>();
|
|
||||||
auto locs = std::unordered_map<std::string, size_t>();
|
|
||||||
auto refs = std::unordered_map<size_t, std::string>();
|
|
||||||
for (const auto& line : lines) {
|
|
||||||
switch (line.type) {
|
|
||||||
case AsmLineType::Op: {
|
|
||||||
output.push_back(
|
|
||||||
std::to_underlying(std::get<sliger::Op>(line.value)));
|
|
||||||
ip += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AsmLineType::Lit: {
|
|
||||||
output.push_back(std::get<uint32_t>(line.value));
|
|
||||||
ip += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AsmLineType::Loc: {
|
|
||||||
locs.insert_or_assign(std::get<Loc>(line.value).value, ip);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AsmLineType::Ref: {
|
|
||||||
output.push_back(0);
|
|
||||||
refs.insert_or_assign(ip, std::get<Ref>(line.value).value);
|
|
||||||
ip += 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < output.size(); ++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;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto execute_action(std::unique_ptr<sliger::json::Value> req,
|
|
||||||
std::unique_ptr<sliger::rpc::BufferedWriter> writer)
|
|
||||||
{
|
|
||||||
auto node = req->as<sliger::json::Object>();
|
|
||||||
auto& type = node.fields.at("type")->as<sliger::json::String>();
|
|
||||||
if (type.value == "some_type") {
|
|
||||||
/* etc. */
|
|
||||||
} else {
|
|
||||||
/* unrecognized action */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
using R = Ref;
|
|
||||||
using L = Loc;
|
|
||||||
using enum sliger::Op;
|
|
||||||
|
|
||||||
auto rpc = sliger::rpc::RpcServer(
|
auto rpc = sliger::rpc::RpcServer(
|
||||||
[&](std::unique_ptr<sliger::json::Value> req,
|
[&](std::unique_ptr<sliger::json::Value> req,
|
||||||
std::unique_ptr<sliger::rpc::BufferedWriter> writer) {
|
std::unique_ptr<sliger::rpc::BufferedWriter> writer) {
|
||||||
execute_action(std::move(req), std::move(writer));
|
auto action = sliger::rpc::action::action_from_json(std::move(req));
|
||||||
|
action->perform_action(std::move(writer));
|
||||||
});
|
});
|
||||||
rpc.listen();
|
rpc.listen();
|
||||||
|
|
||||||
// fn add(a, b) {
|
|
||||||
// + a b
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn main() {
|
|
||||||
// let result = 0;
|
|
||||||
// let i = 0;
|
|
||||||
// loop {
|
|
||||||
// if i >= 10 {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// result = add(result, 5);
|
|
||||||
// i = + i 1;
|
|
||||||
// }
|
|
||||||
// result
|
|
||||||
// }
|
|
||||||
auto program_asm = std::vector<AsmLine> {
|
|
||||||
// clang-format off
|
|
||||||
SourceMap, 0, 0, 0,
|
|
||||||
PushPtr, R("main"),
|
|
||||||
Call, 0,
|
|
||||||
PushPtr, R("_exit"),
|
|
||||||
Jump,
|
|
||||||
Pop,
|
|
||||||
L("add"),
|
|
||||||
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("0"),
|
|
||||||
SourceMap, 66, 8, 5,
|
|
||||||
LoadLocal, 2,
|
|
||||||
PushInt, 10,
|
|
||||||
LessThan,
|
|
||||||
Not,
|
|
||||||
PushPtr, R("1"),
|
|
||||||
JumpIfFalse,
|
|
||||||
SourceMap, 87, 9, 9,
|
|
||||||
PushPtr, R("2"),
|
|
||||||
Jump,
|
|
||||||
L("1"),
|
|
||||||
SourceMap, 104, 11, 5,
|
|
||||||
LoadLocal, 1,
|
|
||||||
PushInt, 5,
|
|
||||||
PushPtr, R("add"),
|
|
||||||
Call, 2,
|
|
||||||
StoreLocal, 1,
|
|
||||||
SourceMap, 133, 12, 5,
|
|
||||||
LoadLocal, 2,
|
|
||||||
PushInt, 1,
|
|
||||||
Add,
|
|
||||||
StoreLocal, 2,
|
|
||||||
PushPtr, R("0"),
|
|
||||||
Jump,
|
|
||||||
L("2"),
|
|
||||||
LoadLocal, 1,
|
|
||||||
StoreLocal, 0,
|
|
||||||
Pop,
|
|
||||||
Pop,
|
|
||||||
Return,
|
|
||||||
L("_exit"),
|
|
||||||
SourceMap, 147, 15, 1
|
|
||||||
// clang-format on
|
|
||||||
};
|
|
||||||
auto program = compile_asm(program_asm);
|
|
||||||
auto vm = sliger::VM(program,
|
|
||||||
{
|
|
||||||
.flame_graph = true,
|
|
||||||
.code_coverage = true,
|
|
||||||
});
|
|
||||||
vm.run_until_done();
|
|
||||||
std::cout << std::format("done\n{}\n", vm.stack_repr_string(4));
|
|
||||||
auto flame_graph = vm.flame_graph_json();
|
|
||||||
std::cout << std::format("flame graph: {}\n", flame_graph);
|
|
||||||
auto code_coverage = vm.code_coverage_json();
|
|
||||||
std::cout << std::format("code coverage: {}\n", code_coverage);
|
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Unit { };
|
struct Unit { };
|
||||||
struct Req { };
|
|
||||||
|
|
||||||
class BufferedWriter {
|
class BufferedWriter {
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user