forked from KPGPMC/furlang
refactor(IR)!: change IR block structure
It now requires an exit instruction.
This commit is contained in:
@@ -18,14 +18,26 @@ public:
|
||||
block() = default;
|
||||
public:
|
||||
template <typename T, typename... Args, typename = std::enable_if_t<std::is_base_of_v<instruction, T>>>
|
||||
void emplace(Args&&... args) {
|
||||
m_instructions.emplace_back(std::make_unique<T>(std::forward<Args>(args)...));
|
||||
bool emplace(Args&&... args) {
|
||||
if (has_exit()) return false;
|
||||
auto instr = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
if (is_exit_instruction(instr->type())) {
|
||||
m_exit = std::move(instr);
|
||||
} else {
|
||||
m_instructions.emplace_back(std::move(instr));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<value_type>& instructions() { return m_instructions; }
|
||||
const std::vector<value_type>& instructions() const { return m_instructions; }
|
||||
|
||||
bool has_exit() const { return m_exit != nullptr; }
|
||||
value_type& exit() { return m_exit; }
|
||||
const value_type& exit() const { return m_exit; }
|
||||
private:
|
||||
std::vector<value_type> m_instructions;
|
||||
value_type m_exit;
|
||||
};
|
||||
|
||||
} // namespace ir
|
||||
|
||||
@@ -20,6 +20,15 @@ enum class instruction_t {
|
||||
Return,
|
||||
};
|
||||
|
||||
static inline bool is_exit_instruction(instruction_t type) {
|
||||
switch (type) {
|
||||
case instruction_t::Branch:
|
||||
case instruction_t::BranchCond:
|
||||
case instruction_t::Return: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
class instruction {
|
||||
public:
|
||||
instruction() = default;
|
||||
|
||||
Reference in New Issue
Block a user