elna/include/elna/source/optimizer.hpp

107 lines
3.3 KiB
C++

#pragma once
#include <unordered_map>
#include "elna/source/parser.hpp"
#include "elna/source/symbol_table.hpp"
namespace elna::source
{
enum class quadruple_operator
{
start,
stop,
add,
sub,
mul,
div,
eq,
neq,
lt,
ge,
gt,
le,
load,
ref,
beqz,
j,
label,
assign,
param,
call
};
/**
* Single instruction representation.
*/
struct quadruple
{
quadruple(const quadruple_operator operation, std::shared_ptr<operand> operand1 = nullptr,
std::shared_ptr<operand> operand2 = nullptr, std::shared_ptr<operand> operand3 = nullptr);
quadruple_operator operation() const noexcept;
std::shared_ptr<operand> operand1();
std::shared_ptr<operand> operand2();
std::shared_ptr<operand> operand3();
private:
quadruple_operator m_operation;
std::shared_ptr<operand> m_operand1;
std::shared_ptr<operand> m_operand2;
std::shared_ptr<operand> m_operand3;
};
class intermediate_code final
{
std::vector<quadruple> instructions;
std::uint32_t m_variable_counter;
std::uint32_t m_label_counter;
public:
intermediate_code();
void emplace_back(const quadruple_operator operation, std::shared_ptr<operand> operand1 = nullptr,
std::shared_ptr<operand> operand2 = nullptr, std::shared_ptr<operand> operand3 = nullptr);
void clear();
std::vector<quadruple>::iterator begin();
std::vector<quadruple>::iterator end();
std::int32_t variable_counter() const noexcept;
std::int32_t increment_variable() noexcept;
std::int32_t label_counter() const noexcept;
std::int32_t increment_label() noexcept;
};
class intermediate_code_generator final : public empty_visitor
{
std::unordered_map<std::string, intermediate_code> code;
intermediate_code current;
std::shared_ptr<symbol_table> table;
quadruple_operator convert(const binary_operator operation) const;
quadruple_operator convert(const unary_operator operation) const;
public:
intermediate_code_generator(std::shared_ptr<symbol_table> table);
std::unordered_map<std::string, intermediate_code>::iterator begin();
std::unordered_map<std::string, intermediate_code>::iterator end();
void visit(declaration *declaration) override;
void visit(constant_definition *definition) override;
void visit(procedure_definition *definition) override;
void visit(call_statement *statement) override;
void visit(assign_statement *statement) override;
void visit(if_statement *statement) override;
void visit(while_statement *statement) override;
void visit(block *block) override;
void visit(program *program) override;
void visit(type_expression *variable) override;
void visit(variable_expression *variable) override;
void visit(binary_expression *expression) override;
void visit(unary_expression *expression) override;
void visit(integer_literal *number) override;
void visit(boolean_literal *number) override;
};
}