From dfcbc4f23b733da1e750678a475ab2e0abe77952 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Sun, 31 May 2026 12:33:31 +0200 Subject: [PATCH] Add IR instruction and block to furlang Signed-off-by: CHatingPython --- furlang/include/furlang/ir/block.hpp | 34 +++++ furlang/include/furlang/ir/instruction.hpp | 139 +++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 furlang/include/furlang/ir/block.hpp create mode 100644 furlang/include/furlang/ir/instruction.hpp diff --git a/furlang/include/furlang/ir/block.hpp b/furlang/include/furlang/ir/block.hpp new file mode 100644 index 0000000..3323552 --- /dev/null +++ b/furlang/include/furlang/ir/block.hpp @@ -0,0 +1,34 @@ +#ifndef FURLANG_IR_BLOCK_HPP +#define FURLANG_IR_BLOCK_HPP + +#include "furlang/ir/instruction.hpp" + +#include +#include +#include + +namespace furlang { +namespace ir { + +// https://en.wikipedia.org/wiki/Basic_block +class block { +public: + using value_type = std::shared_ptr; +public: + block() = default; +public: + template >> + void emplace(Args&&... args) { + m_instructions.emplace_back(std::make_shared(std::forward(args)...)); + } + + std::vector& instructions() { return m_instructions; } + const std::vector& instructions() const { return m_instructions; } +private: + std::vector m_instructions; +}; + +} // namespace ir +} // namespace furlang + +#endif // FURLANG_IR_BLOCK_HPP \ No newline at end of file diff --git a/furlang/include/furlang/ir/instruction.hpp b/furlang/include/furlang/ir/instruction.hpp new file mode 100644 index 0000000..58d756b --- /dev/null +++ b/furlang/include/furlang/ir/instruction.hpp @@ -0,0 +1,139 @@ +#ifndef FURLANG_IR_INSTRUCTION_HPP +#define FURLANG_IR_INSTRUCTION_HPP + +#include "furlang/ir/operand.hpp" + +#include + +namespace furlang { +namespace ir { + +enum class instruction_t { + Alloca, + Assign, + BinaryOp, + Call, + Branch, + BranchNotZero, +}; + +class instruction { +public: + instruction() = default; + virtual ~instruction() = default; + + instruction(instruction&&) = default; + instruction& operator=(instruction&&) = default; + instruction(const instruction&) = delete; + instruction& operator=(const instruction&) = delete; +public: + virtual instruction_t type() const = 0; +}; + +class assign_instruction final : public instruction { +public: + assign_instruction(operand&& src, operand&& dst) + : m_source(std::move(src)), m_destination(std::move(dst)) {} + + ~assign_instruction() override = default; + + assign_instruction(assign_instruction&&) = default; + assign_instruction& operator=(assign_instruction&&) = default; + assign_instruction(const assign_instruction&) = delete; + assign_instruction& operator=(const assign_instruction&) = delete; +public: + instruction_t type() const override { return instruction_t::Assign; } + + const operand& source() const { return m_source; } + const operand& destination() const { return m_destination; } +private: + operand m_source; + operand m_destination; +}; + +enum class binary_op_instruction_t { + Add, + Sub, + Mul, + Div, + Mod, + + Eq, + NotEq, + LessThan, + GreaterThan, + LessEq, + GreaterEq, +}; + +class binary_op_instruction final : public instruction { +public: + binary_op_instruction(binary_op_instruction_t type, operand&& lhs, operand&& rhs, operand&& dst) + : m_type(type), m_lhs(std::move(lhs)), m_rhs(std::move(rhs)), m_dst(std::move(dst)) {} + + ~binary_op_instruction() override = default; + + binary_op_instruction(binary_op_instruction&&) = default; + binary_op_instruction& operator=(binary_op_instruction&&) = default; + binary_op_instruction(const binary_op_instruction&) = delete; + binary_op_instruction& operator=(const binary_op_instruction&) = delete; +public: + instruction_t type() const override { return instruction_t::BinaryOp; } + + binary_op_instruction_t op_type() const { return m_type; } + const operand& lhs() const { return m_lhs; } + const operand& rhs() const { return m_rhs; } + const operand& dst() const { return m_dst; } +private: + binary_op_instruction_t m_type; + operand m_lhs; + operand m_rhs; + operand m_dst; +}; + +using block_index = std::uint64_t; + +class branch_instruction final : public instruction { +public: + branch_instruction(block_index block) + : m_block(block) {} + + ~branch_instruction() override = default; + + branch_instruction(branch_instruction&&) = default; + branch_instruction& operator=(branch_instruction&&) = default; + branch_instruction(const branch_instruction&) = delete; + branch_instruction& operator=(const branch_instruction&) = delete; +public: + instruction_t type() const override { return instruction_t::Branch; } + + block_index block() const { return m_block; } +private: + block_index m_block; +}; + +class branch_nz_instruction final : public instruction { +public: + branch_nz_instruction(operand&& condition, block_index block) + : m_condition(std::move(condition)), m_block(block) {} + + ~branch_nz_instruction() override = default; + + branch_nz_instruction(branch_nz_instruction&&) = default; + branch_nz_instruction& operator=(branch_nz_instruction&&) = default; + branch_nz_instruction(const branch_nz_instruction&) = delete; + branch_nz_instruction& operator=(const branch_nz_instruction&) = delete; +public: + instruction_t type() const override { return instruction_t::BranchNotZero; } + + const operand& condition() const { return m_condition; } + block_index block() const { return m_block; } +private: + operand m_condition; + block_index m_block; +}; + +} // namespace ir +} // namespace furlang + +#endif // FURLANG_IR_INSTRUCTION_HPP \ No newline at end of file