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

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