forked from KPGPMC/furlang
feat(furvm): introduce module, instruction and constant
This commit is contained in:
@@ -0,0 +1,112 @@
|
|||||||
|
#ifndef FURVM_CONSTANT_HPP
|
||||||
|
#define FURVM_CONSTANT_HPP
|
||||||
|
|
||||||
|
#include "furvm/fwd.hpp"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace furvm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bad constant access exception.
|
||||||
|
*/
|
||||||
|
class bad_constant_access : public std::exception {
|
||||||
|
public:
|
||||||
|
bad_constant_access() = default;
|
||||||
|
~bad_constant_access() override = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
bad_constant_access(bad_constant_access&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
bad_constant_access& operator=(bad_constant_access&&) noexcept = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor.
|
||||||
|
*/
|
||||||
|
bad_constant_access(const bad_constant_access&) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor.
|
||||||
|
*/
|
||||||
|
bad_constant_access& operator=(const bad_constant_access&) = default;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a C-style string describing the cause of the error.
|
||||||
|
*
|
||||||
|
* @return The cause of the error.
|
||||||
|
*/
|
||||||
|
const char* what() const noexcept override { return "bad constant access"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class constant_t : std::uint8_t {
|
||||||
|
String, /**< String constant. */
|
||||||
|
};
|
||||||
|
|
||||||
|
class constant {
|
||||||
|
public:
|
||||||
|
using string_type = std::string_view; /**< String constant type. */
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Construct a new string constant.
|
||||||
|
*
|
||||||
|
* @param string String.
|
||||||
|
*/
|
||||||
|
constant(string_type string)
|
||||||
|
: m_type(constant_t::String), m_value(string) {}
|
||||||
|
|
||||||
|
~constant() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
constant(constant&&) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
constant& operator=(constant&&) = default;
|
||||||
|
|
||||||
|
constant(const constant&) = delete;
|
||||||
|
constant& operator=(const constant&) = delete;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns this constant's type.
|
||||||
|
* @see constant_t
|
||||||
|
*
|
||||||
|
* @return The constant type.
|
||||||
|
*/
|
||||||
|
constexpr constant_t type() const { return m_type; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns this constant's string value.
|
||||||
|
* @throws bad_constant_access if this constant's type is not constant_t::String.
|
||||||
|
*
|
||||||
|
* @return The string value.
|
||||||
|
*/
|
||||||
|
constexpr string_type string() const {
|
||||||
|
require_type(constant_t::String);
|
||||||
|
return m_value.string;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void require_type(constant_t type) const {
|
||||||
|
if (m_type != type) throw bad_constant_access();
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
constant_t m_type{};
|
||||||
|
union value {
|
||||||
|
string_type string;
|
||||||
|
|
||||||
|
value(string_type sv)
|
||||||
|
: string(sv) {}
|
||||||
|
} m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace furvm
|
||||||
|
|
||||||
|
#endif // FURVM_CONSTANT_HPP
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
#ifndef FURVM_CONTEXT_HPP
|
#ifndef FURVM_CONTEXT_HPP
|
||||||
#define FURVM_CONTEXT_HPP
|
#define FURVM_CONTEXT_HPP
|
||||||
|
|
||||||
|
#include "furvm/fwd.hpp"
|
||||||
|
#include "furvm/module.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Context.
|
|
||||||
*
|
|
||||||
* A furvm context.
|
|
||||||
*/
|
|
||||||
class context {
|
class context {
|
||||||
|
public:
|
||||||
|
using value_type = std::unique_ptr<mod>;
|
||||||
public:
|
public:
|
||||||
context() = default;
|
context() = default;
|
||||||
~context() = default;
|
~context() = default;
|
||||||
@@ -25,7 +29,71 @@ public:
|
|||||||
|
|
||||||
context(const context&) = delete;
|
context(const context&) = delete;
|
||||||
context& operator=(const context&) = delete;
|
context& operator=(const context&) = delete;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Adds a module to this context.
|
||||||
|
*
|
||||||
|
* @param args Arguments to forward to module's constructor.
|
||||||
|
* @return An index to the emplaced module.
|
||||||
|
*/
|
||||||
|
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<mod, Args...>>>
|
||||||
|
constexpr module_index emplace(Args&&... args) {
|
||||||
|
module_index index = m_modules.size();
|
||||||
|
m_modules.emplace_back(std::make_unique<mod>(std::forward<Args>(args)...));
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erases a module from this context.
|
||||||
|
*
|
||||||
|
* @param index Index to the module.
|
||||||
|
* @return Old value.
|
||||||
|
*/
|
||||||
|
value_type erase(module_index index) {
|
||||||
|
if (index >= m_modules.size()) return nullptr;
|
||||||
|
return std::move(m_modules[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a module of this context.
|
||||||
|
*
|
||||||
|
* @param index Position of the module.
|
||||||
|
* @return The module.
|
||||||
|
*/
|
||||||
|
constexpr value_type& operator[](module_index index) { return m_modules[index]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a module of this context.
|
||||||
|
*
|
||||||
|
* @param index Position of the module.
|
||||||
|
* @return The module.
|
||||||
|
*/
|
||||||
|
constexpr const value_type& operator[](module_index index) const { return m_modules[index]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a module of this context.
|
||||||
|
*
|
||||||
|
* @param index Position of the module.
|
||||||
|
* @return The module.
|
||||||
|
*/
|
||||||
|
constexpr value_type& at(module_index index) { return m_modules.at(index); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a module of this context.
|
||||||
|
*
|
||||||
|
* @param index Position of the module.
|
||||||
|
* @return The module.
|
||||||
|
*/
|
||||||
|
constexpr const value_type& at(module_index index) const { return m_modules.at(index); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns how many does this context have modules.
|
||||||
|
*
|
||||||
|
* @return The module count.
|
||||||
|
*/
|
||||||
|
constexpr size_t size() const { return m_modules.size(); }
|
||||||
private:
|
private:
|
||||||
|
std::vector<std::unique_ptr<mod>> m_modules;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace furvm
|
} // namespace furvm
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#ifndef FURVM_FWD_HPP
|
||||||
|
#define FURVM_FWD_HPP
|
||||||
|
|
||||||
|
#include <cstddef> // IWYU pragma: export
|
||||||
|
#include <cstdint> // IWYU pragma: export
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Furlang's virtual machine.
|
||||||
|
*/
|
||||||
|
namespace furvm {
|
||||||
|
|
||||||
|
// constant.hpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constant index.
|
||||||
|
*
|
||||||
|
* An index to the constant in module's constant pool.
|
||||||
|
*/
|
||||||
|
using constant_index = std::uint16_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum constant_t
|
||||||
|
* @brief Constant type.
|
||||||
|
*/
|
||||||
|
enum class constant_t : std::uint8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class constant
|
||||||
|
* @brief Constant.
|
||||||
|
*/
|
||||||
|
class constant;
|
||||||
|
|
||||||
|
// instruction.hpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum instruction_t
|
||||||
|
* @brief Furvm's instruction type.
|
||||||
|
*/
|
||||||
|
enum class instruction_t : std::uint8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct instruction
|
||||||
|
* @brief Furvm's instruction.
|
||||||
|
*/
|
||||||
|
struct instruction;
|
||||||
|
|
||||||
|
// module.hpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class mod
|
||||||
|
* @brief Module.
|
||||||
|
*
|
||||||
|
* A furvm module. Translation unit of furlang.
|
||||||
|
*/
|
||||||
|
class mod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Furvm module's index.
|
||||||
|
*/
|
||||||
|
using module_index = std::size_t;
|
||||||
|
|
||||||
|
// context.hpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class context
|
||||||
|
* @brief Context.
|
||||||
|
*
|
||||||
|
* A furvm context.
|
||||||
|
*/
|
||||||
|
class context;
|
||||||
|
|
||||||
|
} // namespace furvm
|
||||||
|
|
||||||
|
#endif // FURVM_FWD_HPP
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef FURVM_INSTRUCTION_HPP
|
||||||
|
#define FURVM_INSTRUCTION_HPP
|
||||||
|
|
||||||
|
#include "furvm/fwd.hpp"
|
||||||
|
|
||||||
|
namespace furvm {
|
||||||
|
|
||||||
|
enum class instruction_t : std::uint8_t {
|
||||||
|
/**
|
||||||
|
* @brief No operation.
|
||||||
|
*/
|
||||||
|
NoOperation = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pushes a constant onto the stack.
|
||||||
|
*
|
||||||
|
* Pushes a constant from the constant pool denoted by two next bytes in low-endian onto the stack.
|
||||||
|
*/
|
||||||
|
PushConstant,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pops top element from the stack.
|
||||||
|
*/
|
||||||
|
Drop,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Duplicates top element on the stack.
|
||||||
|
*/
|
||||||
|
Duplicate,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instruction {
|
||||||
|
instruction_t type; /**< Instruction type. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Instruction value.
|
||||||
|
*/
|
||||||
|
union value {
|
||||||
|
constant_index constant; /**< Constant instruction argument. */
|
||||||
|
} value; /**< Instruction value. */
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace furvm
|
||||||
|
|
||||||
|
#endif // FURVM_INSTRUCTION_HPP
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef FURVM_MODULE_HPP
|
||||||
|
#define FURVM_MODULE_HPP
|
||||||
|
|
||||||
|
namespace furvm {
|
||||||
|
|
||||||
|
class mod {
|
||||||
|
public:
|
||||||
|
mod() = default;
|
||||||
|
~mod() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
mod(mod&&) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
|
mod& operator=(mod&&) = default;
|
||||||
|
|
||||||
|
mod(const mod&) = delete;
|
||||||
|
mod& operator=(const mod&) = delete;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace furvm
|
||||||
|
|
||||||
|
#endif // FURVM_MODULE_HPP
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
furvm::context context;
|
furvm::context context;
|
||||||
|
|
||||||
|
auto mainModule = context.emplace();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#include "furvm/module.hpp"
|
||||||
|
|
||||||
|
namespace furvm {}
|
||||||
Reference in New Issue
Block a user