feat: abstract value for IR

This commit is contained in:
2025-12-24 18:59:44 +01:00
parent e5d912b28e
commit e8a496d070
3 changed files with 65 additions and 42 deletions

View File

@@ -2,15 +2,16 @@
#include "codegen/codegen.hpp" #include "codegen/codegen.hpp"
#include "ir/slot.hpp" #include "ir/slot.hpp"
#include "ir/value.hpp"
class StackFasmX86_64Generator : public CodeGenerator class StackFasmX86_64Generator : public CodeGenerator
{ {
public: public:
~StackFasmX86_64Generator() override = default; ~StackFasmX86_64Generator() override = default;
private: private:
StringView GetTempAddr(IR::Tmp reg) StringView GetTempAddr(IR::Value reg)
{ {
return std::move((StringBuilder() << 't' << reg).view()); return std::move((StringBuilder() << reg.Format()).view());
} }
StringView GetSlotAddr(const IR::IRSlot& slot) StringView GetSlotAddr(const IR::IRSlot& slot)

View File

@@ -1,9 +1,10 @@
#pragma once #pragma once
#include <unordered_map> #include <unordered_map>
#include "prelude/string.hpp" #include "prelude/string.hpp"
#include "ir/slot.hpp"
#include "parser/ast.hpp" #include "parser/ast.hpp"
#include "ir/slot.hpp"
#include "ir/allocator.hpp" #include "ir/allocator.hpp"
#include "ir/value.hpp"
namespace IR namespace IR
{ {
@@ -23,11 +24,6 @@ enum class OpType
#define OP_TYPE(x) \ #define OP_TYPE(x) \
OpType GetType() const override { return OpType::x; } OpType GetType() const override { return OpType::x; }
using Tmp = int;
using TmpView = View<Tmp>;
using TmpBuilder = Builder<Tmp>;
class Op class Op
{ {
public: public:
@@ -43,13 +39,13 @@ using OpBuilder = Builder<Op*>;
class Valued class Valued
{ {
public: public:
Valued(Tmp dest) Valued(Value dest)
: m_dest(dest) {} : m_dest(dest) {}
~Valued() = default; ~Valued() = default;
public: public:
Tmp result() const { return m_dest; } Value result() const { return m_dest; }
private: private:
Tmp m_dest; Value m_dest;
}; };
class ExternOp : public Op class ExternOp : public Op
@@ -100,14 +96,14 @@ public:
private: private:
StringView m_name; StringView m_name;
OpView m_ops; OpView m_ops;
View<Tmp> m_slots; ValueView m_slots;
View<StringView> m_params; View<StringView> m_params;
}; };
class LoadConstOp : public Op, public Valued class LoadConstOp : public Op, public Valued
{ {
public: public:
LoadConstOp(Tmp dest, long value) LoadConstOp(Value dest, long value)
: Valued(dest), m_value(value) {} : Valued(dest), m_value(value) {}
~LoadConstOp() {} ~LoadConstOp() {}
@@ -117,7 +113,7 @@ public:
{ {
StringBuilder sb; StringBuilder sb;
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << 't' << result() << " = LOAD_CONST " << m_value; sb << result().Format() << " = LOAD_CONST " << m_value;
return sb.view(); return sb.view();
} }
public: public:
@@ -129,7 +125,7 @@ private:
class LoadOp : public Op, public Valued class LoadOp : public Op, public Valued
{ {
public: public:
LoadOp(Tmp dest, StringView addr) LoadOp(Value dest, StringView addr)
: Valued(dest), m_addr(addr) {} : Valued(dest), m_addr(addr) {}
~LoadOp() {} ~LoadOp() {}
@@ -139,7 +135,7 @@ public:
{ {
StringBuilder sb; StringBuilder sb;
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << 't' << result() << " = LOAD \"" << m_addr.c_str() << "\""; sb << result().Format() << " = LOAD \"" << m_addr.c_str() << "\"";
return sb.view(); return sb.view();
} }
public: public:
@@ -151,7 +147,7 @@ private:
class StoreOp : public Op class StoreOp : public Op
{ {
public: public:
StoreOp(StringView addr, Tmp src) StoreOp(StringView addr, Value src)
: m_addr(addr), m_src(src) {} : m_addr(addr), m_src(src) {}
~StoreOp() {} ~StoreOp() {}
@@ -161,21 +157,21 @@ public:
{ {
StringBuilder sb; StringBuilder sb;
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << "STORE \"" << m_addr.c_str() << "\", t" << m_src; sb << "STORE \"" << m_addr.c_str() << "\", " << m_src.Format();
return sb.view(); return sb.view();
} }
public: public:
const StringView& addr() const { return m_addr; } const StringView& addr() const { return m_addr; }
Tmp src() const { return m_src; } Value src() const { return m_src; }
private: private:
StringView m_addr; StringView m_addr;
Tmp m_src; Value m_src;
}; };
class AddOp : public Op, public Valued class AddOp : public Op, public Valued
{ {
public: public:
AddOp(Tmp dest, Tmp lhs, Tmp rhs) AddOp(Value dest, Value lhs, Value rhs)
: Valued(dest), m_lhs(lhs), m_rhs(rhs) {} : Valued(dest), m_lhs(lhs), m_rhs(rhs) {}
~AddOp() {} ~AddOp() {}
@@ -185,21 +181,21 @@ public:
{ {
StringBuilder sb; StringBuilder sb;
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << 't' << result() << " = ADD " << m_lhs << ", " << m_rhs; sb << result().Format() << " = ADD " << m_lhs.Format() << ", " << m_rhs.Format();
return sb.view(); return sb.view();
} }
public: public:
Tmp lhs() const { return m_lhs; } Value lhs() const { return m_lhs; }
Tmp rhs() const { return m_rhs; } Value rhs() const { return m_rhs; }
private: private:
Tmp m_lhs; Value m_lhs;
Tmp m_rhs; Value m_rhs;
}; };
class CallOp : public Op, public Valued class CallOp : public Op, public Valued
{ {
public: public:
CallOp(Tmp dest, StringView callee, TmpView args) CallOp(Value dest, StringView callee, ValueView args)
: Valued(dest), m_callee(callee), m_args(args) {} : Valued(dest), m_callee(callee), m_args(args) {}
~CallOp() {} ~CallOp() {}
@@ -211,18 +207,18 @@ public:
for (size_t i = 0; i < m_args.size; ++i) for (size_t i = 0; i < m_args.size; ++i)
{ {
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << "PARAM t" << m_args.data[i] << '\n'; sb << "PARAM " << m_args.data[i].Format() << '\n';
} }
sb.AppendIndent(indent); sb.AppendIndent(indent);
sb << 't' << result() << " = CALL " << m_callee.c_str(); sb << result().Format() << " = CALL " << m_callee.c_str();
return sb.view(); return sb.view();
} }
public: public:
const StringView& callee() const { return m_callee; } const StringView& callee() const { return m_callee; }
const TmpView& args() const { return m_args; } const ValueView& args() const { return m_args; }
private: private:
StringView m_callee; StringView m_callee;
TmpView m_args; ValueView m_args;
}; };
class IRBuilder class IRBuilder
@@ -232,14 +228,14 @@ public:
: m_root(root) {} : m_root(root) {}
public: public:
// TODO: support other literals // TODO: support other literals
Tmp ParseIntLiteral(const IntLiteralNode* literal) Value ParseIntLiteral(const IntLiteralNode* literal)
{ {
auto dst = AllocateRegister(); auto dst = AllocateRegister();
m_ops.Push(new LoadConstOp(dst, literal->integer())); m_ops.Push(new LoadConstOp(dst, literal->integer()));
return dst; return dst;
} }
Tmp ParseVariable(const VariableNode* var) Value ParseVariable(const VariableNode* var)
{ {
// auto dst = AllocateRegister(); // auto dst = AllocateRegister();
// m_ops.Push(new LoadOp(dst, var->name())); // m_ops.Push(new LoadOp(dst, var->name()));
@@ -251,10 +247,10 @@ public:
return m_locals[var->name()]; return m_locals[var->name()];
} }
Tmp ParseFnCall(const FnCallNode* fn) Value ParseFnCall(const FnCallNode* fn)
{ {
// TODO: support multiple args // TODO: support multiple args
auto argRegs = TmpBuilder(); auto argRegs = ValueBuilder();
if (fn->arg() != nullptr) if (fn->arg() != nullptr)
{ {
auto arg = ParseExpression(fn->arg()); auto arg = ParseExpression(fn->arg());
@@ -265,7 +261,7 @@ public:
return dst; return dst;
} }
Tmp ParseFactor(const Node* factor) Value ParseFactor(const Node* factor)
{ {
switch(factor->GetType()) switch(factor->GetType())
{ {
@@ -276,10 +272,10 @@ public:
} }
assert(0 && "unreachable"); assert(0 && "unreachable");
return Tmp(); return Value();
} }
Tmp ParseExpression(const Node* expression) Value ParseExpression(const Node* expression)
{ {
if (expression->GetType() == NodeType::Expression) if (expression->GetType() == NodeType::Expression)
{ {
@@ -343,17 +339,17 @@ public:
// TODO: think about safety (copying m_ops.data before giving) // TODO: think about safety (copying m_ops.data before giving)
OpView ops() const { return OpView(m_ops.data, m_ops.size); } OpView ops() const { return OpView(m_ops.data, m_ops.size); }
private: private:
Tmp AllocateRegister() Value AllocateRegister()
{ {
return m_tmp_counter++; return Value(m_value_counter++);
} }
private: private:
OpBuilder m_ops; OpBuilder m_ops;
const Node* m_root = nullptr; const Node* m_root = nullptr;
unsigned int m_tmp_counter = 0; unsigned int m_value_counter = 0;
std::unordered_map<StringView, Tmp> m_locals; std::unordered_map<StringView, Value> m_locals;
}; };
} // namespace IR } // namespace IR

26
include/ir/value.hpp Normal file
View File

@@ -0,0 +1,26 @@
#pragma once
#include "prelude/string.hpp"
namespace IR
{
class Value
{
public:
Value(unsigned int id) : m_id(id) {}
Value() : m_id(0) {}
public:
StringView Format() const
{
auto sb = StringBuilder();
sb.AppendFormat("%%%d", m_id);
return sb.view();
}
private:
unsigned int m_id;
};
using ValueView = View<Value>;
using ValueBuilder = Builder<Value>;
} // namespace IR