forked from KPGPMC/furlang
Add IR operand to furlang
Signed-off-by: CHatingPython <chatingpython@gmail.com>
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
#ifndef FURLANG_IR_OPERAND_HPP
|
||||
#define FURLANG_IR_OPERAND_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace furlang {
|
||||
namespace ir {
|
||||
|
||||
enum class operand_t {
|
||||
None,
|
||||
Register,
|
||||
Integer,
|
||||
String,
|
||||
};
|
||||
|
||||
using register_operand = std::uint32_t;
|
||||
using integer_operand = std::uint64_t;
|
||||
using string_operand = std::string;
|
||||
|
||||
class operand {
|
||||
public:
|
||||
~operand() {
|
||||
if (m_type == operand_t::String) {
|
||||
m_value.string.~basic_string();
|
||||
}
|
||||
}
|
||||
|
||||
operand(operand&& other) noexcept
|
||||
: m_type(other.m_type) {
|
||||
switch (m_type) {
|
||||
case operand_t::None: break;
|
||||
case operand_t::Register: {
|
||||
m_value.reg = other.m_value.reg;
|
||||
} break;
|
||||
case operand_t::Integer: {
|
||||
m_value.integer = other.m_value.integer;
|
||||
} break;
|
||||
case operand_t::String: {
|
||||
new (&m_value.string) std::string(std::move(other.m_value.string));
|
||||
} break;
|
||||
}
|
||||
other.m_value.destroy(other.m_type);
|
||||
}
|
||||
|
||||
operand& operator=(operand&& other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
m_type = other.m_type;
|
||||
switch (m_type) {
|
||||
case operand_t::None: break;
|
||||
case operand_t::Register: {
|
||||
m_value.reg = other.m_value.reg;
|
||||
} break;
|
||||
case operand_t::Integer: {
|
||||
m_value.integer = other.m_value.integer;
|
||||
} break;
|
||||
case operand_t::String: {
|
||||
new (&m_value.string) std::string(std::move(other.m_value.string));
|
||||
} break;
|
||||
}
|
||||
other.m_value.destroy(other.m_type);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operand(const operand&) = delete;
|
||||
operand& operator=(const operand&) = delete;
|
||||
public:
|
||||
static operand new_reg(register_operand value) {
|
||||
operand operand;
|
||||
operand.m_type = operand_t::Register;
|
||||
new (&operand.m_value) union value(value);
|
||||
return operand;
|
||||
}
|
||||
|
||||
static operand new_integer(integer_operand value) {
|
||||
operand operand;
|
||||
operand.m_type = operand_t::Integer;
|
||||
new (&operand.m_value) union value(value);
|
||||
return operand;
|
||||
}
|
||||
|
||||
static operand new_string(const string_operand& value) {
|
||||
operand operand;
|
||||
operand.m_type = operand_t::String;
|
||||
new (&operand.m_value) union value(value);
|
||||
return operand;
|
||||
}
|
||||
|
||||
static operand new_string(string_operand&& value) {
|
||||
operand operand;
|
||||
operand.m_type = operand_t::String;
|
||||
new (&operand.m_value) union value(std::move(value));
|
||||
return operand;
|
||||
}
|
||||
public:
|
||||
operand_t type() const { return m_type; }
|
||||
|
||||
register_operand reg() const { return m_value.reg; }
|
||||
integer_operand integer() const { return m_value.integer; }
|
||||
private:
|
||||
operand() = default;
|
||||
private:
|
||||
operand_t m_type = operand_t::None;
|
||||
union value {
|
||||
std::nullptr_t null = nullptr;
|
||||
register_operand reg;
|
||||
integer_operand integer;
|
||||
string_operand string;
|
||||
|
||||
void destroy(operand_t type) {
|
||||
switch (type) {
|
||||
case operand_t::String: {
|
||||
string.~basic_string();
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
null = nullptr;
|
||||
}
|
||||
|
||||
value() = default;
|
||||
~value() {}
|
||||
|
||||
value(register_operand reg)
|
||||
: reg(reg) {}
|
||||
|
||||
value(integer_operand integer)
|
||||
: integer(integer) {}
|
||||
|
||||
value(const std::string& string)
|
||||
: string(string) {}
|
||||
|
||||
value(std::string&& string)
|
||||
: string(std::move(string)) {}
|
||||
|
||||
value(value&&) noexcept = delete;
|
||||
value& operator=(value&&) noexcept = delete;
|
||||
value(const value&) = delete;
|
||||
value& operator=(const value&) = delete;
|
||||
} m_value;
|
||||
};
|
||||
|
||||
} // namespace ir
|
||||
} // namespace furlang
|
||||
|
||||
#endif // FURLANG_IR_OPERAND_HPP
|
||||
Reference in New Issue
Block a user