mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 15:08:45 +00:00
type_check_visitor FindSubExpressionMethodAndUpdate fixes, fixes
This commit is contained in:
parent
a90bcb5d92
commit
868d514bcc
6 changed files with 79 additions and 49 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
BIN
src/.type_check_visitor.cpp.kate-swp
Normal file
BIN
src/.type_check_visitor.cpp.kate-swp
Normal file
Binary file not shown.
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue