#pragma once #include "common.h" #include #include #include #include namespace CompSysY { DEF_PTR_T(Type); DEF_PTR_T(IntegerType); DEF_PTR_T(VoidType); DEF_PTR_T(LabelType); DEF_PTR_T(ArrayType); DEF_PTR_T(PointerType); DEF_PTR_T(FunctionType); class Type { public: enum class TypeTag { IntegerType, FunctionType, ArrayType, PointerType, VectorType, VoidType, LabelType, }; TypeTag type_tag; Type(TypeTag type_tag) : type_tag(type_tag) {} virtual ~Type() = default; virtual std::string to_string() { switch (type_tag) { case TypeTag::IntegerType: return "IntegerType"; case TypeTag::FunctionType: return "FunctionType"; case TypeTag::ArrayType: return "ArrayType"; case TypeTag::PointerType: return "PointerType"; case TypeTag::VectorType: return "VectorType"; case TypeTag::VoidType: return "VoidType"; case TypeTag::LabelType: return "LabelType"; } } template static bool isType(std::shared_ptr ptr) { if (ptr) { return dynamic_cast(ptr.get()) != nullptr; } else { return false; } } template static std::shared_ptr asType(std::shared_ptr ptr) { return std::dynamic_pointer_cast(ptr); } virtual std::string to_IR_string() = 0; }; class IntegerType : public Type { public: enum class IntTypes { I32, I1 }; IntTypes int_type = IntTypes::I32; IntegerType(IntTypes int_type = IntTypes::I32) : Type(TypeTag::IntegerType), int_type(int_type) {} bool isI32() { return int_type == IntTypes::I32; } bool isI1() { return int_type == IntTypes::I1; } static bool isIntegerType(TypePtr_t type) { return (type->type_tag == Type::TypeTag::IntegerType); } static bool isIntegerTypeI32(TypePtr_t type) { return isIntegerType(type) && std::dynamic_pointer_cast(type)->isI32(); } static bool isIntegerTypeI1(TypePtr_t &type) { return isIntegerType(type) && std::dynamic_pointer_cast(type)->isI1(); } virtual std::string to_IR_string() override { if (isI1()) return "i1"; else return "i32"; } }; class VoidType : public Type { public: VoidType() : Type(TypeTag::VoidType) {} virtual std::string to_IR_string() override { return "void"; } }; class LabelType : public Type { public: LabelType() : Type(TypeTag::LabelType) {} virtual std::string to_IR_string() override { panic("Cannot generate LabelType"); } }; class TypeHelper { public: inline static TypePtr_t TYPE_I32 = std::make_shared(); inline static TypePtr_t TYPE_I1 = std::make_shared(IntegerType::IntTypes::I1); inline static TypePtr_t TYPE_LABEL = std::make_shared(); inline static TypePtr_t TYPE_VOID = std::make_shared(); }; class ArrayType : public Type { public: TypePtr_t elem_type = TypeHelper::TYPE_I32; int elem_count = 0; // current dim size int type_size = 0; // = dim_size * size(elem_type) ArrayType() : Type(TypeTag::ArrayType) {} ArrayType(TypePtr_t element_type, int element_count) : Type(TypeTag::ArrayType), elem_type(element_type), elem_count(element_count) { } static std::shared_ptr build_from_list(const std::vector &dim_list) { TypePtr_t array_type = TypeHelper::TYPE_I32; sysy_assert(dim_list.size() != 0); for (auto itr = dim_list.rbegin(); itr != dim_list.rend(); ++itr) { array_type = std::make_shared(array_type, *itr); } return std::dynamic_pointer_cast(array_type); } virtual std::string to_string() override { return "Array[" + std::to_string(elem_count) + " x " + elem_type->to_string() + "]"; } virtual std::string to_IR_string() override { return "[" + std::to_string(elem_count) + " x " + elem_type->to_IR_string() + "]"; } }; class PointerType : public Type { public: TypePtr_t pointed_type = TypeHelper::TYPE_I32; PointerType(TypePtr_t pointed_type) : Type(TypeTag::PointerType), pointed_type(pointed_type) {} static auto make_shared(TypePtr_t pointed_type) { return std::make_shared(pointed_type); } virtual std::string to_string() override { return "Pointer->" + pointed_type->to_string(); } virtual std::string to_IR_string() override { return pointed_type->to_IR_string() + "*"; } }; class FunctionType : public Type { public: TypePtr_t return_type = TypeHelper::TYPE_I32; std::vector params_type; FunctionType(TypePtr_t return_type) : Type(TypeTag::FunctionType), return_type(return_type) {} FunctionType(TypePtr_t return_type, const std::vector ¶ms_type) : Type(TypeTag::FunctionType), return_type(return_type), params_type(params_type) { } virtual std::string to_IR_string() override { panic("Cannot generate FunctionType"); } }; } // namespace CompSysY