#pragma once #include "common.h" #include #include #include namespace antlrSysY { 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"; } } }; 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; } }; class VoidType : public Type { public: VoidType() : Type(TypeTag::VoidType) {} }; class LabelType : public Type { public: LabelType() : Type(TypeTag::LabelType) {} }; typedef std::shared_ptr TypePtr_t; class TypeHelper { public: 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(); } 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 element_type = TypeHelper::TYPE_I32; int element_count = 0; ArrayType() : Type(TypeTag::ArrayType) {} ArrayType(TypePtr_t element_type, int element_count) : Type(TypeTag::ArrayType), element_count(element_count), element_type(element_type) {} 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(element_count) + " x " + element_type->to_string() + "]"; } }; class PointerType : public Type { public: TypePtr_t pointed_type = TypeHelper::TYPE_I32; PointerType() : Type(TypeTag::PointerType) {} 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(); } }; 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) {} }; } // namespace antlrSysY