165 lines
3.7 KiB
C++
165 lines
3.7 KiB
C++
#pragma once
|
|
#include "prelude/string.hpp"
|
|
|
|
namespace IR
|
|
{
|
|
|
|
class ValueHandle
|
|
{
|
|
public:
|
|
static constexpr uint32_t kNoId = 0;
|
|
|
|
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
|