type_check_visitor FindSubExpressionMethodAndUpdate fixes, fixes

This commit is contained in:
ProgramSnail 2023-05-17 11:51:14 +03:00
parent a90bcb5d92
commit 868d514bcc
6 changed files with 79 additions and 49 deletions

View file

@ -144,13 +144,11 @@ private:
std::optional<FunctionDeclaration*> std::optional<FunctionDeclaration*>
FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, FindSubExpressionMethodAndUpdate(FunctionCallExpression* node,
SubExpressionToken* expression_node, SubExpressionToken* expression_node,
const std::string& name,
const BaseNode& base_node); const BaseNode& base_node);
std::optional<FunctionDeclaration*> std::optional<FunctionDeclaration*>
FindTypeFunctionAndUpdate(FunctionCallExpression* node, FindTypeFunctionAndUpdate(FunctionCallExpression* node,
TypeExpression* type_node, TypeExpression* type_node,
const std::string& name,
std::unordered_map<std::string, utils::IdType>& context); std::unordered_map<std::string, utils::IdType>& context);
private: private:

View file

@ -21,12 +21,21 @@ public:
AbstractType() = default; AbstractType() = default;
AbstractType(utils::AbstractTypeModifier modifier, AbstractType(utils::AbstractTypeModifier modifier,
const std::string& name, const std::string& name,
const std::vector<utils::IdType>& requirements) : modifier_(modifier), name_(name) { const std::vector<utils::IdType>& requirement_graph_ids)
for (auto& typeclass : requirements) { : modifier_(modifier),
requirements_.insert(typeclass); name_(name) {
for (auto& typeclass : requirement_graph_ids) {
requirement_graph_ids_.insert(typeclass);
} }
} }
AbstractType(utils::AbstractTypeModifier modifier,
const std::string& name,
const std::unordered_set<utils::IdType>& requirement_graph_ids)
: modifier_(modifier),
name_(name),
requirement_graph_ids_(requirement_graph_ids) {}
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context); std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
bool Same(const AbstractType& type) const; bool Same(const AbstractType& type) const;
bool operator<(const AbstractType& type) const; bool operator<(const AbstractType& type) const;
@ -35,10 +44,14 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name, std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const; const std::unordered_set<utils::IdType>& type_namespaces) const;
bool HasTypeclass(utils::IdType graph_id) {
return requirement_graph_ids_.count(graph_id) != 0;
}
private: private:
utils::AbstractTypeModifier modifier_; utils::AbstractTypeModifier modifier_;
std::string name_; std::string name_;
std::unordered_set<utils::IdType> requirements_; // TODO: all typeclasses from tree std::unordered_set<utils::IdType> requirement_graph_ids_; // TODO: all typeclasses from tree
}; };
class DefinedType { class DefinedType {

Binary file not shown.

View file

@ -392,15 +392,17 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
} }
} }
auto function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).declaration.value(); // checked in type_check_visitor // TODO: typeclass functions
auto function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_.value()).declaration.value(); // checked in type_check_visitor
for (size_t i = 0; i < node->parameters.size(); ++i) { for (size_t i = 0; i < node->parameters.size(); ++i) {
// TODO: local bastract types, absract types, etc. // TODO: local abstract types, absract types, etc.
context_manager_.DefineLocalType(function_declaration.parameters[i].type, node->parameters[i]->type_id_.value()); // TODO: check context_manager_.DefineLocalType(function_declaration.parameters[i].type, node->parameters[i]->type_id_.value()); // TODO: check
} }
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition; // TODO: typeclass functions
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_.value()).definition;
if (maybe_function_definition.has_value()) { if (maybe_function_definition.has_value()) {
for (size_t i = 0; i < node->arguments.size(); ++i) { for (size_t i = 0; i < node->arguments.size(); ++i) {

View file

@ -811,19 +811,19 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
maybe_function_declaration = FindSubExpressionMethodAndUpdate( maybe_function_declaration = FindSubExpressionMethodAndUpdate(
node, node,
std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()).get(), std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()).get(),
node->name,
node->base); node->base);
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) { } else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
maybe_function_declaration = FindTypeFunctionAndUpdate( maybe_function_declaration = FindTypeFunctionAndUpdate(
node, node,
std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get(), std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get(),
node->name,
context); context);
} else { } else {
error_handling::HandleInternalError("Unexpected prefix type", error_handling::HandleInternalError("Unexpected prefix type",
"TypeCheckVisitor.FunctionCallExpression"); "TypeCheckVisitor.FunctionCallExpression");
} }
} else { } else {
// TODO: static functions from parent namespaces' typeclasses
std::optional<utils::IdType> maybe_function_id; std::optional<utils::IdType> maybe_function_id;
if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
@ -1467,7 +1467,6 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
std::optional<FunctionDeclaration*> std::optional<FunctionDeclaration*>
TypeCheckVisitor::FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, TypeCheckVisitor::FindSubExpressionMethodAndUpdate(FunctionCallExpression* node,
SubExpressionToken* expression_node, SubExpressionToken* expression_node,
const std::string& name,
const BaseNode& base_node) { const BaseNode& base_node) {
std::optional<utils::IdType> maybe_function_id; std::optional<utils::IdType> maybe_function_id;
std::optional<FunctionDeclaration*> maybe_function_declaration; std::optional<FunctionDeclaration*> maybe_function_declaration;
@ -1475,13 +1474,36 @@ std::optional<FunctionDeclaration*>
Visitor::Visit(*expression_node); Visitor::Visit(*expression_node);
utils::IdType expression_type = current_type_; utils::IdType expression_type = current_type_;
std::optional<info::type::DefinedType*> maybe_expression_type_info = auto maybe_typeclass_function_info =
typeclass_graph_.GetFunctionInfo(node->name, std::nullopt);
auto maybe_abstract_type_info =
context_manager_.GetValue<info::type::AbstractType>(expression_type);
if (maybe_abstract_type_info.has_value()) {
if (!maybe_typeclass_function_info.has_value()) {
error_handling::HandleTypecheckError("Typeclass function not found", base_node);
}
info::type::AbstractType* abstract_type_info = maybe_abstract_type_info.value();
if (!typeclass_graph_.FindFunctionTypeclass(node->name).value()) {
error_handling::HandleInternalError("Typeclass function info found, but typeclas id not found",
"TypeCheckVisitor.FindSubExpressionMethodAndUpdate");
}
if (abstract_type_info->HaveTypeclass(typeclass_graph_.FindFunctionTypeclass(node->name).value())) {
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
}
} else {
// TODO: check typeclass methods for defined type
auto maybe_defined_type_info =
context_manager_.GetValue<info::type::DefinedType>(expression_type); context_manager_.GetValue<info::type::DefinedType>(expression_type);
if (!maybe_expression_type_info.has_value()) { if (!maybe_defined_type_info.has_value()) {
error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", base_node); error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", base_node);
} }
utils::IdType type_id = maybe_expression_type_info.value()->GetTypeId(); utils::IdType type_id = maybe_defined_type_info.value()->GetTypeId();
std::optional<info::definition::AnyType*> maybe_type_info = std::optional<info::definition::AnyType*> maybe_type_info =
global_info_.GetTypeInfo<info::definition::AnyType>(type_id); global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) { if (!maybe_type_info.has_value()) {
@ -1490,18 +1512,13 @@ std::optional<FunctionDeclaration*>
} }
// TODO: better decision ?? // TODO: better decision ??
std::optional<utils::IdType> maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[name]; std::optional<utils::IdType> maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
utils::ValueType expression_value_type = context_manager_.GetValueType(expression_type); utils::ValueType expression_value_type = context_manager_.GetValueType(expression_type);
if (expression_value_type == utils::ValueType::Tmp) {
error_handling::HandleInternalError("Expression value type is ValueType::Type",
"TypeCheckVisitor.FunctionCallExpression");
}
if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) { if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) {
// TODO: choose expression value types // TODO: choose expression value types
maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[name]; maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name];
} }
if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage
@ -1517,6 +1534,7 @@ std::optional<FunctionDeclaration*>
maybe_function_declaration = maybe_function_declaration =
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
} }
}
return maybe_function_declaration; return maybe_function_declaration;
} }
@ -1525,7 +1543,6 @@ std::optional<FunctionDeclaration*>
std::optional<FunctionDeclaration*> std::optional<FunctionDeclaration*>
TypeCheckVisitor::FindTypeFunctionAndUpdate(FunctionCallExpression* node, TypeCheckVisitor::FindTypeFunctionAndUpdate(FunctionCallExpression* node,
TypeExpression* type_node, TypeExpression* type_node,
const std::string& name,
std::unordered_map<std::string, utils::IdType>& context) { std::unordered_map<std::string, utils::IdType>& context) {
std::optional<utils::IdType> maybe_function_id; std::optional<utils::IdType> maybe_function_id;
std::optional<FunctionDeclaration*> maybe_function_declaration; std::optional<FunctionDeclaration*> maybe_function_declaration;
@ -1545,7 +1562,7 @@ std::optional<FunctionDeclaration*>
} }
path.push_back(type_node->type.type); path.push_back(type_node->type.type);
maybe_function_id = namespace_visitor_.FindFunctionId(path, name); maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
CollectTypeExpressionContext(*type_node, context); CollectTypeExpressionContext(*type_node, context);

View file

@ -17,8 +17,8 @@ bool AbstractType::Same(const AbstractType& type) const {
} }
bool AbstractType::operator<(const AbstractType& type) const { bool AbstractType::operator<(const AbstractType& type) const {
for (auto& typeclass : requirements_) { for (auto& graph_id : requirement_graph_ids_) {
if (type.requirements_.count(typeclass) == 0) { if (type.requirement_graph_ids_.count(graph_id) == 0) {
return false; return false;
} }
} }