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_errorReporter(_analysis.errorReporter()),
m_typeSystem(_analysis.typeSystem()) 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) bool TypeClassRegistration::analyze(SourceUnit const& _sourceUnit)

View File

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

View File

@ -53,23 +53,8 @@ TypeInference::TypeInference(Analysis& _analysis):
{ {
TypeSystemHelpers helper{m_typeSystem}; 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 { 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) { 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"); defineConversion(BuiltinClass::Integer, PrimitiveType::Integer, "fromInteger");
defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul"); defineBinaryMonoidalOperator(BuiltinClass::Mul, Token::Mul, "mul");
@ -640,8 +616,10 @@ bool TypeInference::visit(TypeClassInstantiation const& _typeClassInstantiation)
} }
}, },
[&](Token _token) -> std::optional<TypeClass> { [&](Token _token) -> std::optional<TypeClass> {
auto const& classRegistrationAnnotation = m_analysis.annotation<TypeClassRegistration>();
if (auto builtinClass = builtinClassFromToken(_token)) if (auto builtinClass = builtinClassFromToken(_token))
if (auto typeClass = util::valueOrNullptr(annotation().builtinClasses, *builtinClass)) if (auto typeClass = util::valueOrNullptr(classRegistrationAnnotation.builtinClasses, *builtinClass))
return *typeClass; return *typeClass;
m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name."); m_errorReporter.typeError(2658_error, _typeClassInstantiation.location(), "Invalid type class name.");
return std::nullopt; return std::nullopt;
@ -1044,7 +1022,9 @@ bool TypeInference::visit(Literal const& _literal)
m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported."); m_errorReporter.typeError(2345_error, _literal.location(), "Only integers are supported.");
return false; 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; return false;
} }
@ -1058,10 +1038,10 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi
if (typeClassDeclaration) if (typeClassDeclaration)
return _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations; return _analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
// TODO: better mechanism than fetching by name. // TODO: better mechanism than fetching by name.
auto const& annotation = _analysis.annotation<TypeRegistration>(); auto const& typeRegistrationAnnotation = _analysis.annotation<TypeRegistration>();
auto const& inferenceAnnotation = _analysis.annotation<TypeInference>(); auto const& classRegistrationAnnotation = _analysis.annotation<TypeClassRegistration>();
return annotation.builtinClassInstantiations.at( return typeRegistrationAnnotation.builtinClassInstantiations.at(
inferenceAnnotation.builtinClassesByName.at( classRegistrationAnnotation.builtinClassesByName.at(
_analysis.typeSystem().typeClassName(_class) _analysis.typeSystem().typeClassName(_class)
) )
); );

View File

@ -45,8 +45,6 @@ public:
}; };
struct GlobalAnnotation struct GlobalAnnotation
{ {
std::map<BuiltinClass, TypeClass> builtinClasses;
std::map<std::string, BuiltinClass> builtinClassesByName;
std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions; std::map<TypeClass, std::map<std::string, Type>> typeClassFunctions;
std::map<Token, std::tuple<TypeClass, std::string>> operators; std::map<Token, std::tuple<TypeClass, std::string>> operators;
std::map<TypeConstructor, std::map<std::string, TypeMember>> members; 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; return _context.analysis.annotation<TypeRegistration>(*typeClassDeclaration).instantiations;
// TODO: better mechanism than fetching by name. // TODO: better mechanism than fetching by name.
auto& instantiations = _context.analysis.annotation<TypeRegistration>().builtinClassInstantiations; 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))); return instantiations.at(builtinClassesByName.at(_context.analysis.typeSystem().typeClassName(_class)));
} }
} }