#ifndef TYPES_H #define TYPES_H #include "builder.h" #include #include namespace types { enum class TypeKind { Fundamental, Function, Pointer, Array, Struct, }; enum FundamentalTypeKind { Int, Bool, Char, Void, /// @brief Mainly used for binop resolution Any, }; class Type { public: TypeKind m_kind; Type(TypeKind kind) : m_kind{ kind } {} virtual ~Type() = default; virtual std::string formatted() = 0; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) = 0; virtual std::optional> return_type(); virtual bool is_signed(); virtual uint32_t size() = 0; }; class FundamentalType : public Type { public: FundamentalTypeKind m_ty; FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {} virtual ~FundamentalType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual bool is_signed() override; virtual uint32_t size() override; }; class FunctionType : public Type { public: std::shared_ptr m_ret_ty; std::vector> m_param_tys; bool m_vararg; FunctionType(std::shared_ptr ret_ty, std::vector> param_tys, bool vararg) : Type(TypeKind::Function) , m_ret_ty{ std::move(ret_ty) } , m_param_tys{ std::move(param_tys) } , m_vararg{ vararg } { } virtual ~FunctionType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual std::optional> return_type() override; virtual uint32_t size() override; }; class PointerType : public Type { public: std::shared_ptr m_inner; PointerType(std::shared_ptr inner) : Type(TypeKind::Pointer), m_inner{ std::move(inner) } { } virtual ~PointerType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; class ArrayType : public Type { public: std::shared_ptr m_inner; uint32_t m_size; ArrayType(std::shared_ptr inner, uint32_t size) : Type(TypeKind::Array), m_inner{ std::move(inner) }, m_size{ size } { } virtual ~ArrayType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; typedef std::pair> StructField; class StructType : public Type { public: std::optional m_name; std::optional> m_fields; bool m_is_ref; StructType(std::optional name, std::optional> fields, bool is_ref) : Type(TypeKind::Struct), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref } { } virtual ~StructType() override = default; virtual std::string formatted() override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; virtual uint32_t size() override; }; // class StructRef : public Type { // public: // std::string m_name; // std::shared_ptr m_referred; // StructRef(std::string name, std::shared_ptr referred) // : Type(TypeKind::StructRef), m_name{ name }, m_referred{ referred } { // } // virtual ~StructRef() override = default; // virtual std::string formatted() override; // virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; // virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) override; // virtual uint32_t size() override; // }; bool types_equal(std::shared_ptr type1, std::shared_ptr type2); } #endif