Files
Fig/src/Sema/Type.cpp

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