forked from KPGPMC/furlang
Compare commits
5 Commits
master
...
great-refactor
| Author | SHA1 | Date | |
|---|---|---|---|
|
c9f714642c
|
|||
|
0dfa8c1c02
|
|||
|
78acfb6ee2
|
|||
|
43dac1ec6d
|
|||
|
b35a274e81
|
@@ -22,7 +22,7 @@ public:
|
|||||||
ir_generator(const ir_generator&) = delete;
|
ir_generator(const ir_generator&) = delete;
|
||||||
ir_generator& operator=(const ir_generator&) = delete;
|
ir_generator& operator=(const ir_generator&) = delete;
|
||||||
public:
|
public:
|
||||||
furlang::ir::module&& move_module() { return std::move(m_module); }
|
furlang::ir::mod&& move_module() { return std::move(m_module); }
|
||||||
public:
|
public:
|
||||||
void visit(const ast::function_definition_node& funcDef) override;
|
void visit(const ast::function_definition_node& funcDef) override;
|
||||||
void visit(const ast::return_statement_node& returnStmt) override;
|
void visit(const ast::return_statement_node& returnStmt) override;
|
||||||
@@ -45,7 +45,7 @@ private:
|
|||||||
|
|
||||||
furlang::ir::block_index push_block(bool validate = true);
|
furlang::ir::block_index push_block(bool validate = true);
|
||||||
private:
|
private:
|
||||||
furlang::ir::module m_module;
|
furlang::ir::mod m_module;
|
||||||
std::unique_ptr<furlang::ir::function> m_currentFunction;
|
std::unique_ptr<furlang::ir::function> m_currentFunction;
|
||||||
std::shared_ptr<furlang::ir::block> m_currentBlock;
|
std::shared_ptr<furlang::ir::block> m_currentBlock;
|
||||||
ir_register m_registerCounter = 0;
|
ir_register m_registerCounter = 0;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace front {
|
|||||||
class ssa {
|
class ssa {
|
||||||
using block_map_t = std::unordered_map<furlang::ir::block_index, std::vector<furlang::ir::block_index>>;
|
using block_map_t = std::unordered_map<furlang::ir::block_index, std::vector<furlang::ir::block_index>>;
|
||||||
public:
|
public:
|
||||||
static void optimize(furlang::ir::module& mod);
|
static void optimize(furlang::ir::mod& mod);
|
||||||
private:
|
private:
|
||||||
static void optimize(const std::unique_ptr<furlang::ir::function>& func);
|
static void optimize(const std::unique_ptr<furlang::ir::function>& func);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
namespace furc::front {
|
namespace furc::front {
|
||||||
|
|
||||||
void ssa::optimize(furlang::ir::module& mod) {
|
void ssa::optimize(furlang::ir::mod& mod) {
|
||||||
for (const auto& func : mod.functions()) {
|
for (const auto& func : mod.functions()) {
|
||||||
ssa::optimize(func);
|
ssa::optimize(func);
|
||||||
ssa::constant_propagation(func);
|
ssa::constant_propagation(func);
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ namespace ir {
|
|||||||
/**
|
/**
|
||||||
* @brief IR module
|
* @brief IR module
|
||||||
*/
|
*/
|
||||||
class module {
|
class mod {
|
||||||
public:
|
public:
|
||||||
using value_type = std::unique_ptr<function>; /**< Value type. */
|
using value_type = std::unique_ptr<function>; /**< Value type. */
|
||||||
public:
|
public:
|
||||||
module() = default;
|
mod() = default;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Pushes and returns a new IR function.
|
* @brief Pushes and returns a new IR function.
|
||||||
@@ -49,4 +49,4 @@ private:
|
|||||||
} // namespace ir
|
} // namespace ir
|
||||||
} // namespace furlang
|
} // namespace furlang
|
||||||
|
|
||||||
#endif // FURLANG_IR_MODULE_HPP
|
#endif // FURLANG_IR_MODULE_HPP
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
#include "furvm/fwd.hpp"
|
#include "furvm/fwd.hpp"
|
||||||
#include "furvm/module.hpp"
|
#include "furvm/module.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
@@ -33,73 +37,70 @@ public:
|
|||||||
context& operator=(const context&) = delete;
|
context& operator=(const context&) = delete;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Adds a module to this context.
|
* @brief Emplaces a new module in this context.
|
||||||
*
|
*
|
||||||
* @param args Arguments to forward to module's constructor.
|
* @param args Arguments to forward to module's constructor.
|
||||||
* @return An index to the emplaced module.
|
* @return An index to the emplaced module.
|
||||||
*/
|
*/
|
||||||
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<mod, module_handle, Args...>>>
|
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<mod, Args...>>>
|
||||||
constexpr const auto& emplace(Args&&... args) {
|
auto& emplace_module(Args&&... args) {
|
||||||
module_handle id = static_cast<module_handle>(m_modules.size());
|
mod_p mod = std::make_shared<class mod>(std::forward<Args>(args)...);
|
||||||
return m_modules.emplace_back(std::make_unique<mod>(id, std::forward<Args>(args)...));
|
return m_modules.emplace(mod->name(), std::move(mod)).first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Erases a module from this context.
|
* @brief Erases a module from this context.
|
||||||
*
|
*
|
||||||
* @param index Index to the module.
|
* @param name Name of the module to erase.
|
||||||
* @return Old value.
|
* @return A shared pointer to the erased module.
|
||||||
*/
|
*/
|
||||||
mod_p erase(module_handle index) {
|
template <typename Name>
|
||||||
if (index >= m_modules.size()) return nullptr;
|
mod_p erase_module(Name&& name) {
|
||||||
return std::move(m_modules[index]);
|
return std::move(m_modules.erase(std::forward<Name>(name))->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a module of this context.
|
* @brief Returns a module of this context.
|
||||||
*
|
*
|
||||||
* @param index Position of the module.
|
* @param name Name of the module.
|
||||||
* @return The module.
|
* @return The module.
|
||||||
*/
|
*/
|
||||||
constexpr mod_p& operator[](module_handle index) { return m_modules[index]; }
|
template <typename Name>
|
||||||
|
constexpr mod_p& module_at(Name&& name) {
|
||||||
|
return m_modules.at(std::forward<Name>(name));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a module of this context.
|
* @brief Returns a module of this context.
|
||||||
*
|
*
|
||||||
* @param index Position of the module.
|
* @param name Name of the module.
|
||||||
* @return The module.
|
* @return The module.
|
||||||
*/
|
*/
|
||||||
constexpr const mod_p& operator[](module_handle index) const { return m_modules[index]; }
|
template <typename Name>
|
||||||
|
constexpr const mod_p& module_at(Name&& name) const {
|
||||||
/**
|
return m_modules.at(std::forward<Name>(name));
|
||||||
* @brief Returns a module of this context.
|
}
|
||||||
*
|
|
||||||
* @param index Position of the module.
|
|
||||||
* @return The module.
|
|
||||||
*/
|
|
||||||
constexpr mod_p& at(module_handle index) { return m_modules.at(index); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a module of this context.
|
|
||||||
*
|
|
||||||
* @param index Position of the module.
|
|
||||||
* @return The module.
|
|
||||||
*/
|
|
||||||
constexpr const mod_p& at(module_handle index) const { return m_modules.at(index); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns how many does this context have modules.
|
* @brief Returns how many does this context have modules.
|
||||||
*
|
*
|
||||||
* @return The module count.
|
* @return The module count.
|
||||||
*/
|
*/
|
||||||
constexpr size_t size() const { return m_modules.size(); }
|
constexpr size_t module_count() const { return m_modules.size(); }
|
||||||
|
public:
|
||||||
|
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<executor, Args...>>>
|
||||||
|
auto& emplace_executor(Args&&... args) {
|
||||||
|
executor_p executor = std::make_shared<class executor>(std::forward<Args>(args)...);
|
||||||
|
return m_executors.emplace_back(std::move(executor));
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Removes unreferenced things from the thing list.
|
* @brief Removes unreferenced things from the thing list.
|
||||||
*/
|
*/
|
||||||
void collect();
|
void collect();
|
||||||
private:
|
private:
|
||||||
std::vector<mod_p> m_modules;
|
std::unordered_map<std::string, mod_p> m_modules;
|
||||||
|
|
||||||
std::vector<thing_p> m_things;
|
std::vector<thing_p> m_things;
|
||||||
std::vector<executor_p> m_executors;
|
std::vector<executor_p> m_executors;
|
||||||
|
|
||||||
@@ -110,4 +111,4 @@ private:
|
|||||||
|
|
||||||
} // namespace furvm
|
} // namespace furvm
|
||||||
|
|
||||||
#endif // FURVM_CONTEXT_HPP
|
#endif // FURVM_CONTEXT_HPP
|
||||||
|
|||||||
@@ -26,15 +26,6 @@ static inline executor_flags operator~(executor_flags flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class executor {
|
class executor {
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief A private token for the private constructor.
|
|
||||||
*
|
|
||||||
* Also `egzekutor` in Polish translates to `executor` I think.
|
|
||||||
*/
|
|
||||||
struct egzekutor {
|
|
||||||
explicit egzekutor() = default;
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Executor frame.
|
* @brief Executor frame.
|
||||||
@@ -50,14 +41,14 @@ public:
|
|||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Private constructor.
|
* @brief Returns a new executor.
|
||||||
*
|
*
|
||||||
* @param id
|
* @param context Context.
|
||||||
* @param context
|
|
||||||
*/
|
*/
|
||||||
executor(egzekutor, executor_handle id, const context_p& context);
|
executor(const context_p& context)
|
||||||
|
: m_context(context) {}
|
||||||
|
|
||||||
~executor();
|
~executor() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move constructor.
|
* @brief Move constructor.
|
||||||
@@ -72,21 +63,6 @@ public:
|
|||||||
executor(const executor&) = delete;
|
executor(const executor&) = delete;
|
||||||
executor& operator=(const executor&) = delete;
|
executor& operator=(const executor&) = delete;
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* @brief Returns a new executor.
|
|
||||||
*
|
|
||||||
* @param context Furvm context.
|
|
||||||
* @return Shared pointer to the new executor.
|
|
||||||
*/
|
|
||||||
static executor_p create(const context_p& context);
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Returns an id of this executor.
|
|
||||||
*
|
|
||||||
* @return The id.
|
|
||||||
*/
|
|
||||||
executor_handle id() const { return m_id; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns flags of this executor.
|
* @brief Returns flags of this executor.
|
||||||
*
|
*
|
||||||
@@ -97,9 +73,10 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Pushes a new frame.
|
* @brief Pushes a new frame.
|
||||||
*
|
*
|
||||||
* @param function Function.
|
* @param mod Module.
|
||||||
|
* @param function Function handle.
|
||||||
*/
|
*/
|
||||||
void push_frame(const function_p& function);
|
void push_frame(const mod_p& mod, function_handle function);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Pops the top frame.
|
* @brief Pops the top frame.
|
||||||
@@ -172,9 +149,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void step();
|
void step();
|
||||||
private:
|
private:
|
||||||
executor_handle m_id;
|
executor_flags m_flags{}; // NOLINT(bugprone-invalid-enum-default-initialization)
|
||||||
executor_flags m_flags{}; // NOLINT(bugprone-invalid-enum-default-initialization)
|
context_p m_context;
|
||||||
context_p m_context;
|
|
||||||
|
|
||||||
std::stack<struct frame> m_frames;
|
std::stack<struct frame> m_frames;
|
||||||
std::stack<thing_p> m_stack;
|
std::stack<thing_p> m_stack;
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
#define FURVM_FUNCTION_HPP
|
#define FURVM_FUNCTION_HPP
|
||||||
|
|
||||||
#include "furvm/fwd.hpp"
|
#include "furvm/fwd.hpp"
|
||||||
#include "furvm/module.hpp" // IWYU pragma: keep
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
@@ -18,35 +19,32 @@ enum class function_t : std::uint8_t {
|
|||||||
using native_function = std::function<void(executor&)>;
|
using native_function = std::function<void(executor&)>;
|
||||||
|
|
||||||
class function {
|
class function {
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief A private token for the private constructor.
|
|
||||||
*
|
|
||||||
* Also `funkcja` in Polish translates to `function` from what I heard.
|
|
||||||
*/
|
|
||||||
struct funkcja {
|
|
||||||
explicit funkcja() = default;
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
/**
|
template <typename Name>
|
||||||
* @brief Private constructor.
|
function(Name&& name, bytecode_pos position)
|
||||||
*
|
: m_name(std::forward<Name>(name)), m_type(function_t::Normal), m_value(position) {}
|
||||||
* @param id
|
|
||||||
* @param position
|
|
||||||
* @param mod
|
|
||||||
*/
|
|
||||||
function(funkcja, function_handle id, std::size_t position, const mod_p& mod);
|
|
||||||
|
|
||||||
/**
|
function(const char* name, bytecode_pos position)
|
||||||
* @brief Private constructor.
|
: m_name(name), m_type(function_t::Normal), m_value(position) {}
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @param native
|
|
||||||
* @param mod
|
|
||||||
*/
|
|
||||||
function(funkcja, function_handle id, const native_function& native, const mod_p& mod);
|
|
||||||
|
|
||||||
~function() = default;
|
template <typename Name>
|
||||||
|
function(Name&& name, const native_function& native)
|
||||||
|
: m_name(std::forward<Name>(name)), m_type(function_t::Native), m_value(native) {}
|
||||||
|
|
||||||
|
function(const char* name, const native_function& native)
|
||||||
|
: m_name(name), m_type(function_t::Native), m_value(native) {}
|
||||||
|
|
||||||
|
template <typename Name, typename ModuleName>
|
||||||
|
function(Name&& name, ModuleName&& moduleName, function_handle function)
|
||||||
|
: m_name(std::forward<Name>(name)),
|
||||||
|
m_type(function_t::Import),
|
||||||
|
m_value(std::forward<ModuleName>(moduleName), function) {}
|
||||||
|
|
||||||
|
template <typename ModuleName>
|
||||||
|
function(const char* name, ModuleName&& moduleName, function_handle function)
|
||||||
|
: m_name(name), m_type(function_t::Import), m_value(std::forward<ModuleName>(moduleName), function) {}
|
||||||
|
|
||||||
|
~function();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move constructor.
|
* @brief Move constructor.
|
||||||
@@ -62,28 +60,11 @@ public:
|
|||||||
function& operator=(const function&) = delete;
|
function& operator=(const function&) = delete;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns a new function.
|
* @brief Returns a name of this function.
|
||||||
*
|
*
|
||||||
* @param mod Module.
|
* @return The name.
|
||||||
* @param args Arguments to pass to the function constructor.
|
|
||||||
* @return The new function.
|
|
||||||
*/
|
*/
|
||||||
template <typename... Args,
|
constexpr const std::string& name() const { return m_name; }
|
||||||
typename = std::enable_if_t<std::is_constructible_v<function, funkcja, function_handle, Args..., const mod_p&>>>
|
|
||||||
static function_p create(const mod_p& mod, Args&&... args) {
|
|
||||||
function_handle id = mod->m_functions.size();
|
|
||||||
|
|
||||||
auto func = std::make_shared<function>(funkcja{}, id, std::forward<Args>(args)..., mod);
|
|
||||||
mod->m_functions.emplace(mod->m_functions.begin() + id, func);
|
|
||||||
return std::move(func);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Returns an id of this function.
|
|
||||||
*
|
|
||||||
* @return The id.
|
|
||||||
*/
|
|
||||||
constexpr function_handle id() const { return m_id; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a type of this function.
|
* @brief Returns a type of this function.
|
||||||
@@ -91,13 +72,6 @@ public:
|
|||||||
* @return The type.
|
* @return The type.
|
||||||
*/
|
*/
|
||||||
constexpr function_t type() const { return m_type; }
|
constexpr function_t type() const { return m_type; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a parent module of this function.
|
|
||||||
*
|
|
||||||
* @return A shared pointer to the module.
|
|
||||||
*/
|
|
||||||
const mod_p& mod() const { return m_module; }
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns a value for normal function.
|
* @brief Returns a value for normal function.
|
||||||
@@ -120,13 +94,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a module of imported function.
|
* @brief Returns a name of the function's module.
|
||||||
*
|
*
|
||||||
* @return A handle to the module.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
module_handle imported_module() const {
|
const std::string& imported_module() const {
|
||||||
if (m_type != function_t::Import) throw std::runtime_error("function type mismatch");
|
if (m_type != function_t::Import) throw std::runtime_error("function type mismatch");
|
||||||
return m_value.imp.mod;
|
return m_value.imp.moduleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,15 +113,14 @@ public:
|
|||||||
return m_value.imp.function;
|
return m_value.imp.function;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
function_handle m_id;
|
std::string m_name;
|
||||||
function_t m_type;
|
function_t m_type;
|
||||||
mod_p m_module;
|
|
||||||
|
|
||||||
union value {
|
union value {
|
||||||
std::size_t position = 0;
|
std::size_t position = 0;
|
||||||
native_function native;
|
native_function native;
|
||||||
struct {
|
struct {
|
||||||
module_handle mod;
|
std::string moduleName;
|
||||||
function_handle function;
|
function_handle function;
|
||||||
} imp;
|
} imp;
|
||||||
|
|
||||||
@@ -159,8 +132,9 @@ private:
|
|||||||
value(const native_function& native)
|
value(const native_function& native)
|
||||||
: native(native) {}
|
: native(native) {}
|
||||||
|
|
||||||
value(module_handle mod, function_handle function)
|
template <typename Name>
|
||||||
: imp({ mod, function }) {}
|
value(Name&& moduleName, function_handle function)
|
||||||
|
: imp({ std::forward<Name>(moduleName), function }) {}
|
||||||
|
|
||||||
~value() {}
|
~value() {}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ namespace furvm {
|
|||||||
*/
|
*/
|
||||||
using byte = std::uint8_t;
|
using byte = std::uint8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An offset into bytecode.
|
||||||
|
*/
|
||||||
|
using bytecode_pos = std::uint64_t;
|
||||||
|
|
||||||
// constant.hpp
|
// constant.hpp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,11 +98,6 @@ class mod;
|
|||||||
*/
|
*/
|
||||||
using mod_p = std::shared_ptr<mod>;
|
using mod_p = std::shared_ptr<mod>;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Furvm module's index.
|
|
||||||
*/
|
|
||||||
using module_handle = std::uint32_t;
|
|
||||||
|
|
||||||
// thing.hpp
|
// thing.hpp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
#ifndef FURVM_MODULE_HPP
|
#ifndef FURVM_MODULE_HPP
|
||||||
#define FURVM_MODULE_HPP
|
#define FURVM_MODULE_HPP
|
||||||
|
|
||||||
|
#include "furvm/function.hpp"
|
||||||
#include "furvm/fwd.hpp"
|
#include "furvm/fwd.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
@@ -16,12 +23,24 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Construct a new module.
|
* @brief Construct a new module.
|
||||||
*
|
*
|
||||||
* @param id Id of this module.
|
* @param name Name of this module.
|
||||||
|
* @param args Arguments to forward to bytecode's constructor.
|
||||||
|
*/
|
||||||
|
template <typename Name,
|
||||||
|
typename... Args,
|
||||||
|
typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>>
|
||||||
|
mod(Name&& name, Args&&... args)
|
||||||
|
: m_name(std::forward<Name>(name)), m_bytecode(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Construct a new module.
|
||||||
|
*
|
||||||
|
* @param name C-string name of this module.
|
||||||
* @param args Arguments to forward to bytecode's constructor.
|
* @param args Arguments to forward to bytecode's constructor.
|
||||||
*/
|
*/
|
||||||
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>>
|
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>>
|
||||||
mod(module_handle id, Args&&... args)
|
mod(const char* name, Args&&... args)
|
||||||
: m_id(id), m_bytecode(std::forward<Args>(args)...) {}
|
: m_name(name), m_bytecode(std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
~mod() = default;
|
~mod() = default;
|
||||||
|
|
||||||
@@ -39,11 +58,11 @@ public:
|
|||||||
mod& operator=(const mod&) = delete;
|
mod& operator=(const mod&) = delete;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns an id of this module.
|
* @brief Returns this module's name.
|
||||||
*
|
*
|
||||||
* @return The id.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
constexpr module_handle id() const { return m_id; }
|
constexpr const std::string& name() const { return m_name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a byte from bytecode of this module.
|
* @brief Returns a byte from bytecode of this module.
|
||||||
@@ -52,7 +71,32 @@ public:
|
|||||||
* @return The byte.
|
* @return The byte.
|
||||||
*/
|
*/
|
||||||
constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); }
|
constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a reference to the module's bytecode.
|
||||||
|
*
|
||||||
|
* @return The reference to bytecode.
|
||||||
|
*/
|
||||||
|
constexpr bytecode_t& bytecode() { return m_bytecode; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a const reference to the module's bytecode.
|
||||||
|
*
|
||||||
|
* @return The reference to bytecode.
|
||||||
|
*/
|
||||||
|
constexpr const bytecode_t& bytecode() const { return m_bytecode; }
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a function from this module.
|
||||||
|
*
|
||||||
|
* @param name Name of the function.
|
||||||
|
* @return The function.
|
||||||
|
*/
|
||||||
|
template <typename Name>
|
||||||
|
constexpr const function_p& function_at(Name&& name) const {
|
||||||
|
return m_functions.at(std::forward<Name>(name));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a function from this module.
|
* @brief Returns a function from this module.
|
||||||
*
|
*
|
||||||
@@ -60,10 +104,33 @@ public:
|
|||||||
* @return The function.
|
* @return The function.
|
||||||
*/
|
*/
|
||||||
constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); }
|
constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns an id of a function.
|
||||||
|
*
|
||||||
|
* @param function Function to get the id of.
|
||||||
|
* @return The function's id.
|
||||||
|
*/
|
||||||
|
function_handle function_id(const function_p& function) const {
|
||||||
|
if (auto it = std::find(m_functions.begin(), m_functions.end(), function); it != m_functions.end())
|
||||||
|
return it - m_functions.begin();
|
||||||
|
throw std::runtime_error("function not in the module");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
function_handle emplace_function(Args&&... args) {
|
||||||
|
function_p function = std::make_shared<class function>(std::forward<Args>(args)...);
|
||||||
|
m_functionMap.emplace(function->name(), function);
|
||||||
|
function_handle id = m_functions.size();
|
||||||
|
m_functions.emplace_back(std::move(function));
|
||||||
|
return id;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
module_handle m_id;
|
std::string m_name;
|
||||||
bytecode_t m_bytecode;
|
bytecode_t m_bytecode;
|
||||||
std::vector<function_p> m_functions;
|
|
||||||
|
std::unordered_map<std::string, function_p> m_functionMap;
|
||||||
|
std::vector<function_p> m_functions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace furvm
|
} // namespace furvm
|
||||||
|
|||||||
@@ -53,28 +53,12 @@ public:
|
|||||||
|
|
||||||
class thing final {
|
class thing final {
|
||||||
friend class executor;
|
friend class executor;
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief A private token for the private constructor.
|
|
||||||
*
|
|
||||||
* Also `rzecz` in Polish translates to `thing` I think.
|
|
||||||
*/
|
|
||||||
struct rzecz {
|
|
||||||
explicit rzecz() = default;
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
using nref_t = std::size_t; /**< Type of reference count. */
|
using nref_t = std::size_t; /**< Type of reference count. */
|
||||||
|
|
||||||
static constexpr thing_handle GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */
|
static constexpr thing_handle GENERATION_SIZE = 12; /**< Bit size of generation part in thing_handle. */
|
||||||
public:
|
public:
|
||||||
/**
|
thing(const context_p& context, thing_t type);
|
||||||
* @brief Private constructor.
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @param type
|
|
||||||
* @param context
|
|
||||||
*/
|
|
||||||
thing(rzecz, thing_handle id, thing_t type, const context_p& context);
|
|
||||||
|
|
||||||
~thing();
|
~thing();
|
||||||
|
|
||||||
@@ -189,29 +173,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
friend thing_p operator>=(const thing_p& lhs, const thing_p& rhs);
|
friend thing_p operator>=(const thing_p& lhs, const thing_p& rhs);
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* @brief Returns a new thing.
|
|
||||||
*
|
|
||||||
* @param context Furvm context.
|
|
||||||
* @param args Arguments to forward to the thing constructor.
|
|
||||||
* @return Shared pointer to the new thing.
|
|
||||||
*/
|
|
||||||
template <typename... Args,
|
|
||||||
typename = std::enable_if_t<std::is_constructible_v<thing, rzecz, thing_handle, Args..., const context_p&>>>
|
|
||||||
static thing_p create(const context_p& context, Args&&... args) {
|
|
||||||
thing_handle id = context->m_things.size();
|
|
||||||
if (!context->m_deadThings.empty()) {
|
|
||||||
id = context->m_deadThings.front();
|
|
||||||
context->m_deadThings.pop();
|
|
||||||
id += 1 << GENERATION_SIZE;
|
|
||||||
}
|
|
||||||
thing_handle idx = id & ((1ULL << ((sizeof(id) * 8) - GENERATION_SIZE)) - 1);
|
|
||||||
|
|
||||||
auto th = std::make_shared<thing>(rzecz{}, id, std::forward<Args>(args)..., context);
|
|
||||||
context->m_things.emplace(context->m_things.begin() + idx, th);
|
|
||||||
return std::move(th);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a clone of the thing.
|
* @brief Returns a clone of the thing.
|
||||||
*
|
*
|
||||||
@@ -251,9 +212,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
constexpr nref_t reference_count() const { return m_refCount; }
|
constexpr nref_t reference_count() const { return m_refCount; }
|
||||||
private:
|
private:
|
||||||
thing_handle m_id;
|
context_p m_context;
|
||||||
thing_t m_type;
|
thing_t m_type;
|
||||||
context_p m_context;
|
|
||||||
|
|
||||||
nref_t m_refCount = 0;
|
nref_t m_refCount = 0;
|
||||||
void* m_data = nullptr;
|
void* m_data = nullptr;
|
||||||
|
|||||||
+8
-19
@@ -8,26 +8,15 @@
|
|||||||
#include "furvm/thing.hpp"
|
#include "furvm/thing.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
executor::executor(egzekutor, executor_handle id, const context_p& context)
|
void executor::push_frame(const mod_p& mod, function_handle function) {
|
||||||
: m_id(id), m_context(context) {}
|
const auto& func = mod->function_at(function);
|
||||||
|
if (func->type() != function_t::Normal) throw std::runtime_error("unexpected function type");
|
||||||
executor::~executor() {
|
m_frames.emplace((struct executor::frame){ mod, func->position(), m_stack.size() });
|
||||||
m_context->m_executors[m_id] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
executor_p executor::create(const context_p& context) {
|
|
||||||
auto ex = std::make_shared<executor>(egzekutor{}, context->m_executors.size(), context);
|
|
||||||
context->m_executors.push_back(ex);
|
|
||||||
return std::move(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void executor::push_frame(const function_p& function) {
|
|
||||||
if (function->type() != function_t::Normal) return;
|
|
||||||
m_frames.emplace((struct executor::frame){ function->mod(), function->position(), m_stack.size() });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct executor::frame executor::pop_frame() {
|
struct executor::frame executor::pop_frame() {
|
||||||
@@ -98,7 +87,7 @@ void executor::step() {
|
|||||||
switch (instr) {
|
switch (instr) {
|
||||||
case instruction_t::NoOperation: break;
|
case instruction_t::NoOperation: break;
|
||||||
case instruction_t::PushB2I: {
|
case instruction_t::PushB2I: {
|
||||||
auto thing = thing::create(m_context, thing_t::Int32);
|
auto thing = std::make_shared<class thing>(m_context, thing_t::Int32);
|
||||||
thing->int32() = frame.mod->byte(frame.position++);
|
thing->int32() = frame.mod->byte(frame.position++);
|
||||||
push_thing(std::move(thing));
|
push_thing(std::move(thing));
|
||||||
} break;
|
} break;
|
||||||
@@ -185,11 +174,11 @@ void executor::step() {
|
|||||||
|
|
||||||
const function_p& function = frame.mod->function_at(funcId);
|
const function_p& function = frame.mod->function_at(funcId);
|
||||||
switch (function->type()) {
|
switch (function->type()) {
|
||||||
case function_t::Normal: push_frame(function); break;
|
case function_t::Normal: push_frame(frame.mod, funcId); break;
|
||||||
case function_t::Native: function->native()(*this); break;
|
case function_t::Native: function->native()(*this); break;
|
||||||
case function_t::Import: {
|
case function_t::Import: {
|
||||||
const mod_p& impMod = m_context->m_modules.at(function->imported_module());
|
const mod_p& impMod = m_context->m_modules.at(function->imported_module());
|
||||||
push_frame(impMod->function_at(function->imported_function()));
|
push_frame(frame.mod, function->imported_function());
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
+19
-13
@@ -1,15 +1,22 @@
|
|||||||
#include "furvm/function.hpp"
|
#include "furvm/function.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace furvm {
|
namespace furvm {
|
||||||
|
|
||||||
function::function(funkcja, function_handle id, std::size_t position, const mod_p& mod)
|
function::~function() {
|
||||||
: m_id(id), m_type(function_t::Normal), m_module(mod), m_value(position) {}
|
switch (m_type) {
|
||||||
|
case function_t::Normal:
|
||||||
function::function(funkcja, function_handle id, const native_function& native, const mod_p& mod)
|
case function_t::Native:
|
||||||
: m_id(id), m_type(function_t::Native), m_module(mod), m_value(native) {}
|
default: break;
|
||||||
|
case function_t::Import: {
|
||||||
|
m_value.imp.moduleName.~basic_string();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function::function(function&& other) noexcept
|
function::function(function&& other) noexcept
|
||||||
: m_id(other.m_id), m_type(other.m_type), m_module(std::move(other.m_module)) {
|
: m_name(std::move(other.m_name)), m_type(other.m_type) {
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case function_t::Normal: {
|
case function_t::Normal: {
|
||||||
m_value.position = other.m_value.position;
|
m_value.position = other.m_value.position;
|
||||||
@@ -18,8 +25,8 @@ function::function(function&& other) noexcept
|
|||||||
new (&m_value.native) native_function(std::move(other.m_value.native));
|
new (&m_value.native) native_function(std::move(other.m_value.native));
|
||||||
} break;
|
} break;
|
||||||
case function_t::Import: {
|
case function_t::Import: {
|
||||||
m_value.imp.mod = other.m_value.imp.mod;
|
m_value.imp.moduleName = std::move(other.m_value.imp.moduleName);
|
||||||
m_value.imp.function = other.m_value.imp.function;
|
m_value.imp.function = other.m_value.imp.function;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
other.m_value.position = 0;
|
other.m_value.position = 0;
|
||||||
@@ -28,9 +35,8 @@ function::function(function&& other) noexcept
|
|||||||
function& function::operator=(function&& other) noexcept {
|
function& function::operator=(function&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
|
|
||||||
m_id = other.m_id;
|
m_name = std::move(other.m_name);
|
||||||
m_type = other.m_type;
|
m_type = other.m_type;
|
||||||
m_module = std::move(other.m_module);
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case function_t::Normal: {
|
case function_t::Normal: {
|
||||||
m_value.position = other.m_value.position;
|
m_value.position = other.m_value.position;
|
||||||
@@ -39,8 +45,8 @@ function& function::operator=(function&& other) noexcept {
|
|||||||
new (&m_value.native) native_function(std::move(other.m_value.native));
|
new (&m_value.native) native_function(std::move(other.m_value.native));
|
||||||
} break;
|
} break;
|
||||||
case function_t::Import: {
|
case function_t::Import: {
|
||||||
m_value.imp.mod = other.m_value.imp.mod;
|
m_value.imp.moduleName = std::move(other.m_value.imp.moduleName);
|
||||||
m_value.imp.function = other.m_value.imp.function;
|
m_value.imp.function = other.m_value.imp.function;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
other.m_value.position = 0;
|
other.m_value.position = 0;
|
||||||
|
|||||||
+4
-8
@@ -24,15 +24,11 @@ static constexpr std::array<furvm::byte, 8> s_bytecode = {
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
auto context = std::make_shared<furvm::context>();
|
auto context = std::make_shared<furvm::context>();
|
||||||
|
|
||||||
auto mainModule = context->emplace(s_bytecode.begin(), s_bytecode.end());
|
auto mainModule = context->emplace_module("main", s_bytecode.begin(), s_bytecode.end());
|
||||||
|
mainModule->emplace_function("main", 0);
|
||||||
|
|
||||||
auto mainFunction = furvm::function::create(mainModule, 0);
|
auto executor = context->emplace_executor(context);
|
||||||
|
executor->push_frame(mainModule, 0);
|
||||||
std::ofstream file("./test.furm", std::ios::binary);
|
|
||||||
furvm::serializer::serialize_module(file, mainModule);
|
|
||||||
|
|
||||||
auto executor = furvm::executor::create(context);
|
|
||||||
executor->push_frame(mainFunction);
|
|
||||||
|
|
||||||
static constexpr std::size_t FPC = 3; // Frames per collection
|
static constexpr std::size_t FPC = 3; // Frames per collection
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "furvm/serializer.hpp"
|
#include "furvm/serializer.hpp"
|
||||||
|
|
||||||
#include "furvm/function.hpp" // IWYU pragma: keep
|
#include "furvm/function.hpp" // IWYU pragma: keep
|
||||||
|
#include "furvm/fwd.hpp"
|
||||||
|
#include "furvm/module.hpp" // IWYU pragma: keep
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -73,8 +75,9 @@ bool serializer::serialize_module(std::ostream& os, const mod_p& mod) {
|
|||||||
write_u32(os, VERSION);
|
write_u32(os, VERSION);
|
||||||
|
|
||||||
write_u32(os, mod->m_functions.size());
|
write_u32(os, mod->m_functions.size());
|
||||||
for (const auto& func : mod->m_functions) {
|
for (function_handle id = 0; id < static_cast<function_handle>(mod->m_functions.size()); ++id) {
|
||||||
write_u16(os, func->id());
|
const auto& func = mod->m_functions[id];
|
||||||
|
write_u16(os, id);
|
||||||
write_u8(os, static_cast<std::uint8_t>(func->type()));
|
write_u8(os, static_cast<std::uint8_t>(func->type()));
|
||||||
switch (func->type()) {
|
switch (func->type()) {
|
||||||
case function_t::Normal: {
|
case function_t::Normal: {
|
||||||
|
|||||||
+16
-23
@@ -17,8 +17,8 @@ std::size_t thing_type_size(thing_t type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
thing::thing(rzecz, thing_handle id, thing_t type, const context_p& context)
|
thing::thing(const context_p& context, thing_t type)
|
||||||
: m_id(id), m_type(type), m_context(context) {
|
: m_context(context), m_type(type) {
|
||||||
std::size_t size = thing_type_size(type);
|
std::size_t size = thing_type_size(type);
|
||||||
std::byte* data = nullptr;
|
std::byte* data = nullptr;
|
||||||
if (!m_context->m_deadThingData.empty()) {
|
if (!m_context->m_deadThingData.empty()) {
|
||||||
@@ -56,12 +56,7 @@ thing::~thing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
thing::thing(thing&& other) noexcept
|
thing::thing(thing&& other) noexcept
|
||||||
: m_id(other.m_id),
|
: m_context(std::move(other.m_context)), m_type(other.m_type), m_refCount(other.m_refCount), m_data(other.m_data) {
|
||||||
m_type(other.m_type),
|
|
||||||
m_context(std::move(other.m_context)),
|
|
||||||
m_refCount(other.m_refCount),
|
|
||||||
m_data(other.m_data) {
|
|
||||||
other.m_id = {};
|
|
||||||
other.m_type = {};
|
other.m_type = {};
|
||||||
other.m_refCount = {};
|
other.m_refCount = {};
|
||||||
other.m_data = nullptr;
|
other.m_data = nullptr;
|
||||||
@@ -69,13 +64,11 @@ thing::thing(thing&& other) noexcept
|
|||||||
|
|
||||||
thing& thing::operator=(thing&& other) noexcept {
|
thing& thing::operator=(thing&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
m_id = other.m_id;
|
|
||||||
m_type = other.m_type;
|
|
||||||
m_context = std::move(other.m_context);
|
m_context = std::move(other.m_context);
|
||||||
|
m_type = other.m_type;
|
||||||
m_refCount = other.m_refCount;
|
m_refCount = other.m_refCount;
|
||||||
m_data = other.m_data;
|
m_data = other.m_data;
|
||||||
|
|
||||||
other.m_id = {};
|
|
||||||
other.m_type = {};
|
other.m_type = {};
|
||||||
other.m_refCount = {};
|
other.m_refCount = {};
|
||||||
other.m_data = nullptr;
|
other.m_data = nullptr;
|
||||||
@@ -89,7 +82,7 @@ static constexpr std::uint16_t thing_type_pair(thing_t lhs, thing_t rhs) {
|
|||||||
thing_p operator+(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator+(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = lhs->int32() + rhs->int32();
|
res->int32() = lhs->int32() + rhs->int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -100,7 +93,7 @@ thing_p operator+(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator-(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator-(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = lhs->int32() - rhs->int32();
|
res->int32() = lhs->int32() - rhs->int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -111,7 +104,7 @@ thing_p operator-(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator*(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator*(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = lhs->int32() * rhs->int32();
|
res->int32() = lhs->int32() * rhs->int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -122,7 +115,7 @@ thing_p operator*(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator/(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator/(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = lhs->int32() / rhs->int32();
|
res->int32() = lhs->int32() / rhs->int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -133,7 +126,7 @@ thing_p operator/(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator%(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator%(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = lhs->int32() % rhs->int32();
|
res->int32() = lhs->int32() % rhs->int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -144,7 +137,7 @@ thing_p operator%(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator==(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator==(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() == rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() == rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -155,7 +148,7 @@ thing_p operator==(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator!=(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator!=(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() != rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() != rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -166,7 +159,7 @@ thing_p operator!=(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator<(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator<(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() < rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() < rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -177,7 +170,7 @@ thing_p operator<(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator>(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator>(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() > rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() > rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -188,7 +181,7 @@ thing_p operator>(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator<=(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator<=(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() <= rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() <= rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -199,7 +192,7 @@ thing_p operator<=(const thing_p& lhs, const thing_p& rhs) {
|
|||||||
thing_p operator>=(const thing_p& lhs, const thing_p& rhs) {
|
thing_p operator>=(const thing_p& lhs, const thing_p& rhs) {
|
||||||
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
switch (thing_type_pair(lhs->m_type, rhs->m_type)) {
|
||||||
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
case thing_type_pair(thing_t::Int32, thing_t::Int32): {
|
||||||
auto res = thing::create(lhs->m_context, thing_t::Int32);
|
auto res = std::make_shared<thing>(lhs->m_context, thing_t::Int32);
|
||||||
res->int32() = static_cast<std::int32_t>(lhs->int32() >= rhs->int32());
|
res->int32() = static_cast<std::int32_t>(lhs->int32() >= rhs->int32());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -216,7 +209,7 @@ thing_p thing::clone(const thing_p& thing) {
|
|||||||
}
|
}
|
||||||
thing_handle idx = id & ((1ULL << ((sizeof(id) * 8) - GENERATION_SIZE)) - 1);
|
thing_handle idx = id & ((1ULL << ((sizeof(id) * 8) - GENERATION_SIZE)) - 1);
|
||||||
|
|
||||||
auto th = std::make_shared<class thing>(rzecz{}, id, thing->m_type, thing->m_context);
|
auto th = std::make_shared<class thing>(thing->m_context, thing->m_type);
|
||||||
switch (thing->m_type) {
|
switch (thing->m_type) {
|
||||||
// Primitives
|
// Primitives
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
Reference in New Issue
Block a user