mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-26 08:48:44 +00:00
some fixes, going to fix function_call_expression typeclass argument types search bug
This commit is contained in:
parent
f2192b5331
commit
0290b5604a
9 changed files with 307 additions and 111 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
111
src/types.cpp
111
src/types.cpp
|
|
@ -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
99
src/utils.cpp
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue