#ifndef TYPES_H #define TYPES_H #include "builder.h" #include #include namespace types { enum class BinOp { Assignment, Add, Sub, LessThan, GreaterThan, }; int operator_precedence(BinOp& op); std::string format_operator(BinOp& op); enum class TypeKind { Fundamental, Function, Pointer, }; enum FundamentalTypeKind { Int, Bool, Char, Void, }; 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) = 0; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr) = 0; virtual std::optional> return_type(); virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); }; class FundamentalType : public Type { private: FundamentalTypeKind m_ty; public: 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) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr) override; virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override; virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override; virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override; virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) 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) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr) override; virtual std::optional> return_type() override; }; class PointerType : public Type { private: std::shared_ptr m_inner; public: 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) override; virtual std::pair> load(codegen::Builder& builder, llvm::Value* ptr) override; }; } #endif