107 lines
3.3 KiB
C++
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;
|
|
};
|
|
}
|