feat: implement proper IR with value handles with dynamic and transferable types
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user