155 lines
4.7 KiB
C++
155 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include "common.h"
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
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";
|
|
}
|
|
}
|
|
template <typename TT>
|
|
static bool isType(std::shared_ptr<Type> ptr) {
|
|
if (ptr) {
|
|
return dynamic_cast<TT *>(ptr.get()) != nullptr;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
template <typename TT>
|
|
static std::shared_ptr<TT> asType(std::shared_ptr<Type> ptr) {
|
|
return std::dynamic_pointer_cast<TT>(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;
|
|
}
|
|
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");
|
|
}
|
|
};
|
|
|
|
typedef std::shared_ptr<Type> 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<IntegerType>(type)->isI32();
|
|
}
|
|
static bool isIntegerTypeI1(TypePtr_t &type) {
|
|
return isIntegerType(type) && std::dynamic_pointer_cast<IntegerType>(type)->isI1();
|
|
}
|
|
inline static TypePtr_t TYPE_I32 = std::make_shared<IntegerType>();
|
|
inline static TypePtr_t TYPE_I1 = std::make_shared<IntegerType>(IntegerType::IntTypes::I1);
|
|
inline static TypePtr_t TYPE_LABEL = std::make_shared<LabelType>();
|
|
inline static TypePtr_t TYPE_VOID = std::make_shared<VoidType>();
|
|
};
|
|
|
|
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<ArrayType> build_from_list(const std::vector<int> &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<ArrayType>(array_type, *itr);
|
|
}
|
|
return std::dynamic_pointer_cast<ArrayType>(array_type);
|
|
}
|
|
virtual std::string to_string() override {
|
|
return "Array[" + std::to_string(element_count) + " x " + element_type->to_string() + "]";
|
|
}
|
|
virtual std::string to_IR_string() override {
|
|
return "[" + std::to_string(element_count) + " x " + element_type->to_IR_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<PointerType>(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<TypePtr_t> params_type;
|
|
FunctionType(TypePtr_t return_type) : Type(TypeTag::FunctionType), return_type(return_type) {}
|
|
FunctionType(TypePtr_t return_type, const std::vector<TypePtr_t> ¶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 antlrSysY
|