chore(furdb): initialize furdb
This commit is contained in:
@@ -16,6 +16,7 @@ add_subdirectory(furvm)
|
|||||||
add_subdirectory(furc)
|
add_subdirectory(furc)
|
||||||
add_subdirectory(furas)
|
add_subdirectory(furas)
|
||||||
add_subdirectory(disfuras)
|
add_subdirectory(disfuras)
|
||||||
|
add_subdirectory(furdb)
|
||||||
|
|
||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs)
|
set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/docs)
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
file(GLOB_RECURSE FURDB_SRCS "src/**.cpp")
|
||||||
|
file(GLOB_RECURSE FURDB_HDRS "include/**.hpp")
|
||||||
|
add_executable(furdb ${FURDB_SRCS} ${FURDB_HDRS})
|
||||||
|
target_include_directories(furdb PRIVATE include/)
|
||||||
|
target_link_libraries(furdb PUBLIC furlang libfurc libfurvm)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef COMMAND_HPP
|
||||||
|
#define COMMAND_HPP
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct command_info {
|
||||||
|
std::string_view commandName;
|
||||||
|
std::vector<std::string_view> args;
|
||||||
|
};
|
||||||
|
|
||||||
|
class command {
|
||||||
|
public:
|
||||||
|
command() = default;
|
||||||
|
virtual ~command() = default;
|
||||||
|
|
||||||
|
command(command&&) noexcept = default;
|
||||||
|
command& operator=(command&&) noexcept = default;
|
||||||
|
command(const command&) = delete;
|
||||||
|
command& operator=(const command&) = delete;
|
||||||
|
public:
|
||||||
|
virtual void execute(context& ctx, const command_info& info) = 0;
|
||||||
|
public:
|
||||||
|
static command_info parse(std::string_view line);
|
||||||
|
};
|
||||||
|
|
||||||
|
class quit_command final : public command {
|
||||||
|
public:
|
||||||
|
void execute(context& ctx, const command_info& info) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class run_command final : public command {
|
||||||
|
public:
|
||||||
|
void execute(context& ctx, const command_info& info) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMMAND_HPP
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef CONTEXT_HPP
|
||||||
|
#define CONTEXT_HPP
|
||||||
|
|
||||||
|
#include <furvm/context.hpp>
|
||||||
|
#include <furvm/executor.hpp>
|
||||||
|
#include <furvm/fwd.hpp>
|
||||||
|
#include <furvm/module.hpp>
|
||||||
|
|
||||||
|
struct context {
|
||||||
|
furvm::context_p context = std::make_shared<furvm::context>();
|
||||||
|
furvm::mod_h mod;
|
||||||
|
furvm::executor_h executor;
|
||||||
|
furvm::function_h mainFunction;
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONTEXT_HPP
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "command.hpp"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
|
#include <random>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
command_info command::parse(std::string_view line) {
|
||||||
|
command_info info;
|
||||||
|
|
||||||
|
while (!line.empty() && std::isspace(line.front()) != 0)
|
||||||
|
line = line.substr(1);
|
||||||
|
std::size_t length = 0;
|
||||||
|
while (line.size() > length && std::isalnum(line.at(length)) != 0)
|
||||||
|
++length;
|
||||||
|
info.commandName = line.substr(0, length);
|
||||||
|
line = line.substr(length);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (!line.empty() && std::isspace(line.front()) != 0)
|
||||||
|
line = line.substr(1);
|
||||||
|
if (line.empty()) break;
|
||||||
|
length = 0;
|
||||||
|
while (line.size() > length && std::isalnum(line.at(length)) != 0)
|
||||||
|
++length;
|
||||||
|
info.args.push_back(line.substr(0, length));
|
||||||
|
line = line.substr(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void quit_command::execute(context& ctx, const command_info& info) {
|
||||||
|
static std::random_device s_rd;
|
||||||
|
static std::mt19937 s_gen(s_rd());
|
||||||
|
static std::uniform_int_distribution<> s_dis(1, 1000);
|
||||||
|
|
||||||
|
int roll = s_dis(s_gen);
|
||||||
|
|
||||||
|
std::cout << "Farewell";
|
||||||
|
if (roll == 1) {
|
||||||
|
std::cout << ", stasiu pensive";
|
||||||
|
} else if (roll <= 100) {
|
||||||
|
std::cout << ", kromek-man";
|
||||||
|
}
|
||||||
|
std::cout << "!\n";
|
||||||
|
|
||||||
|
ctx.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_command::execute(context& ctx, const command_info& info) {
|
||||||
|
ctx.run();
|
||||||
|
std::cout << "Execution finished\n";
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "context.hpp"
|
||||||
|
|
||||||
|
void context::run() {
|
||||||
|
if ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done)
|
||||||
|
executor->push_frame(mod, *mainFunction);
|
||||||
|
while ((executor->flags() & furvm::executor_flags::Done) != furvm::executor_flags::Done) {
|
||||||
|
executor->step();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#include "command.hpp"
|
||||||
|
#include "context.hpp"
|
||||||
|
#include "furvm/function.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <furvm/fwd.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// taken from furvm uwu :3 ^^ nya~ ngh~
|
||||||
|
static void print_thing(const furvm::thing<furvm::thing_allocator>& thing) {
|
||||||
|
using namespace furvm;
|
||||||
|
|
||||||
|
switch (thing.true_type().type) {
|
||||||
|
case thing_type::S8: std::cout << thing.cast_to<thing_type::s16>(); break;
|
||||||
|
case thing_type::S16: std::cout << thing.get<thing_type::s16>(); break;
|
||||||
|
case thing_type::S32: std::cout << thing.get<thing_type::s32>(); break;
|
||||||
|
case thing_type::S64: std::cout << thing.get<thing_type::s64>(); break;
|
||||||
|
case thing_type::U8: std::cout << thing.get<thing_type::u8>(); break;
|
||||||
|
case thing_type::U16: std::cout << thing.get<thing_type::u16>(); break;
|
||||||
|
case thing_type::U32: std::cout << thing.get<thing_type::u32>(); break;
|
||||||
|
case thing_type::U64: std::cout << thing.get<thing_type::u64>(); break;
|
||||||
|
case thing_type::Array:
|
||||||
|
std::cout << "{ ";
|
||||||
|
for (thing_type::u64 i = 0; i < thing.length(); ++i) {
|
||||||
|
if (i > 0) std::cout << ", ";
|
||||||
|
print_thing(thing.at(i));
|
||||||
|
}
|
||||||
|
std::cout << " }";
|
||||||
|
break;
|
||||||
|
default: std::cerr << "{Type not recognized}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Argument parsing
|
||||||
|
// TODO: Multiple modules
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Usage: " << argv[0] << " <module.fmod>\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unordered_map<std::string_view, command*> s_commands;
|
||||||
|
s_commands["quit"] = s_commands["q"] = new quit_command();
|
||||||
|
s_commands["run"] = s_commands["r"] = new run_command();
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::ifstream file(argv[1], std::ios::binary | std::ios::in);
|
||||||
|
|
||||||
|
context ctx;
|
||||||
|
try {
|
||||||
|
ctx.mod = ctx.context->emplace(argv[1], furvm::mod::load(file));
|
||||||
|
} catch (std::exception ex) {
|
||||||
|
std::cerr << "Failed to load module " << argv[1] << ": " << ex.what() << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ctx.executor = ctx.context->emplace_executor(ctx.context);
|
||||||
|
ctx.mainFunction = ctx.mod->function_at("main", furvm::function_sig{});
|
||||||
|
|
||||||
|
ctx.mod->set_native_function("println", [](furvm::executor& executor) {
|
||||||
|
auto arg = executor.load_thing(0);
|
||||||
|
print_thing(*arg);
|
||||||
|
std::cout << '\n';
|
||||||
|
});
|
||||||
|
|
||||||
|
std::string inputLine;
|
||||||
|
std::string prevInput;
|
||||||
|
while (ctx.running) {
|
||||||
|
std::swap(inputLine, prevInput);
|
||||||
|
std::cout << "(furdb) ";
|
||||||
|
if (!std::getline(std::cin, inputLine)) break;
|
||||||
|
|
||||||
|
if (inputLine.empty()) {
|
||||||
|
inputLine = prevInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto info = command::parse(inputLine);
|
||||||
|
auto it = s_commands.find(info.commandName);
|
||||||
|
if (it == s_commands.end()) {
|
||||||
|
std::cerr << "Unknown command \"" << info.commandName << "\"\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
it->second->execute(ctx, info);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
std::cerr << "Uncaught exception: " << ex.what() << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user