some fixes, going to fix function_call_expression typeclass argument types search bug

This commit is contained in:
ProgramSnail 2023-05-22 01:25:12 +03:00
parent f2192b5331
commit 0290b5604a
9 changed files with 307 additions and 111 deletions

View file

@ -52,11 +52,9 @@ void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.EnterContext();
}
// including namespace typeclass
// define typeclasses local types as namespace typeclass
for (auto& requirement_graph_id : requirement_graph_ids) {
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(requirement_graph_id).name, abstract_type);
}
abstract_type = context_manager_.ToModifiedValue(abstract_type, utils::ValueType::Tmp); // ??
AddGraphIdLocalTypes(graph_id, abstract_type);
} else if (node->link_type_id_.has_value()) {
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
@ -80,12 +78,7 @@ void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.EnterContext();
}
// better decision ??
// define typeclasses local types as namespace type
auto typeclass_graph_ids = typeclass_graph_.GetDependenciesVector(type_info->type.node->graph_id_);
for (auto& typeclass_graph_id : typeclass_graph_ids) {
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(typeclass_graph_id).name, type);
}
AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
error_handling::HandleTypecheckError("Namespaces of one type are one in another", node->base);
@ -269,6 +262,8 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
returned_type_ = current_type_;
}
if (!context_manager_.EqualValues(returned_type, returned_type_.value())) {
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type)->ToString());
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type_.value())->ToString());
error_handling::HandleTypecheckError("Wrong function return type", node->base);
}
returned_type_ = std::nullopt;
@ -319,7 +314,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
utils::ValueType::Tmp);
if (!context_manager_.DefineLocalType(node->type->type, current_type_)) {
error_handling::HandleTypecheckError("Can't define basic / astract type: abstract type redefinition", node->base);
error_handling::HandleTypecheckError("Can't define basic / abstract type: abstract type redefinition", node->base);
}
current_type_ = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp);
@ -731,6 +726,8 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
// TODO: more builtin functions, better handling (??)
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context_manager_.EnterContext();
std::optional<FunctionDeclaration*> maybe_function_declaration;
std::unordered_map<std::string, utils::IdType> context;
@ -749,7 +746,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
if (node->prefix.has_value()) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_);
utils::IdType expression_type = current_type_;
maybe_function_declaration = FindExpressionMethodAndUpdate(node, expression_type);
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
maybe_function_declaration = FindTypeFunctionAndUpdate(
node,
@ -843,6 +841,8 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
info::type::TupleType(std::nullopt, fields, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
@ -988,7 +988,10 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
current_type_ = TypeInContext(current_type_, context);
current_type_ = context_manager_.AddValue(
info::type::DefinedType(type_id, current_type_, type_info.modifier, context_manager_.GetValueManager()),
info::type::DefinedType(type_id,
current_type_,
type_info.modifier,
context_manager_.GetValueManager()),
utils::ValueType::Tmp);
node->base.type_ = current_type_;
@ -1279,7 +1282,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
auto maybe_internal_type = info::type::ToInternalType(node->type.type);
if (maybe_internal_type.has_value()) {
if (maybe_internal_type.has_value()) { // TODO: ???
// checks made in link_symbols_visitor
current_type_ =
context_manager_.AddValue<info::type::InternalType>(
@ -1471,6 +1474,18 @@ std::optional<FunctionDeclaration*>
utils::IdType expression_type) {
std::optional<FunctionDeclaration*> maybe_function_declaration;
auto maybe_internal_type_info = context_manager_.GetValue<info::type::InternalType>(expression_type);
if (maybe_internal_type_info.has_value()) {
auto maybe_abstract_type_id = context_manager_.FindLocalType(info::type::ToString(*maybe_internal_type_info.value()));
if (maybe_abstract_type_id.has_value()) {
expression_type = maybe_abstract_type_id.value();
} else {
error_handling::HandleInternalError("InternalType local abstract type not found",
"TypeCheckVisitor.FindExpressionMethodAndUpdate",
&node->base);
}
}
auto maybe_abstract_type_info = context_manager_.GetValue<info::type::AbstractType>(expression_type);
if (maybe_abstract_type_info.has_value()) {
@ -1478,8 +1493,7 @@ std::optional<FunctionDeclaration*>
maybe_abstract_type_info.value(),
true);
} else {
auto maybe_defined_type_info =
context_manager_.GetValue<info::type::DefinedType>(expression_type);
auto maybe_defined_type_info = context_manager_.GetValue<info::type::DefinedType>(expression_type);
if (!maybe_defined_type_info.has_value()) {
error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", node->base);
}
@ -1488,7 +1502,7 @@ std::optional<FunctionDeclaration*>
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("Functions / Methods implemented only for AnyType",
"TypeCheckVisitor.FunctionCallExpresssion",
"TypeCheckVisitor.FindExpressionMethodAndUpdate",
&node->base);
}
info::definition::AnyType* type_info = maybe_type_info.value();
@ -1645,6 +1659,7 @@ std::optional<FunctionDeclaration*>
}
node->graph_id_ = maybe_typeclass_graph_id;
node->abstract_type_name_ = abstract_type_info->GetName();
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
@ -1671,6 +1686,7 @@ std::optional<FunctionDeclaration*>
}
node->graph_id_ = defined_type->type.node->graph_id_;
// type defined -> abstract type name not needed
maybe_function_declaration = maybe_type_function_info.value()->declaration;

View file

@ -128,7 +128,7 @@ void TypeclassGraph::CalculateGraph() {
}
std::vector<size_t> sorted_verticles = utils::BackTopSort(edges);
std::reverse(sorted_verticles.begin(), sorted_verticles.end());
// std::reverse(sorted_verticles.begin(), sorted_verticles.end());
for (auto& id : sorted_verticles) {
for (auto& dependency : verticles_[id].dependencies) {
@ -146,7 +146,7 @@ void TypeclassGraph::CalculateGraph() {
}
}
}
for (auto& inherited_dependency : verticles_[method_to_vertex_[dependency]].dependencies) {
for (auto& inherited_dependency : verticles_[name_to_typeclass_[dependency]].dependencies) {
verticles_[id].dependencies.insert(inherited_dependency);
}
}

View file

@ -124,6 +124,21 @@ std::optional<utils::IdType> TupleType::GetFieldType(const std::string& name,
return std::nullopt;
}
std::string TupleType::ToString() {
std::string result;
result += "(";
for (auto& field : fields_) {
result += "& ";
result += type_manager_->GetAnyValue(field.second)->ToString();
}
result += ")";
return result;
}
//
std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -174,6 +189,21 @@ std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
return std::nullopt;
}
std::string VariantType::ToString() {
std::string result;
result += "(";
for (auto& constructor : constructors_) {
result += "& ";
result += constructor.ToString();
}
result += ")";
return result;
}
//
std::optional<utils::IdType> OptionalType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -203,6 +233,10 @@ std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string OptionalType::ToString() {
return "Optional " + type_manager_->GetAnyValue(type_)->ToString();
}
//
std::optional<utils::IdType> ReferenceToType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -232,6 +266,29 @@ std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& na
return type_manager_->GetAnyValue(type_)->GetFieldType(name, type_namespaces);
}
std::string ReferenceToType::ToString() {
std::string result;
for (auto& reference : references_) {
switch (reference) {
case utils::ReferenceModifier::Dereference:
result += '~';
break;
case utils::ReferenceModifier::Reference:
result += '^';
break;
case utils::ReferenceModifier::UniqueReference:
result += '@';
break;
}
}
result += type_manager_->GetAnyValue(type_)->ToString();
return result;
}
//
std::optional<utils::IdType> FunctionType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -284,6 +341,26 @@ std::optional<utils::IdType> FunctionType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string FunctionType::ToString() {
std::string result;
result += "(";
bool is_first_argument = true;
for (auto& argument_type : argument_types_) {
if (is_first_argument) {
is_first_argument = false;
} else {
result += " -> ";
}
result += type_manager_->GetAnyValue(argument_type)->ToString();
}
result += " -> " + type_manager_->GetAnyValue(return_type_)->ToString() + ")";
return result;
}
//
std::optional<utils::IdType> ArrayType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -314,6 +391,10 @@ std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&,
return std::nullopt;
}
std::string ArrayType::ToString() {
return "Array (" + std::to_string(size_) + ") " + type_manager_->GetAnyValue(elements_type_)->ToString();
}
//
std::optional<utils::IdType> Type::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -477,5 +558,35 @@ std::string Type::GetTypeName() const {
return ""; // ??
}
std::string Type::ToString() {
size_t index = type_.index();
switch (index) {
case 0:
return std::get<AbstractType>(type_).ToString();
case 1:
return std::get<DefinedType>(type_).ToString();
case 2:
return ::info::type::ToString(std::get<InternalType>(type_));
case 3:
return std::get<TupleType>(type_).ToString();
case 4:
return std::get<VariantType>(type_).ToString();
case 5:
return std::get<ReferenceToType>(type_).ToString();
case 6:
return std::get<FunctionType>(type_).ToString();
case 7:
return std::get<ArrayType>(type_).ToString();
case 8:
return std::get<OptionalType>(type_).ToString();
default:
// error
break;
}
return "";
}
} // namespace info::type

99
src/utils.cpp Normal file
View file

@ -0,0 +1,99 @@
// for clangd
#include "../include/utils.hpp"
#include"../include/error_handling.hpp"
namespace utils {
using std::size_t;
using IdType = size_t;
ValueType IsConstModifierToValueType(IsConstModifier modifier) {
switch (modifier) {
case IsConstModifier::Const:
return ValueType::Const;
case IsConstModifier::Var:
return ValueType::Var;
}
exit(1); // unreachable
}
ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
switch (modifier) {
case ClassInternalsModifier::Const:
return ValueType::Const;
case ClassInternalsModifier::Var:
return ValueType::Var;
case ClassInternalsModifier::Static:
throw std::bad_cast(); // ??
}
exit(1); // unreachable
}
bool IsBuiltinFunction(const std::string& name) { // optimize ??
std::unordered_set<std::string> builtin_functions;
builtin_functions.insert("=");
builtin_functions.insert("<-");
builtin_functions.insert("==");
// builtin_functions.insert("!=");
builtin_functions.insert("<");
// builtin_functions.insert(">");
// builtin_functions.insert("<=");
// builtin_functions.insert(">=");
builtin_functions.insert("+=");
builtin_functions.insert("-=");
builtin_functions.insert("*=");
builtin_functions.insert("div");
builtin_functions.insert("mod");
builtin_functions.insert("/=");
// builtin_functions.insert("+");
// builtin_functions.insert("-");
// builtin_functions.insert("*");
// builtin_functions.insert("/");
builtin_functions.insert("&&");
builtin_functions.insert("||");
builtin_functions.insert("size");
builtin_functions.insert("random");
builtin_functions.insert("print");
builtin_functions.insert("scan");
builtin_functions.insert("zero");
builtin_functions.insert("one");
return builtin_functions.count(name) != 0;
}
void BackVisitDfs(size_t id,
std::vector<size_t>& verticles,
std::vector<size_t>& marks,
const std::vector<std::vector<size_t>>& edges,
size_t mark) {
if (marks[id] != 0) {
return;
}
marks[id] = mark;
for (size_t i = 0; i < edges[id].size(); ++i) {
BackVisitDfs(edges[id][i], verticles, marks, edges, mark);
}
verticles.push_back(id);
}
std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_) {
std::vector<size_t> sorted_verticles;
std::vector<size_t> marks(edges_.size(), 0);
for (size_t i = 0; i < edges_.size(); ++i) {
if (marks[i] == 0) {
BackVisitDfs(i, sorted_verticles, marks, edges_, 1);
}
}
return sorted_verticles;
}
} // namespace utils