Move builtin type class registration to TypeClassRegistration

This commit is contained in:
Kamil Śliwak 2023-09-19 17:13:25 +02:00
parent 201259d50b
commit 4960de7b42
5 changed files with 38 additions and 34 deletions

View File

@ -32,6 +32,30 @@ TypeClassRegistration::TypeClassRegistration(Analysis& _analysis):
m_errorReporter(_analysis.errorReporter()),
m_typeSystem(_analysis.typeSystem())
{
auto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass {
Type type = m_typeSystem.freshTypeVariable({});
auto result = m_typeSystem.declareTypeClass(
type,
_name,
nullptr
);
if (auto error = std::get_if<std::string>(&result))
solAssert(!error, *error);
TypeClass declaredClass = std::get<TypeClass>(result);
// TODO: validation?
GlobalAnnotation& annotation = m_analysis.annotation<TypeClassRegistration>();
solAssert(annotation.builtinClassesByName.emplace(_name, _class).second);
return annotation.builtinClasses.emplace(_class, declaredClass).first->second;
};
declareBuiltinClass("integer", BuiltinClass::Integer);
declareBuiltinClass("*", BuiltinClass::Mul);
declareBuiltinClass("+", BuiltinClass::Add);
declareBuiltinClass("==", BuiltinClass::Equal);
declareBuiltinClass("<", BuiltinClass::Less);
declareBuiltinClass("<=", BuiltinClass::LessOrEqual);
declareBuiltinClass(">", BuiltinClass::Greater);
declareBuiltinClass(">=", BuiltinClass::GreaterOrEqual);
}
bool TypeClassRegistration::analyze(SourceUnit const& _sourceUnit)

View File

@ -41,6 +41,8 @@ public:
};
struct GlobalAnnotation
{
std::map<BuiltinClass, TypeClass> builtinClasses;
std::map<std::string, BuiltinClass> builtinClassesByName;
};
TypeClassRegistration(Analysis& _analysis);

View File

@ -53,23 +53,8 @@ TypeInference::TypeInference(Analysis& _analysis):
{
TypeSystemHelpers helper{m_typeSystem};
auto declareBuiltinClass = [&](std::string _name, BuiltinClass _class) -> TypeClass {
Type type = m_typeSystem.freshTypeVariable({});
auto result = m_typeSystem.declareTypeClass(
type,
_name,
nullptr
);
if (auto error = std::get_if<std::string>(&result))
solAssert(!error, *error);
TypeClass declaredClass = std::get<TypeClass>(result);
// TODO: validation?
solAssert(annotation().builtinClassesByName.emplace(_name, _class).second);
return annotation().builtinClasses.emplace(_class, declaredClass).first->second;
};
auto registeredTypeClass = [&](BuiltinClass _builtinClass) -> TypeClass {
return annotation().builtinClasses.at(_builtinClass);
return m_analysis.annotation<TypeClassRegistration>().builtinClasses.at(_builtinClass);
};
auto defineConversion = [&](BuiltinClass _builtinClass, PrimitiveType _fromType, std::string _functionName) {
@ -106,15 +91,6 @@ TypeInference::TypeInference(Analysis& _analysis):
}};
};
declareBuiltinClass("integer", BuiltinClass::Integer);
declareBuiltinClass("*", BuiltinClass::Mul);
declareBuiltinClass("+", BuiltinClass::Add);
declareBuiltinClass("==", BuiltinClass::Equal);
declareBuiltinClass("<", BuiltinClass::Less);
declareBuiltinClass("<=", BuiltinClass::LessOrEqual);
declareBuiltinClass(">", BuiltinClass::Greater);
declareBuiltinClass(">=", BuiltinClass::GreaterOrEqual);
defineConversion(BuiltinClass::Integer, PrimitiveType::Integer, "fromInteger");
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
@ -640,8 +616,10 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
}
},
[&](Token _token) -> std::optional<TypeClass> {
auto const& classRegistrationAnnotation = m_analysis.annotation<TypeClassRegistration>();
if (auto builtinClass = builtinClassFromToken(_token))
if (auto typeClass = util::valueOrNullptr(annotation().builtinClasses, *builtinClass))
if (auto typeClass = util::valueOrNullptr(classRegistrationAnnotation.builtinClasses, *builtinClass))
return *typeClass;
m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name.");
return std::nullopt;
@ -1044,7 +1022,9 @@ bool TypeInference::visit(Literal const& _literal)
m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported.");
return false;
}
literalAnnotation.type = m_typeSystem.freshTypeVariable(Sort{{annotation().builtinClasses.at(BuiltinClass::Integer)}});
TypeClass integerClass = m_analysis.annotation<TypeClassRegistration>().builtinClasses.at(BuiltinClass::Integer);
literalAnnotation.type = m_typeSystem.freshTypeVariable(Sort{{integerClass}});
return false;
}
@ -1058,10 +1038,10 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi
if (typeClassDeclaration)
return _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
// TODO: better mechanism than fetching by name.
auto const& annotation = _analysis.annotation<TypeRegistration>();
auto const& inferenceAnnotation = _analysis.annotation<TypeInference>();
return annotation.builtinClassInstantiations.at(
inferenceAnnotation.builtinClassesByName.at(
auto const& typeRegistrationAnnotation = _analysis.annotation<TypeRegistration>();
auto const& classRegistrationAnnotation = _analysis.annotation<TypeClassRegistration>();
return typeRegistrationAnnotation.builtinClassInstantiations.at(
classRegistrationAnnotation.builtinClassesByName.at(
_analysis.typeSystem().typeClassName(_class)
)
);

View File

@ -45,8 +45,6 @@ public:
};
struct GlobalAnnotation
{
std::map<BuiltinClass, TypeClass> builtinClasses;
std::map<std::string, BuiltinClass> builtinClassesByName;
std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;
std::map<Token, std::tuple<TypeClass, std::string>> operators;
std::map<TypeConstructor, std::map<std::string, TypeMember>> members;

View File

@ -219,7 +219,7 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(IRGener
return _context.analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
// TODO: better mechanism than fetching by name.
auto& instantiations = _context.analysis.annotation<TypeRegistration>().builtinClassInstantiations;
auto& builtinClassesByName = _context.analysis.annotation<TypeInference>().builtinClassesByName;
auto& builtinClassesByName = _context.analysis.annotation<TypeClassRegistration>().builtinClassesByName;
return instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class)));
}
}