mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
basic type unification (gen 2)
This commit is contained in:
parent
662a846d2d
commit
190046498a
2 changed files with 82 additions and 66 deletions
|
|
@ -176,11 +176,9 @@ public:
|
||||||
kCheckLeftIsSubmode, // only check is performed
|
kCheckLeftIsSubmode, // only check is performed
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: next iteration of type check
|
bool Unify(Type left_id, Type right_id, UnifyModePolicy policy);
|
||||||
bool Unify(Type left, Type right, UnifyModePolicy policy);
|
|
||||||
|
|
||||||
bool Resolve(Type generic,
|
bool Resolve(Type generic, const TypeData &replacement, Modifier modifier);
|
||||||
const TypeData &replacement /* TODO , Mode mode = {}*/);
|
|
||||||
|
|
||||||
// TODO: needed ??
|
// TODO: needed ??
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -222,80 +222,98 @@ nodes::Type TypeStorage::AddModificationOf(Type type, Modifier modifier) {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
bool TypeStorage::Unify(Type /*left*/, Type /*right*/,
|
// TODO: FIXME: Handle "equal to builtin type without params" in some way
|
||||||
UnifyModePolicy /*policy*/) {
|
// TODO: return Optional<Error> instead ??
|
||||||
// Type &left = left_id.get();
|
bool TypeStorage::Unify(Type left_id, Type right_id, UnifyModePolicy policy) {
|
||||||
// Type &right = right_id.get();
|
TypeData &left = left_id.get();
|
||||||
|
TypeData &right = right_id.get();
|
||||||
|
|
||||||
// switch (policy) {
|
// --- modifiers
|
||||||
// case UnifyModePolicy::Ignore:
|
|
||||||
// break;
|
|
||||||
// case UnifyModePolicy::ApplyStrongest:
|
|
||||||
// left.mode = Mode::choose_min(left.mode, right.mode);
|
|
||||||
// right.mode = left.mode;
|
|
||||||
// break;
|
|
||||||
// case UnifyModePolicy::CheckLeftIsSubmode:
|
|
||||||
// if (not left.mode.is_submode(right.mode)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (const auto *left_generic = get_if<GenericType>(&left.type);
|
switch (policy) {
|
||||||
// left_generic != nullptr) {
|
case UnifyModePolicy::kIgnore:
|
||||||
// // TODO: check if other type contains generic
|
break;
|
||||||
// std::clog << "left is resolved with policy <" <<
|
case UnifyModePolicy::kApplyStrongest:
|
||||||
// static_cast<size_t>(policy) << ">\n"; resolve(*left_generic, right,
|
left.modifier = utils::ChooseMinModifier(left.modifier, right.modifier);
|
||||||
// left.mode); return true;
|
right.modifier = left.modifier;
|
||||||
// }
|
break;
|
||||||
|
case UnifyModePolicy::kCheckLeftIsSubmode:
|
||||||
|
if (not utils::IsSubmodifier(left.modifier, right.modifier)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if (const auto *right_generic = get_if<GenericType>(&right.type);
|
// --- generics
|
||||||
// right_generic != nullptr) {
|
|
||||||
// // TODO: check if other type contains generic
|
|
||||||
// std::clog << "right is resolved with policy <" <<
|
|
||||||
// static_cast<size_t>(policy) << ">\n"; resolve(*right_generic, left,
|
|
||||||
// right.mode); return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (left.type.index() != right.type.index()) {
|
// TODO: check if other type contains this generic (prevent inf loops ??)
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (holds_alternative<ArrowType>(left.type)) {
|
if (left.IsGeneric()) {
|
||||||
// const auto &left_types = std::get<ArrowType>(left.type).types;
|
// TODO: use Log
|
||||||
// const auto &right_types = std::get<ArrowType>(right.type).types;
|
// std::clog << "left is resolved with policy <" <<
|
||||||
|
// static_cast<size_t>(policy)
|
||||||
|
// << ">\n";
|
||||||
|
Resolve(left_id, right, left.modifier);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// if (left_types.size() != right_types.size()) {
|
if (right.IsGeneric()) {
|
||||||
// return false;
|
// TODO: use Log
|
||||||
// }
|
// std::clog << "right is resolved with policy <"
|
||||||
|
// << static_cast<size_t>(policy) << ">\n";
|
||||||
|
Resolve(right_id, left, right.modifier);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// bool all_unify_passed = true;
|
// --- name
|
||||||
// for (size_t i = 0; i < left_types.size(); ++i) {
|
|
||||||
// if (not unify(left_types[i], right_types[i], policy)) {
|
|
||||||
// all_unify_passed = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return all_unify_passed;
|
if (left.name != right.name) {
|
||||||
// }
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// --- annotations
|
||||||
// return true;
|
|
||||||
throw std::exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TypeStorage::Resolve(
|
if (left.HasAnnotation() and right.HasAnnotation() and
|
||||||
Type generic, const TypeData &replacement /* TODO , Mode mode = {}*/) {
|
left.annotation != right.annotation) {
|
||||||
error_handling::ensure(generic.get().IsGeneric(), "Type should be generic");
|
return false;
|
||||||
error_handling::ensure(generic.get().IsGeneric(), "Type should be generic");
|
}
|
||||||
for (auto &type : storage_) {
|
|
||||||
if (type.IsGeneric() && type.name == generic.get().name) {
|
if (not left.HasAnnotation()) {
|
||||||
type = replacement;
|
left.annotation = right.annotation;
|
||||||
// type.mode = mode;
|
}
|
||||||
|
|
||||||
|
if (not right.HasAnnotation()) {
|
||||||
|
right.annotation = left.annotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- params
|
||||||
|
|
||||||
|
if (left.params.size() != right.params.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool all_unifications_passed = true;
|
||||||
|
for (size_t i = 0; i < left.params.size(); ++i) {
|
||||||
|
if (not Unify(left.params[i], right.params[i], policy)) {
|
||||||
|
all_unifications_passed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_unifications_passed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TypeStorage::Resolve(Type generic, const TypeData &replacement,
|
||||||
|
Modifier modifier) {
|
||||||
|
// TODO: use Log
|
||||||
|
// error_handling::ensure(generic.get().IsGeneric(), "Type should be
|
||||||
|
// generic"); error_handling::ensure(generic.get().IsGeneric(), "Type should
|
||||||
|
// be generic");
|
||||||
|
for (auto &type : storage_) {
|
||||||
|
if (type.IsGeneric() and type.name == generic.get().name) {
|
||||||
|
type = replacement;
|
||||||
|
type.modifier = modifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
throw std::exception();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue