diff --git a/furc/include/furc/front/ir_generator.hpp b/furc/include/furc/front/ir_generator.hpp index 472cb08..4d741aa 100644 --- a/furc/include/furc/front/ir_generator.hpp +++ b/furc/include/furc/front/ir_generator.hpp @@ -5,8 +5,6 @@ #include "furc/ast/visitor.hpp" #include "furlang/ir/module.hpp" -#include - namespace furc { namespace front { @@ -38,8 +36,6 @@ private: std::unique_ptr m_currentFunction; std::shared_ptr m_currentBlock; std::uint32_t m_registerCounter = 0; - - std::unordered_map m_variableMap; }; } // namespace front diff --git a/furc/src/front/ir_generator.cpp b/furc/src/front/ir_generator.cpp index 788028b..5cd5d7e 100644 --- a/furc/src/front/ir_generator.cpp +++ b/furc/src/front/ir_generator.cpp @@ -71,7 +71,8 @@ void ir_generator::visit_integer_literal_node(const ast::integer_literal_node& n } void ir_generator::visit_var_read_expression_node(const ast::var_read_expression_node& node) { - throw std::runtime_error("unimplemented"); + m_currentBlock->emplace(ir::operand::new_variable(std::string(*node.get_name())), + ir::operand::new_reg(m_registerCounter++)); } void ir_generator::visit_unaryop_expression_node(const ast::unaryop_expression_node& node) { @@ -109,7 +110,24 @@ void ir_generator::visit_binop_expression_node(const ast::binop_expression_node& } void ir_generator::visit_var_assign_expression_node(const ast::var_assign_expression_node& node) { - throw std::runtime_error("unimplemented"); + node.rhs()->accept(*this); + std::uint32_t rhs = m_registerCounter - 1; + assert(node.lhs()->expression_type() == ast::expression_node_t::VarRead); + ast::var_read_expression_node_h lhs = node.lhs(); + + std::uint32_t reg = m_registerCounter++; + + auto compound = node.compound(); + if (compound != ast::binop_expression_node_t::None) { + m_currentBlock->emplace(binary_op_instruction_t(compound), + ir::operand::new_variable(std::string(*lhs->get_name())), + ir::operand::new_reg(rhs), + ir::operand::new_reg(reg)); + } else { + m_currentBlock->emplace(ir::operand::new_reg(rhs), ir::operand::new_reg(reg)); + } + m_currentBlock->emplace(ir::operand::new_reg(reg), + ir::operand::new_variable(std::string(*lhs->get_name()))); } furlang::ir::block_index ir_generator::push_block() { diff --git a/furlang/include/furlang/ir/operand.hpp b/furlang/include/furlang/ir/operand.hpp index 7c2397f..4baf57b 100644 --- a/furlang/include/furlang/ir/operand.hpp +++ b/furlang/include/furlang/ir/operand.hpp @@ -11,11 +11,13 @@ namespace ir { enum class operand_t { None, Register, + Variable, Integer, String, }; using register_operand = std::uint32_t; +using variable_operand = std::string; using integer_operand = std::uint64_t; using string_operand = std::string; @@ -34,11 +36,14 @@ public: case operand_t::Register: { m_value.reg = other.m_value.reg; } break; + case operand_t::Variable: { + new (&m_value.variable) variable_operand(std::move(other.m_value.variable)); + } 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)); + new (&m_value.string) string_operand(std::move(other.m_value.string)); } break; } other.m_value.destroy(other.m_type); @@ -52,11 +57,14 @@ public: case operand_t::Register: { m_value.reg = other.m_value.reg; } break; + case operand_t::Variable: { + new (&m_value.variable) variable_operand(std::move(other.m_value.variable)); + } 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)); + new (&m_value.string) string_operand(std::move(other.m_value.string)); } break; } other.m_value.destroy(other.m_type); @@ -68,29 +76,31 @@ public: public: static operand new_reg(register_operand value) { operand operand; - operand.m_type = operand_t::Register; - new (&operand.m_value) union value(value); + operand.m_type = operand_t::Register; + operand.m_value.reg = value; + return operand; + } + + template + static operand new_variable(T&& value) { + operand operand; + operand.m_type = operand_t::Variable; + new (&operand.m_value.variable) variable_operand(std::forward(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); + operand.m_type = operand_t::Integer; + operand.m_value.integer = value; return operand; } - static operand new_string(const string_operand& value) { + template + static operand new_string(T&& 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)); + new (&operand.m_value.string) string_operand(std::forward(value)); return operand; } public: @@ -103,6 +113,7 @@ public: switch (operand.m_type) { case operand_t::None: return os << "none"; case operand_t::Register: return os << '%' << operand.m_value.reg; + case operand_t::Variable: return os << operand.m_value.variable; case operand_t::Integer: return os << operand.m_value.integer; case operand_t::String: return os << '"' << operand.m_value.string << '"'; } @@ -115,6 +126,7 @@ private: union value { std::nullptr_t null = nullptr; register_operand reg; + variable_operand variable; integer_operand integer; string_operand string; @@ -131,18 +143,6 @@ private: 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;