This commit is contained in:
ProgramSnail 2023-05-18 01:02:54 +03:00
parent 3abac1b643
commit b901078956
6 changed files with 291 additions and 155 deletions

View file

@ -356,11 +356,13 @@ public:
std::vector<utils::IdType>
GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node);
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*>
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node);
std::unordered_map<std::string, TypeclassGraph::FunctionInfo>
GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>>
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>>
GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node);
std::unordered_map<std::string, utils::IdType>* ChooseNamespaces(
utils::ClassInternalsModifier modifier,

View file

@ -30,7 +30,8 @@ public:
return &std::get<T>(value);
}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const InternalValue& value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public:
std::variant<double,
long long,
@ -48,7 +49,8 @@ public:
ValueManager* value_manager)
: fields(std::move(fields)), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const TupleValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public:
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
@ -67,7 +69,8 @@ public:
TupleValue value;
size_t current_constructor;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const VariantValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
};
struct ReferenceToValue {
@ -83,7 +86,9 @@ public:
std::vector<utils::ReferenceModifier> references;
utils::IdType value;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const ReferenceToValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private:
ValueManager* value_manager_ = nullptr;
};
@ -100,7 +105,9 @@ public:
std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const FunctionValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private:
ValueManager* value_manager_ = nullptr;
};
@ -119,7 +126,9 @@ public:
std::vector<utils::IdType> elements;
bool is_constant_size = false;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const ArrayValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
private:
ValueManager* value_manager_ = nullptr;
};
@ -131,7 +140,9 @@ public:
OptionalValue(std::optional<utils::IdType> value, ValueManager* value_manager)
: value(value), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const OptionalValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public:
std::optional<utils::IdType> value;
@ -146,7 +157,9 @@ public:
template<typename T>
explicit Value(const T& value) : value(value) {} // move ??
std::optional<utils::IdType> GetFieldValue(const std::string& name);
bool Same(const Value& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
public:
std::variant<InternalValue,
TupleValue,
@ -186,7 +199,9 @@ public:
return values_.at(value_id).second;
}
bool EqualValues(utils::IdType first_value, utils::IdType second_value) = delete; // TODO
bool EqualValues(utils::IdType first_value, utils::IdType second_value) {
return GetAnyValue(first_value)->Same(*GetAnyValue(second_value));
}
bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete;

View file

@ -492,28 +492,41 @@ std::vector<utils::IdType>
return typeclasses_vector;
}
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*>
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> functions;
std::unordered_map<std::string, TypeclassGraph::FunctionInfo> functions;
for (auto& typeclass : node->typeclasses) {
utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_;
auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id);
for (auto& requirement : requirements) {
functions[requirement.first] = requirement.second;
auto requirement_iter = functions.find(requirement.first);
if (requirement_iter == functions.end()) {
functions[requirement.first] = *requirement.second;
} else {
if (requirement_iter->second.definition.has_value()) {
if (requirement.second->definition.has_value()) {
error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node);
}
} else {
requirement_iter->second.definition = requirement.second->definition;
}
}
}
}
return functions;
}
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>>
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node) {
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> // TODO: optimize, cache
GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node,
const interpreter::tokens::BaseNode& base_node) {
std::unordered_map<std::string, TypeclassGraph::FunctionInfo*> functions_set = GetAnnotatedTypeFunctionsMap(node);
auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node);
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo*>> functions_vector;
std::vector<std::pair<std::string, TypeclassGraph::FunctionInfo>> functions_vector;
functions_vector.reserve(functions_vector.size());
for (auto& typeclass : functions_set) {
functions_vector.push_back(typeclass);

View file

@ -269,18 +269,18 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
is_in_statement_ = true;
std::unordered_map<std::string, info::TypeclassGraph::FunctionInfo*> required_functions =
global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get());
std::unordered_map<std::string, info::TypeclassGraph::FunctionInfo> required_functions =
global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get(), node->base);
std::string& type_name = node->definition->type->type;
for (auto& function : required_functions) { // TODO: optimize
if (function.second->definition.has_value()) { // TODO: check
if (function.second.definition.has_value()) { // TODO: check
continue;
}
std::unordered_map<std::string, utils::IdType>* current_namespaces =
global_info_.ChooseNamespaces(function.second->modifier, namespace_visitor_.GetCurrentNamespace());
global_info_.ChooseNamespaces(function.second.modifier, namespace_visitor_.GetCurrentNamespace());
auto& type_functions = global_info_.GetNamespaceInfo((*current_namespaces)[type_name]).functions;

View file

@ -3,13 +3,30 @@
namespace info::value {
std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string& name) {
bool InternalValue::Same(const InternalValue& other_value) const {
}
std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string& name) const {
return std::nullopt;
}
//
std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name) {
bool TupleValue::Same(const TupleValue& other_value) const {
// TODO: check, that type is same
if (fields.size() != other_value.fields.size()) {
return false;
}
for (size_t i = 0; i < fields.size(); ++i) {
if (!) {
return false;
}
}
return true;
}
std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name) const {
for (size_t i = 0; i < fields.size(); ++i) { // TODO: optimize??
if (fields[i].first.has_value() && fields[i].first.value() == name) {
return fields[i].second;
@ -20,37 +37,126 @@ std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name)
//
std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name) {
bool VariantValue::Same(const VariantValue& other_value) const {
// TODO: check, that type is same
}
std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name) const {
return value.GetFieldValue(name);
}
//
std::optional<utils::IdType> ReferenceToValue::GetFieldValue(const std::string& name) {
bool ReferenceToValue::Same(const ReferenceToValue& other_value) const {
if (references.size() != other_value.references.size()) {
return false;
}
for (size_t i = 0; i < references.size(); ++i) {
if (references[i] != other_value.references[i]) {
return false;
}
}
return value_manager_->GetAnyValue(value)->Same(*value_manager_->GetAnyValue(other_value.value));
}
std::optional<utils::IdType> ReferenceToValue::GetFieldValue(const std::string& name) const {
return value_manager_->GetAnyValue(value)->GetFieldValue(name);
}
//
std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string& name) {
bool FunctionValue::Same(const FunctionValue& other_value) const {
size_t this_index = function.index();
size_t other_index = other_value.function.index();
if (this_index == other_index) {
switch (this_index) {
case 0:
return std::get<interpreter::tokens::FunctionDeclaration*>(function) == std::get<interpreter::tokens::FunctionDeclaration*>(other_value.function);
case 1:
return std::get<interpreter::tokens::LambdaFunction*>(function) == std::get<interpreter::tokens::LambdaFunction*>(other_value.function);
default:
// error
break;
}
}
return false;
}
std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string& name) const {
return std::nullopt;
}
//
std::optional<utils::IdType> ArrayValue::GetFieldValue(const std::string& name) {
bool ArrayValue::Same(const ArrayValue& other_value) const {
if (is_constant_size != other_value.is_constant_size
|| elements.size() != other_value.elements.size()) {
return false;
}
for (size_t i = 0; i < elements.size(); ++i) {
if (!value_manager_->GetAnyValue(elements[i])->Same(*value_manager_->GetAnyValue(other_value.elements[i]))) {
return false;
}
}
return true;
}
std::optional<utils::IdType> ArrayValue::GetFieldValue(const std::string& name) const {
return std::nullopt;
}
//
std::optional<utils::IdType> OptionalValue::GetFieldValue(const std::string& name) {
bool OptionalValue::Same(const OptionalValue& other_value) const {
if (value.has_value() != other_value.value.has_value()) {
return false;
}
if (value.has_value()) { // => other_value.value.has_value()
return value_manager_->GetAnyValue(value.value())->Same(*value_manager_->GetAnyValue(other_value.value.value()));
}
return true;
}
std::optional<utils::IdType> OptionalValue::GetFieldValue(const std::string& name) const {
return std::nullopt;
}
//
std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) {
bool Value::Same(const Value& other_value) const {
size_t this_index = value.index();
size_t other_index = other_value.value.index();
if (this_index == other_index) {
switch (this_index) {
case 0:
return std::get<InternalValue>(value).Same(std::get<InternalValue>(other_value.value));
case 1:
return std::get<TupleValue>(value).Same(std::get<TupleValue>(other_value.value));
case 2:
return std::get<VariantValue>(value).Same(std::get<VariantValue>(other_value.value));
case 3:
return std::get<ReferenceToValue>(value).Same(std::get<ReferenceToValue>(other_value.value));
case 4:
return std::get<FunctionValue>(value).Same(std::get<FunctionValue>(other_value.value));
case 5:
return std::get<ArrayValue>(value).Same(std::get<ArrayValue>(other_value.value));
case 6:
return std::get<OptionalValue>(value).Same(std::get<OptionalValue>(other_value.value));
default:
// error
break;
}
}
return false;
}
std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) const {
size_t index = value.index();
switch (index) {