feat: implement proper IR with value handles with dynamic and transferable types

This commit is contained in:
2026-01-01 15:50:26 +01:00
parent 3b8dfc4dae
commit 6f4ab269e2
8 changed files with 621 additions and 375 deletions

View File

@@ -4,23 +4,161 @@
namespace IR
{
class Value
{
public:
Value(unsigned int id) : m_id(id) {}
Value() : m_id(0) {}
public:
StringView Format() const
class ValueHandle
{
auto sb = StringBuilder();
sb.AppendFormat("%%%d", m_id);
return sb.view();
}
private:
unsigned int m_id;
};
public:
static constexpr uint32_t kNoId = 0;
using ValueView = View<Value>;
using ValueBuilder = Builder<Value>;
struct Type
{
enum class Kind
{
Void,
Int,
Ptr
};
Kind kind;
uint32_t bits;
public:
Type(Kind kind_) : kind(kind_), bits(32) {}
Type(Kind kind_, uint32_t bits_) : kind(kind_), bits(bits_) {}
Type(const Type *typ) : kind(typ->kind), bits(32) {}
public:
StringView Format() const
{
switch (kind)
{
case Kind::Int:
{
StringBuilder sb;
sb.AppendFormat("i%d", bits);
return sb.view();
}
case Kind::Void:
{
return StringView("void");
}
case Kind::Ptr:
{
return StringView("ptr");
}
}
assert(false && "unreachable");
return StringView();
}
};
public:
ValueHandle(uint32_t id = kNoId) : m_id(id) {}
bool HasId() const { return m_id != kNoId; }
uint32_t GetId() const { return m_id; }
public:
virtual StringView Format() const
{
auto sb = StringBuilder();
if (HasId())
sb.AppendFormat("%%%d", m_id);
else
sb.Extend("<?>");
return sb.view();
}
public:
virtual const Type *GetType() const = 0;
private:
uint32_t m_id;
};
class ConstantInt : public ValueHandle
{
public:
ConstantInt(unsigned int id, long value)
: ValueHandle(id), m_value(value)
{
m_type = new Type{Type::Kind::Int};
}
const Type *GetType() const override { return m_type; }
public:
virtual StringView Format() const override
{
auto sb = StringBuilder();
sb.AppendFormat("%s %d", m_type->Format().c_str(), m_value);
return sb.view();
}
public:
long GetValue() const { return m_value; }
private:
long m_value;
Type *m_type;
};
class Pointer : public ValueHandle
{
public:
Pointer(unsigned int id)
: ValueHandle(id)
{
m_type = new Type{Type::Kind::Ptr};
}
const Type *GetType() const override { return m_type; }
public:
virtual StringView Format() const override
{
auto sb = StringBuilder();
sb.AppendFormat("%s %%%d", m_type->Format().c_str(), GetId());
return sb.view();
}
private:
Type *m_type;
};
// TODO: Remove void value and use void type only
class Void : public ValueHandle
{
public:
Void(unsigned int id)
: ValueHandle(id)
{
m_type = new Type{Type::Kind::Void};
}
const Type *GetType() const override { return m_type; }
public:
virtual StringView Format() const override
{
return m_type->Format();
}
private:
Type *m_type;
};
class Instruction : public ValueHandle
{
public:
Instruction(unsigned int id, const Type *typ)
: ValueHandle(id), m_type(new Type(typ)) {}
const Type *GetType() const override { return m_type; }
private:
Type *m_type;
};
using ValueView = View<ValueHandle *>;
using ValueBuilder = Builder<ValueHandle *>;
} // namespace IR