#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 FundamentalTypeKind { Int, Bool }; class Type { public: 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() = 0; virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; }; class FundamentalType : public Type { private: FundamentalTypeKind m_ty; public: FundamentalType(FundamentalTypeKind kind) : 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 std::optional> return_type() 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 { private: std::shared_ptr m_ret_ty; std::vector> m_param_tys; public: FunctionType(std::shared_ptr ret_ty, std::vector> param_tys) : m_ret_ty{ std::move(ret_ty) }, m_param_tys{ std::move(param_tys) } { } 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; 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 PointerType : public Type { private: std::shared_ptr m_inner; public: PointerType(std::shared_ptr inner) : 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; virtual std::optional> return_type() 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; }; } #endif