#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; using ValueBuilder = Builder; } // namespace IR