better global_info API, better const/var/static handling, const typeclass requirements, fixes

This commit is contained in:
ProgramSnail 2023-05-14 11:28:37 +03:00
parent 047ead6fa3
commit 4f54bb4bd7
15 changed files with 381 additions and 213 deletions

View file

@ -58,12 +58,14 @@ void BuildVisitor::Visit(Namespace* node) {
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
std::string modifier = parse_node.NthChild(1).GetValue();
if (modifier == "const") {
node->modifier = utils::IsConstModifier::Const;
node->modifier = utils::ClassInternalsModifier::Const;
} else if (modifier == "var") {
node->modifier = utils::IsConstModifier::Var;
node->modifier = utils::ClassInternalsModifier::Var;
} else {
error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace");
}
} else {
node->modifier = utils::ClassInternalsModifier::Static;
}
node->type = parse_node.ChildByFieldName("type").GetValue();
@ -273,15 +275,26 @@ void BuildVisitor::Visit(TypeclassDefinitionStatement* node) {
size_t child_count = parse_node.NamedChildCount();
for (size_t i = 0; i + 1 < child_count; ++i) {
current_node_ = parse_node.NthNamedChild(i + 1);
if (current_node_.PreviousSibling().GetValue() != "var") {
node->function_requirements.push_back(std::make_unique<FunctionDeclaration>());
Visit(node->function_requirements.back().get());
} else {
node->method_requirements.push_back(std::make_unique<FunctionDeclaration>());
Visit(node->method_requirements.back().get());
}
if (child_count > 1) {
node->requirements.reserve(child_count - 1);
for (size_t i = 0; i + 1 < child_count; ++i) {
current_node_ = parse_node.NthNamedChild(i + 1);
std::string modifier_name = current_node_.PreviousSibling().GetValue();
utils::ClassInternalsModifier modifier;
if (modifier_name == "const") {
modifier = utils::ClassInternalsModifier::Const;
} else if (modifier_name == "var") {
modifier = utils::ClassInternalsModifier::Var;
} else {
modifier = utils::ClassInternalsModifier::Static;
}
node->requirements.push_back({modifier,
std::make_unique<FunctionDeclaration>()});
Visit(node->requirements.back().second.get());
}
}
current_node_ = parse_node;

View file

@ -135,17 +135,11 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
current_info_.reset();
}
namespace_visitor_.AddEnterNamespace(type_name, std::nullopt, node->base);
for (size_t i = 0; i < node->function_requirements.size(); ++i) {
Visit(node->function_requirements[i].get());
for (size_t i = 0; i < node->requirements.size(); ++i) {
namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, node->base);
Visit(node->requirements[i].second.get());
namespace_visitor_.ExitNamespace();
}
namespace_visitor_.ExitNamespace();
namespace_visitor_.AddEnterNamespace(type_name, utils::IsConstModifier::Var, node->base);
for (size_t i = 0; i < node->method_requirements.size(); ++i) {
Visit(node->method_requirements[i].get());
}
namespace_visitor_.ExitNamespace();
info.node = node;

View file

@ -18,7 +18,7 @@ void GlobalInfo::NamespaceVisitor::AddImport(definition::Import&& import_info,
}
void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier,
utils::ClassInternalsModifier modifier,
const interpreter::tokens::BaseNode& base_node) {
if (type::ToInternalType(name).has_value()) {
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
@ -38,7 +38,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
}
definition::Namespace* namespace_info = &global_info_.namespaces_[id];
if (modifier.has_value()) {
if (modifier != utils::ClassInternalsModifier::Static) {
namespace_info->modifier = modifier;
}
@ -51,7 +51,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
}
void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name,
std::optional<utils::IsConstModifier> modifier) {
utils::ClassInternalsModifier modifier) {
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
auto current_namespaces = ChooseNamespaces(modifier, i);
auto namespace_iter = current_namespaces->find(name);
@ -222,6 +222,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
return id;
}
// TODO: which info needed ??
utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass,
definition::Typeclass&& typeclass_info,
const interpreter::tokens::BaseNode& base_node) {
@ -237,6 +238,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
global_info_.name_to_typeclass_[typeclass] = id;
global_info_.typeclasses_.push_back(std::move(typeclass_info));
definition::Typeclass& moved_typeclass_info = global_info_.typeclasses_.back();
// global_info_.typeclass_graph_.AddTypeclassByNode(moved_typeclass_info.node); // TODO
error_handling::HandleInternalError("Typeclasses are not implemented properly yet",
"GlobalInfo.NamespaceVisitor.AddTypeclass");
return id;
}
@ -282,14 +289,14 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddPartition(const std::vector<std::
return id;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional<std::vector<std::string>>& path) {
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceId(const std::optional<std::vector<std::string>>& path) {
return FindSomething<utils::IdType>(path,
[] (utils::IdType current_namespace) -> std::optional<utils::IdType> {
return current_namespace;
});
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction(
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunctionId(
const std::optional<std::vector<std::string>>& path,
const std::string& name) {
return FindSomething<utils::IdType>(path,
@ -304,7 +311,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction(
});
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod(
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethodId(
const std::optional<std::vector<std::string>>& path,
const std::string& type,
const std::string& name,
@ -335,7 +342,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod(
});
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType(
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeId(
const std::optional<std::vector<std::string>>& path,
const std::string& type) {
return FindSomething<utils::IdType>(path,
@ -350,7 +357,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType(
});
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const std::string& type) {
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalTypeId(const std::string& type) {
auto type_id_iter = global_info_.namespaces_[namespace_stack_.back()].types.find(type);
if (type_id_iter != global_info_.namespaces_[namespace_stack_.back()].types.end()) {
@ -360,7 +367,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const s
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(const std::string& abstract_type) {
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) {
@ -370,7 +377,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(cons
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const std::string& typeclass) {
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) {
auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass);
if (typeclass_id_iter != global_info_.name_to_typeclass_.end()) {
@ -380,7 +387,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const s
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructor(
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructorId(
const std::optional<std::vector<std::string>>& path,
const std::string& constructor) {
return FindSomething<utils::IdType>(path,
@ -439,17 +446,19 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
}
std::unordered_map<std::string, utils::IdType>*
GlobalInfo::NamespaceVisitor::ChooseNamespaces(std::optional<utils::IsConstModifier> modifier,
GlobalInfo::NamespaceVisitor::ChooseNamespaces(utils::ClassInternalsModifier modifier,
utils::IdType namespace_id) {
std::unordered_map<std::string, utils::IdType>* current_namespaces = nullptr;
if (modifier.has_value()) {
if (modifier.value() == utils::IsConstModifier::Const) {
switch (modifier) {
case utils::ClassInternalsModifier::Const:
current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces;
} else {
break;
case utils::ClassInternalsModifier::Var:
current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces;
}
} else {
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
break;
case utils::ClassInternalsModifier::Static:
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
break;
}
return current_namespaces;

View file

@ -12,11 +12,11 @@ namespace interpreter {
void LinkSymbolsVisitor::Visit(Namespace* node) {
// Visitor::Visit(&node->type); // not needed
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalType(node->type);
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalTypeId(node->type);
std::optional<utils::IdType> maybe_typeclass;
if (namespace_visitor_.GetCurrentPath().size() == 0) {
maybe_typeclass = namespace_visitor_.FindTypeclass(node->type);
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
}
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
@ -49,8 +49,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
path.push_back(path_type.type);
}
node->type_id_ = namespace_visitor_.FindType(path, node->type.type);
node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type);
node->type_id_ = namespace_visitor_.FindTypeId(path, node->type.type);
node->constructor_id_ = namespace_visitor_.FindConstructorId(path, node->type.type);
// internal type
if (info::type::ToInternalType(node->type.type).has_value()) {
@ -91,9 +91,9 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
node->type.type_id_ = node->type_id_.value();
}
std::optional<utils::IdType> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
std::optional<info::definition::Namespace*> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
if (maybe_type_namespace.has_value()) {
info::definition::Namespace* type_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_namespace.value());
info::definition::Namespace* type_namespace = maybe_type_namespace.value();
for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) {
info::definition::Namespace* parent_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(type_namespace->parent_namespace);
@ -111,7 +111,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
// Typeclass
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclass(node->typeclass);
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass);
if (maybe_typeclass.has_value()) {
node->typeclass_id_ = maybe_typeclass.value();

View file

@ -25,15 +25,15 @@ void PrintVisitor::Visit(NamespaceSources* node) {
void PrintVisitor::Visit(Namespace* node) {
out_ << "[Namespace] ";
if (node->modifier.has_value()) {
switch (node->modifier.value()) {
case utils::IsConstModifier::Const:
out_ << "const ";
break;
case utils::IsConstModifier::Var:
out_ << "var ";
break;
}
switch (node->modifier) {
case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
}
Visit(&node->type);
out_ << "{\n";
@ -157,20 +157,22 @@ void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
void PrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "[Typeclass] (";
Visit(node->definition.get());
if (!node->function_requirements.empty()) {
if (!node->requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->function_requirements) {
for (auto& requirement : node->requirements) {
out_ << "& ";
Visit(requirement.get());
out_ << "\n";
}
if (!node->method_requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
switch (requirement.first) {
case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
}
Visit(requirement.second.get());
out_ << "\n";
}
out_ << ")\n";
@ -392,15 +394,15 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
out_ << "[ReferenceExpression ";
for (auto& reference : node->references) {
switch (reference) {
case utils::ReferenceModifier::Reference:
out_ << '^';
break;
case utils::ReferenceModifier::UniqueReference:
out_ << '@';
break;
case utils::ReferenceModifier::Dereference:
out_ << '~';
break;
case utils::ReferenceModifier::Reference:
out_ << '^';
break;
case utils::ReferenceModifier::UniqueReference:
out_ << '@';
break;
case utils::ReferenceModifier::Dereference:
out_ << '~';
break;
}
}
out_ << "] (";
@ -491,11 +493,11 @@ void PrintVisitor::Visit(TypeConstructorParameter* node) {
Visit(&node->name.value());
switch (node->asignment_modifier.value()) {
case utils::AssignmentModifier::Assign:
out_ << " = ";
break;
out_ << " = ";
break;
case utils::AssignmentModifier::Move:
out_ << " <- ";
break;
out_ << " <- ";
break;
}
}
Visitor::Visit(node->value);

View file

@ -38,9 +38,9 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()};
utils::IdType abstract_type = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
IsConstModifierToValueType(node->modifier.value()));
ClassInternalsModifierToValueType(node->modifier));
if (node->modifier.has_value()) {
if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.EnterVariableContext(utils::ClassInternalVarName,
abstract_type);
} else {
@ -48,7 +48,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
}
context_manager_.DefineLocalType(node->type, abstract_type);
} else if (node->link_type_id_.has_value()) {
if (node->modifier.has_value()) {
if (node->modifier != utils::ClassInternalsModifier::Static) {
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
if (!maybe_type_info.has_value()) {
@ -64,7 +64,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
current_type_,
maybe_type_info.value()->modifier,
context_manager_.GetValueManager()),
IsConstModifierToValueType(node->modifier.value())));
ClassInternalsModifierToValueType(node->modifier)));
} else {
context_manager_.EnterContext();
}
@ -599,7 +599,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
// TODO: better structure
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
// TODO: Check, that type is not abstract ??
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
auto maybe_operator_id = namespace_visitor_.FindFunctionId(std::nullopt, node->operator_name);
info::definition::Function* operator_info = nullptr;
node->is_method_ = false;
@ -621,16 +621,16 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
std::string left_type_name = maybe_left_type_info.value()->type.type;
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Const);
auto maybe_const_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Const);
if (left_value_type != utils::ValueType::Const) {
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Var);
maybe_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
left_type_name,
node->operator_name,
utils::IsConstModifier::Var);
}
if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) {
@ -795,14 +795,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
}
path.push_back(type_expression.type.type);
maybe_function_id = namespace_visitor_.FindFunction(path, node->name);
maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
CollectTypeExpressionContext(*std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()), context);
} else {
// error
}
} else {
maybe_function_id = namespace_visitor_.FindFunction(std::nullopt, node->name);
maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
}
if (!maybe_function_id.has_value()) {

View file

@ -43,15 +43,15 @@ void TypedPrintVisitor::Visit(Namespace* node) {
}
out_ << "] ";
if (node->modifier.has_value()) {
switch (node->modifier.value()) {
case utils::IsConstModifier::Const:
out_ << "const ";
break;
case utils::IsConstModifier::Var:
out_ << "var ";
break;
}
switch (node->modifier) {
case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
}
Visit(&node->type);
out_ << "{\n";
@ -87,14 +87,14 @@ void TypedPrintVisitor::Visit(AliasDefinitionStatement* node) {
out_ << ") ";
switch (node->modifier) {
case utils::AliasModifier::Alias:
out_ << "alias";
break;
out_ << "alias";
break;
case utils::AliasModifier::Type:
out_ << "type";
break;
out_ << "type";
break;
case utils::AliasModifier::Let:
out_ << "let";
break;
out_ << "let";
break;
}
out_ << ' ';
Visit(&node->type);
@ -113,11 +113,11 @@ void TypedPrintVisitor::Visit(VariableDefinitionStatement* node) {
out_ << ") ";
switch (node->modifier) {
case utils::IsConstModifier::Const:
out_ << "const";
break;
out_ << "const";
break;
case utils::IsConstModifier::Var:
out_ << "var";
break;
out_ << "var";
break;
}
out_ << ' ';
Visitor::Visit(node->name);
@ -172,11 +172,11 @@ void TypedPrintVisitor::Visit(TypeDefinitionStatement* node) {
out_ << ") ";
switch (node->modifier) {
case utils::ClassModifier::Struct:
out_ << "struct";
break;
out_ << "struct";
break;
case utils::ClassModifier::Class:
out_ << "class";
break;
out_ << "class";
break;
}
if (node->is_in_interface) {
out_ << " interface";
@ -198,11 +198,11 @@ void TypedPrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
out_ << ") ";
switch (node->modifier) {
case utils::AbstractTypeModifier::Basic:
out_ << "basic";
break;
out_ << "basic";
break;
case utils::AbstractTypeModifier::Abstract:
out_ << "abstract";
break;
out_ << "abstract";
break;
}
out_ << "] (";
Visit(node->type.get());
@ -218,20 +218,22 @@ void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "] (";
Visit(node->definition.get());
if (!node->function_requirements.empty()) {
if (!node->requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->function_requirements) {
for (auto& requirement : node->requirements) {
out_ << "& ";
Visit(requirement.get());
out_ << "\n";
}
if (!node->method_requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
switch (requirement.first) {
case utils::ClassInternalsModifier::Const:
out_ << "const ";
break;
case utils::ClassInternalsModifier::Var:
out_ << "var ";
break;
case utils::ClassInternalsModifier::Static:
break;
}
Visit(requirement.second.get());
out_ << "\n";
}
out_ << ")\n";

View file

@ -357,11 +357,8 @@ void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
void Visitor::Visit(TypeclassDefinitionStatement* node) {
Visit(node->definition.get());
for (auto& function_requirement : node->function_requirements) {
Visit(function_requirement.get());
}
for (auto& method_requirement : node->method_requirements) {
Visit(method_requirement.get());
for (auto& function_requirement : node->requirements) {
Visit(function_requirement.second.get());
}
}