101 lines
2.7 KiB
C++
101 lines
2.7 KiB
C++
/*!
|
|
@file src/Sema/Type.cpp
|
|
@brief 类型系统实现
|
|
*/
|
|
|
|
#include <Sema/Type.hpp>
|
|
|
|
namespace Fig
|
|
{
|
|
bool Type::is(TypeTag t) const
|
|
{
|
|
return base && base->tag == t;
|
|
}
|
|
|
|
String Type::toString() const
|
|
{
|
|
if (!base)
|
|
return "Unknown";
|
|
if (base->tag == TypeTag::Function)
|
|
{
|
|
auto *ft = static_cast<FuncType *>(base);
|
|
String sig = "func(";
|
|
for (size_t i = 0; i < ft->paramTypes.size(); ++i)
|
|
{
|
|
sig += ft->paramTypes[i].toString();
|
|
if (i < ft->paramTypes.size() - 1)
|
|
sig += ", ";
|
|
}
|
|
sig += ") -> " + ft->retType.toString();
|
|
return sig;
|
|
}
|
|
|
|
String res = base->name;
|
|
if (isNullable && base->tag != TypeTag::Null)
|
|
res += "?";
|
|
return res;
|
|
}
|
|
|
|
bool Type::isAssignableTo(const Type &target) const
|
|
{
|
|
if (target.is(TypeTag::Any) || this->is(TypeTag::Any))
|
|
{
|
|
return true; // Any 逃逸
|
|
}
|
|
if (this->is(TypeTag::Null) && target.isNullable)
|
|
{
|
|
return true; // Null 安全赋值
|
|
}
|
|
|
|
return *this->base == *target.base && (!this->isNullable || target.isNullable);
|
|
}
|
|
|
|
TypeContext::TypeContext()
|
|
{
|
|
intType = new BaseType(TypeTag::Int, "Int");
|
|
doubleType = new BaseType(TypeTag::Double, "Double");
|
|
stringType = new BaseType(TypeTag::String, "String");
|
|
boolType = new BaseType(TypeTag::Bool, "Bool");
|
|
anyType = new BaseType(TypeTag::Any, "Any");
|
|
nullType = new BaseType(TypeTag::Null, "Null");
|
|
|
|
allTypes.push_back(intType);
|
|
allTypes.push_back(doubleType);
|
|
allTypes.push_back(stringType);
|
|
allTypes.push_back(boolType);
|
|
allTypes.push_back(anyType);
|
|
allTypes.push_back(nullType);
|
|
}
|
|
|
|
TypeContext::~TypeContext()
|
|
{
|
|
for (auto t : allTypes)
|
|
{
|
|
delete t;
|
|
}
|
|
}
|
|
|
|
Type TypeContext::GetBasic(TypeTag tag, bool nullable)
|
|
{
|
|
BaseType *b = nullptr;
|
|
switch (tag)
|
|
{
|
|
case TypeTag::Int: b = intType; break;
|
|
case TypeTag::Double: b = doubleType; break;
|
|
case TypeTag::String: b = stringType; break;
|
|
case TypeTag::Bool: b = boolType; break;
|
|
case TypeTag::Any: b = anyType; break;
|
|
case TypeTag::Null: b = nullType; break;
|
|
default: break;
|
|
}
|
|
return {b, nullable};
|
|
}
|
|
|
|
Type TypeContext::CreateFuncType(DynArray<Type> params, Type ret)
|
|
{
|
|
auto *ft = new FuncType(std::move(params), ret);
|
|
allTypes.push_back(ft);
|
|
return Type{ft, false};
|
|
}
|
|
} // namespace Fig
|