mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-26 16:58:45 +00:00
part of type_check_visitor done
This commit is contained in:
parent
6fc91aafa0
commit
656f58bcde
14 changed files with 891 additions and 539 deletions
|
|
@ -117,6 +117,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|||
info.argument_type_nodes[i] = &node->type->types[i];
|
||||
}
|
||||
|
||||
info.node = node;
|
||||
|
||||
if (was_in_statement) {
|
||||
current_info_ = std::move(info);
|
||||
} else {
|
||||
|
|
@ -148,7 +150,7 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
|
||||
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
|
||||
|
||||
info.expression = &node->value;
|
||||
info.node = node;
|
||||
|
||||
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// for clangd
|
||||
#include "../include/global_info.hpp"
|
||||
#include "../include/error_handling.hpp"
|
||||
|
||||
namespace info {
|
||||
|
||||
|
|
@ -63,9 +64,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::st
|
|||
id = global_info_.functions_.size();
|
||||
namespace_stack_.back()->functions[name] = id;
|
||||
global_info_.functions_.emplace_back();
|
||||
global_info_.functions_.back().argument_count = function_declaration_info.argument_types.size();
|
||||
global_info_.functions_.back().declaration = std::move(function_declaration_info);
|
||||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_.back().argument_count != function_declaration_info.argument_types.size()) {
|
||||
error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo");
|
||||
}
|
||||
global_info_.functions_[id].declaration = std::move(function_declaration_info);
|
||||
}
|
||||
|
||||
|
|
@ -82,9 +87,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::str
|
|||
id = global_info_.functions_.size();
|
||||
namespace_stack_.back()->functions[name] = id;
|
||||
global_info_.functions_.emplace_back();
|
||||
global_info_.functions_.back().argument_count = function_definition_info.argument_names.size();
|
||||
global_info_.functions_.back().definition = std::move(function_definition_info);
|
||||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_.back().argument_count != function_definition_info.argument_names.size()) {
|
||||
error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo");
|
||||
}
|
||||
global_info_.functions_[id].definition = std::move(function_definition_info);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void LinkSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
for (size_t i = 0; i <node->parameters.size(); ++i) {
|
||||
abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]);
|
||||
}
|
||||
Visit(node->value.get());
|
||||
Visitor::Visit(node->value.get());
|
||||
abstract_types_.ExitContext();
|
||||
}
|
||||
|
||||
|
|
@ -68,10 +68,10 @@ void LinkSymbolsVisitor::Visit(VariableDefinitionStatement* node) {
|
|||
void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||
abstract_types_.EnterContext();
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
Visitor::Visit(parameter.get());
|
||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||
}
|
||||
Visit(node->type.get());
|
||||
Visitor::Visit(node->type.get());
|
||||
abstract_types_.ExitContext();
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
Visit(node->type.get());
|
||||
Visitor::Visit(node->type.get());
|
||||
// TODO: can't be used before definition
|
||||
abstract_types_.DefineType(node->type->type, node->type->type_graph_id_);
|
||||
}
|
||||
|
|
@ -108,224 +108,54 @@ void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
|
||||
void LinkSymbolsVisitor::Visit(FunctionDefinition* node) {
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
Visitor::Visit(parameter.get());
|
||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeDefinition* node) {
|
||||
Visit(node->type.get());
|
||||
Visitor::Visit(node->type.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
Visitor::Visit(parameter.get());
|
||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(AnyAnnotatedType* node) {
|
||||
// TODO check ??
|
||||
if (!node->typeclasses.empty() > 0) {
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
Visitor::Visit(typeclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flow control -----------------
|
||||
|
||||
void LinkSymbolsVisitor::Visit(MatchCase* node) {
|
||||
Visitor::Visit(node->value);
|
||||
if (node->condition.has_value()) {
|
||||
Visitor::Visit(node->condition.value());
|
||||
}
|
||||
if (node->statement.has_value()) {
|
||||
Visitor::Visit(node->statement.value());
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(Match* node) {
|
||||
Visitor::Visit(node->value);
|
||||
for (auto& match_case : node->matches) {
|
||||
Visit(&match_case);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(Condition* node) {
|
||||
Visitor::Visit(node->conditions[0]);
|
||||
Visitor::Visit(node->statements[0]);
|
||||
for (size_t i = 1; i < node->conditions.size(); ++i) {
|
||||
Visitor::Visit(node->conditions[i]);
|
||||
Visitor::Visit(node->statements[i]);
|
||||
}
|
||||
if (node->statements.size() > node->conditions.size()) {
|
||||
Visitor::Visit(node->statements[node->conditions.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(DoWhileLoop* node) {
|
||||
Visitor::Visit(node->statement);
|
||||
Visitor::Visit(node->condition);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(WhileLoop* node) {
|
||||
Visitor::Visit(node->condition);
|
||||
Visitor::Visit(node->statement);
|
||||
}
|
||||
void LinkSymbolsVisitor::Visit(ForLoop* node) {
|
||||
Visitor::Visit(node->variable);
|
||||
Visitor::Visit(node->interval);
|
||||
Visitor::Visit(node->statement);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(LoopLoop* node) {
|
||||
Visitor::Visit(node->statement);
|
||||
}
|
||||
|
||||
// Statements, expressions, blocks, etc. -----------------
|
||||
|
||||
void LinkSymbolsVisitor::Visit(Block* node) {
|
||||
for (auto& statement : node->statements) {
|
||||
Visitor::Visit(statement);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ScopedStatement* node) {
|
||||
Visitor::Visit(node->statement);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(LoopControlExpression& node) {}
|
||||
|
||||
// Operators
|
||||
|
||||
void LinkSymbolsVisitor::Visit(BinaryOperatorExpression* node) {
|
||||
Visitor::Visit(node->left_expression);
|
||||
Visitor::Visit(node->right_expression);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(UnaryOperatorExpression* node) {
|
||||
Visitor::Visit(node->expression);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ReferenceExpression* node) {
|
||||
Visit(node->expression.get());
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(AccessExpression* node) {
|
||||
Visitor::Visit(node->name.get());
|
||||
Visitor::Visit(node->id);
|
||||
}
|
||||
|
||||
// Other Expressions
|
||||
|
||||
void LinkSymbolsVisitor::Visit(FunctionCallExpression* node) {
|
||||
Visit(node->name.get());
|
||||
for (auto& argument : node->arguments) {
|
||||
Visitor::Visit(argument);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TupleExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(VariantExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ReturnExpression* node) {
|
||||
Visitor::Visit(node->expression);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeConstructor* node) {
|
||||
Visit(node->type.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visitor::Visit(std::get<2>(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move to find_symbols_visitor
|
||||
void LinkSymbolsVisitor::Visit(LambdaFunction* node) {
|
||||
abstract_types_.EnterContext();
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
Visitor::Visit(parameter.get());
|
||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||
}
|
||||
|
||||
////////////
|
||||
node->argument_graph_ids_.resize(node->arguments.size());
|
||||
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
||||
node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
|
||||
}
|
||||
|
||||
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
|
||||
///////////
|
||||
|
||||
Visitor::Visit(node->expression);
|
||||
abstract_types_.ExitContext();
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ArrayExpression* node) {
|
||||
for (auto& element : node->elements) {
|
||||
Visitor::Visit(element);
|
||||
}
|
||||
}
|
||||
|
||||
// Name
|
||||
|
||||
void LinkSymbolsVisitor::Visit(NameExpression* node) {
|
||||
for (auto& variable_namespace : node->namespaces) {
|
||||
Visitor::Visit(variable_namespace);
|
||||
}
|
||||
// for (auto& expression : node->expressions) {
|
||||
// Visit(expression);
|
||||
// }
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TupleName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visitor::Visit(name);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(VariantName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visitor::Visit(name);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(AnnotatedName* node) {
|
||||
if (node->type.has_value()) {
|
||||
Visitor::Visit(node->type.value());
|
||||
}
|
||||
}
|
||||
|
||||
// Type, typeclass, etc. -----------------
|
||||
|
||||
// Type
|
||||
|
||||
void LinkSymbolsVisitor::Visit(FunctionType* node) {
|
||||
for (auto& type : node->types) {
|
||||
Visitor::Visit(type);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TupleType* node) {
|
||||
for (auto& entity : node->entities) {
|
||||
Visit(entity.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(VariantType* node) {
|
||||
for (auto& constructor : node->constructors) {
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
// do nothing
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ParametrizedType* node) {
|
||||
Visit(node->type_expression.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visitor::Visit(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeExpression* node) {
|
||||
std::vector<std::string> path;
|
||||
path.reserve(node->namespaces.size());
|
||||
|
|
@ -361,19 +191,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) {
|
|||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ExtendedScopedAnyType* node) {
|
||||
Visitor::Visit(node->type);
|
||||
}
|
||||
|
||||
// Typeclass
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
|
||||
Visit(node->typeclass_expression.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visitor::Visit(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeclassExpression* node) {
|
||||
std::vector<std::string> path;
|
||||
path.reserve(node->namespaces.size());
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ void PrintVisitor::Visit(AnyAnnotatedType* node) {
|
|||
out_ << "[Annotated (Abstract) Type ";
|
||||
Visit(&node->type);
|
||||
out_ << ']';
|
||||
if (!node->typeclasses.empty() > 0) {
|
||||
if (!node->typeclasses.empty()) {
|
||||
out_ << " (";
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
Visitor::Visit(typeclass);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
#include "../include/type_check_visitor.hpp"
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
// for clangd
|
||||
#include "../include/type_check_visitor.hpp"
|
||||
#include "../include/error_handling.hpp"
|
||||
|
||||
// TODO
|
||||
|
||||
|
|
@ -17,26 +21,30 @@ void TypeCheckVisitor::Visit(SourceFile* node) {
|
|||
// error
|
||||
}
|
||||
}
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Sources* node) {
|
||||
for (auto& statement : node->statements) {
|
||||
Visitor::Visit(statement);
|
||||
}
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// Namespaces, partitions -----------------
|
||||
|
||||
void TypeCheckVisitor::Visit(Partition* node) {
|
||||
Visit(node->scope.get());
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Namespace* node) {
|
||||
if (node->name.has_value()) {
|
||||
// TODO: add modifiers
|
||||
node->variable_type_ = info::type::Type {info::type::DefinedType {node->type_id_.value()}};
|
||||
context_manager_.EnterVariableContext(node->name.value().name,
|
||||
&node->variable_type_.value());
|
||||
context_manager_.AddType(info::type::DefinedType {node->type_id_.value()}));
|
||||
}
|
||||
|
||||
namespace_visitor_.EnterNamespace(node->type);
|
||||
|
|
@ -44,6 +52,8 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
|||
Visit(node->scope.get());
|
||||
|
||||
namespace_visitor_.ExitNamespace();
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// Definitions -----------------
|
||||
|
|
@ -51,364 +61,520 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
|||
void TypeCheckVisitor::Visit(ImportStatement* node) {}
|
||||
|
||||
void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
|
||||
// TODO check, that all paramaters used
|
||||
// check, that all paramaters used ??
|
||||
utils::IdType type = context_manager_.AddType(info::type::DefinedType {node->type_id_}); // ??
|
||||
|
||||
Visit(node->value.get());
|
||||
context_manager_.EqualTypes(type, current_type_);
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
|
||||
// TODO: remove variable on move
|
||||
// TODO: add modifiers
|
||||
Visitor::Visit(node->value);
|
||||
// current_type from value automatically passed to name definitions
|
||||
Visitor::Visit(node->name);
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
||||
// later check, that function definition requirements are satisfied
|
||||
// check later that function definition requirements are satisfied
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
// check, that all paramaters used ??
|
||||
context_manager_.EnterContext();
|
||||
|
||||
// Visit(node->definition.get()); // ??
|
||||
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
||||
context_manager_.DefineVariable(node->definition->arguments[i].name,
|
||||
context_manager_.AddType(info::type::AbstractType { node->argument_graph_ids_[i] }));
|
||||
}
|
||||
|
||||
Visitor::Visit(node->value);
|
||||
context_manager_.EqualTypes(
|
||||
context_manager_.AddType(info::type::AbstractType { node->return_type_graph_id_ }), current_type_);
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
|
||||
switch (node->modifier) {
|
||||
case TypeDefinitionStatement::Struct:
|
||||
break;
|
||||
case TypeDefinitionStatement::Class:
|
||||
break;
|
||||
}
|
||||
Visit(node->definition.get());
|
||||
Visitor::Visit(node->value);
|
||||
// TODO: add modifiers
|
||||
// check, that all paramaters used ??
|
||||
// TODO: defined type typeclasses
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
switch (node->modifier) {
|
||||
case AbstractTypeDefinitionStatement::Basic:
|
||||
break;
|
||||
case AbstractTypeDefinitionStatement::Abstract:
|
||||
break;
|
||||
utils::IdType type = context_manager_.AddType(info::type::AbstractType {node->type_graph_id_} );
|
||||
|
||||
// Visit(node->type.get()); ??
|
||||
for (auto& typeclass : node->type->typeclasses) { // TODO
|
||||
Visitor::Visit(typeclass);
|
||||
context_manager_.AddTypeRequirement(type, current_type_);
|
||||
}
|
||||
Visit(node->type.get());
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
if (!node->requirements.empty()) {
|
||||
}
|
||||
for (auto& requirement : node->requirements) {
|
||||
Visit(requirement.get());
|
||||
}
|
||||
// check, that all paramaters used ??
|
||||
// TODO: needed ??
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// Definition parts
|
||||
|
||||
void TypeCheckVisitor::Visit(FunctionDefinition* node) {
|
||||
switch (node->modifier) {
|
||||
case FunctionDefinition::Operator:
|
||||
break;
|
||||
case FunctionDefinition::Function:
|
||||
break;
|
||||
}
|
||||
Visit(&node->name);
|
||||
if (!node->parameters.empty()) {
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
}
|
||||
if (!node->arguments.empty()) {
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(&argument);
|
||||
}
|
||||
}
|
||||
// TODO: needed ??
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TypeDefinition* node) {
|
||||
Visit(node->type.get());
|
||||
if (!node->parameters.empty()) {
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
}
|
||||
// TODO: needed ??
|
||||
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// used on upper levels
|
||||
void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
|
||||
Visit(&node->type);
|
||||
if (!node->typeclasses.empty() > 0) {
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
Visitor::Visit(typeclass);
|
||||
}
|
||||
}
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// Flow control -----------------
|
||||
|
||||
void TypeCheckVisitor::Visit(MatchCase* node) {
|
||||
Visitor::Visit(node->value);
|
||||
Visitor::Visit(node->value); // TODO: literal & name instead of expression
|
||||
if (node->condition.has_value()) {
|
||||
Visitor::Visit(node->condition.value());
|
||||
}
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||
|
||||
if (node->statement.has_value()) {
|
||||
Visitor::Visit(node->statement.value());
|
||||
}
|
||||
// current_type_ from statement is current_type_ for MatchCase
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Match* node) {
|
||||
void TypeCheckVisitor::Visit(Match* node) { // TODO return variant type ?? (problems with same types)
|
||||
// TODO: types can be different in statement
|
||||
utils::IdType type;
|
||||
|
||||
Visitor::Visit(node->value);
|
||||
for (auto& match_case : node->matches) {
|
||||
Visit(&match_case);
|
||||
for (size_t i = 0; i < node->matches.size(); ++i) {
|
||||
Visit(&node->matches[i]);
|
||||
if (i == 0) {
|
||||
type = current_type_;
|
||||
} else {
|
||||
context_manager_.EqualTypes(type, current_type_);
|
||||
}
|
||||
}
|
||||
|
||||
current_type_ = type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Condition* node) {
|
||||
Visitor::Visit(node->conditions[0]);
|
||||
Visitor::Visit(node->statements[0]);
|
||||
for (size_t i = 1; i < node->conditions.size(); ++i) {
|
||||
void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant type ?? (problem with same types)
|
||||
// TODO: types can be different in statement
|
||||
utils::IdType type;
|
||||
|
||||
for (size_t i = 0; i < node->conditions.size(); ++i) {
|
||||
Visitor::Visit(node->conditions[i]);
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||
|
||||
Visitor::Visit(node->statements[i]);
|
||||
if (i == 0) {
|
||||
type = current_type_;
|
||||
} else {
|
||||
context_manager_.EqualTypes(type, current_type_);
|
||||
}
|
||||
}
|
||||
|
||||
if (node->statements.size() > node->conditions.size()) {
|
||||
Visitor::Visit(node->statements[node->conditions.size()]);
|
||||
context_manager_.EqualTypes(type, current_type_);
|
||||
current_type_ = type;
|
||||
} else {
|
||||
current_type_ = context_manager_.AddType(info::type::OptionalType {type});
|
||||
}
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
|
||||
out_ << "[Do] (\n";
|
||||
Visitor::Visit(node->statement);
|
||||
out_ << ") [while] (";
|
||||
Visitor::Visit(node->condition);
|
||||
out_ << ")\n";
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||
|
||||
Visitor::Visit(node->statement);
|
||||
|
||||
info::type::ArrayType type;
|
||||
type.size = 0;
|
||||
type.elements_type = current_type_;
|
||||
current_type_ = context_manager_.AddType(type);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(WhileLoop* node) {
|
||||
out_ << "[While] (";
|
||||
Visitor::Visit(node->statement);
|
||||
out_ << ") [do] (\n";
|
||||
Visitor::Visit(node->condition);
|
||||
out_ << ")\n";
|
||||
}
|
||||
void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||
out_ << "[For] (";
|
||||
Visitor::Visit(node->variable);
|
||||
out_ << ") [in] (";
|
||||
Visitor::Visit(node->interval);
|
||||
out_ << ") [do] (\n";
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||
|
||||
Visitor::Visit(node->statement);
|
||||
out_ << ")\n";
|
||||
|
||||
info::type::ArrayType type;
|
||||
type.size = 0;
|
||||
type.elements_type = current_type_;
|
||||
current_type_ = context_manager_.AddType(type);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||
Visitor::Visit(node->interval);
|
||||
|
||||
if (!std::holds_alternative<info::type::ArrayType>(context_manager_.GetType(current_type_))) {
|
||||
error_handling::HandleTypecheckError("For loop interval type mismatch");
|
||||
}
|
||||
|
||||
info::type::ArrayType type_value =
|
||||
std::get<info::type::ArrayType>(context_manager_.GetType(current_type_));
|
||||
|
||||
current_type_ = context_manager_.AddType(type_value.elements_type);
|
||||
Visitor::Visit(node->variable);
|
||||
|
||||
Visitor::Visit(node->statement);
|
||||
|
||||
info::type::ArrayType type;
|
||||
type.size = 0;
|
||||
type.elements_type = current_type_;
|
||||
current_type_ = context_manager_.AddType(type);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(LoopLoop* node) {
|
||||
out_ << "[Loop] (\n";
|
||||
Visitor::Visit(node->statement);
|
||||
out_ << ")\n";
|
||||
|
||||
info::type::ArrayType type;
|
||||
type.size = 0;
|
||||
type.elements_type = current_type_;
|
||||
current_type_ = context_manager_.AddType(type);
|
||||
}
|
||||
|
||||
// Statements, expressions, blocks, etc. -----------------
|
||||
|
||||
void TypeCheckVisitor::Visit(Block* node) {
|
||||
out_ << "[Block] {\n";
|
||||
void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (problem with same types)
|
||||
utils::IdType type;
|
||||
|
||||
bool is_first_returned_type = true;
|
||||
|
||||
for (auto& statement : node->statements) {
|
||||
returned_type_ = std::nullopt;
|
||||
Visitor::Visit(statement);
|
||||
if (returned_type_.has_value()) {
|
||||
if (is_first_returned_type) {
|
||||
type = returned_type_.value();
|
||||
is_first_returned_type = false;
|
||||
} else {
|
||||
context_manager_.EqualTypes(type, returned_type_.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
out_ << "}\n";
|
||||
|
||||
if (is_first_returned_type) {
|
||||
type = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
current_type_ = type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ScopedStatement* node) {
|
||||
out_ << "[Scoped] ( ";
|
||||
Visitor::Visit(node->statement);
|
||||
out_ << ")\n";
|
||||
// current_type_ is type of statement
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
||||
switch (node) {
|
||||
case LoopControlExpression::Break:
|
||||
out_ << "[Break]\n";
|
||||
break;
|
||||
case LoopControlExpression::Continue:
|
||||
out_ << "[Continue]\n";
|
||||
break;
|
||||
}
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
// Operators
|
||||
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
||||
out_ << "[BinaryOperator] (";
|
||||
Visitor::Visit(node->left_expression);
|
||||
out_ << ") [";
|
||||
Visit(&node->operator_name);
|
||||
out_ << "] (";
|
||||
Visitor::Visit(node->right_expression);
|
||||
out_ << ')';
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
|
||||
|
||||
if (!maybe_operator_id.has_value()) {
|
||||
error_handling::HandleTypecheckError("Operator not found");
|
||||
}
|
||||
|
||||
auto operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||
|
||||
if (operator_info->argument_count != 2) {
|
||||
error_handling::HandleTypecheckError("Operator wrong argument count");
|
||||
}
|
||||
|
||||
if (operator_info->definition.has_value()) {
|
||||
Visitor::Visit(node->left_expression);
|
||||
context_manager_.AddTypeRequirement(current_type_,
|
||||
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[0]}));
|
||||
|
||||
Visitor::Visit(node->right_expression);
|
||||
context_manager_.AddTypeRequirement(current_type_,
|
||||
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[1]}));
|
||||
} else if (operator_info->declaration.has_value()) {
|
||||
// TODO: get argument types
|
||||
} else {
|
||||
error_handling::HandleInternalError("Operator definition and declaration both not found", "TypeCheckVisitor");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
||||
out_ << "[UnaryOperator ";
|
||||
Visit(&node->operator_name);
|
||||
out_ << "] (";
|
||||
Visitor::Visit(node->expression);
|
||||
out_ << ')';
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
|
||||
|
||||
if (!maybe_operator_id.has_value()) {
|
||||
error_handling::HandleTypecheckError("Operator not found");
|
||||
}
|
||||
|
||||
auto operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
|
||||
|
||||
if (operator_info->argument_count != 1) {
|
||||
error_handling::HandleTypecheckError("Operator wrong argument count");
|
||||
}
|
||||
|
||||
if (operator_info->definition.has_value()) {
|
||||
Visitor::Visit(node->expression);
|
||||
context_manager_.AddTypeRequirement(current_type_,
|
||||
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[0]}));
|
||||
} else if (operator_info->declaration.has_value()) {
|
||||
// TODO: get argument type
|
||||
} else {
|
||||
error_handling::HandleInternalError("Operator definition and declaration both not found", "TypeCheckVisitor");
|
||||
}
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
||||
out_ << "[ReferenceExpression ";
|
||||
for (auto& reference : node->references) {
|
||||
switch (reference) {
|
||||
case ReferenceType::Reference:
|
||||
out_ << '~';
|
||||
break;
|
||||
case ReferenceType::UniqueReference:
|
||||
out_ << '@';
|
||||
break;
|
||||
}
|
||||
}
|
||||
out_ << "] (";
|
||||
Visit(node->expression.get());
|
||||
out_ << ')';
|
||||
|
||||
info::type::ReferenceToType type;
|
||||
type.references = node->references;
|
||||
type.type = current_type_;
|
||||
current_type_ = context_manager_.AddType(type);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(AccessExpression* node) { // TODO
|
||||
Visitor::Visit(node->name);
|
||||
void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||
Visitor::Visit(node->id);
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Int), current_type_);
|
||||
// TODO: separate type for counting ?
|
||||
|
||||
Visitor::Visit(node->name.get());
|
||||
if (!std::holds_alternative<info::type::ArrayType>(context_manager_.GetType(current_type_))) {
|
||||
error_handling::HandleTypecheckError("Access type mismatch");
|
||||
}
|
||||
|
||||
info::type::ArrayType type_value =
|
||||
std::get<info::type::ArrayType>(context_manager_.GetType(current_type_));
|
||||
|
||||
current_type_ = context_manager_.AddType(type_value.elements_type);
|
||||
}
|
||||
|
||||
// Other Expressions
|
||||
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||
out_ << "[FunctionCall ";
|
||||
// TODO: add function paramaters
|
||||
Visit(node->name.get());
|
||||
out_ << "] (";
|
||||
for (auto& argument : node->arguments) {
|
||||
Visitor::Visit(argument);
|
||||
out_ << ", ";
|
||||
}
|
||||
out_ << ")";
|
||||
|
||||
if (!std::holds_alternative<info::type::FunctionType>(context_manager_.GetType(current_type_))) {
|
||||
error_handling::HandleTypecheckError("Mismatched types in function call expression");
|
||||
}
|
||||
|
||||
info::type::FunctionType type_value = std::get<info::type::FunctionType>(context_manager_.GetType(current_type_));
|
||||
|
||||
if (type_value.argument_types.size() != node->arguments.size()) {
|
||||
error_handling::HandleTypecheckError("Mismatched argument count in function call expression");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
if (std::holds_alternative<std::string>(node->arguments[i])) {
|
||||
} else if (std::holds_alternative<info::type::TupleType>(node->arguments[i])) {
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
context_manager_.AddTypeRequirement(current_type_, type_value.argument_types[i]);
|
||||
}
|
||||
|
||||
current_type_ = type_value.return_type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TupleExpression* node) {
|
||||
out_ << "[TupleExpression] (";
|
||||
info::type::TupleType type;
|
||||
|
||||
type.fields.reserve(node->expressions.size());
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "&";
|
||||
Visitor::Visit(expression);
|
||||
type.fields.push_back({std::nullopt, current_type_});
|
||||
}
|
||||
out_ << ")";
|
||||
|
||||
current_type_ = context_manager_.AddType(std::move(type));
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||
out_ << "[VariantExpression] (";
|
||||
info::type::VariantType type;
|
||||
|
||||
for (auto& expression : node->expressions) {
|
||||
out_ << "|";
|
||||
info::type::TupleType constructor;
|
||||
|
||||
Visitor::Visit(expression);
|
||||
|
||||
constructor.fields.push_back({std::nullopt, current_type_}); // ??
|
||||
type.constructors.push_back(constructor);
|
||||
}
|
||||
out_ << ")";
|
||||
|
||||
current_type_ = context_manager_.AddType(std::move(type));
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ReturnExpression* node) {
|
||||
Visitor::Visit(node->expression);
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
||||
out_ << "[TypeConstructor ";
|
||||
Visit(node->type.get());
|
||||
out_ << "]\n(";
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor names, etc.
|
||||
utils::IdType type;
|
||||
|
||||
bool is_first = true;
|
||||
for (auto& parameter : node->parameters) {
|
||||
if (!is_first) {
|
||||
out_ << ")\n";
|
||||
is_first = false;
|
||||
}
|
||||
out_ << '(';
|
||||
Visit(&std::get<0>(parameter));
|
||||
switch (std::get<1>(parameter)) {
|
||||
case TypeConstructor::Assign:
|
||||
out_ << " = ";
|
||||
break;
|
||||
case TypeConstructor::Move:
|
||||
out_ << " <- ";
|
||||
break;
|
||||
}
|
||||
Visitor::Visit(std::get<2>(parameter));
|
||||
Visit(node->type.get());
|
||||
type = current_type_;
|
||||
|
||||
info::AnyTypeInfo* type_info = &std::get<info::AnyTypeInfo>(
|
||||
namespace_visitor_.GetGlobalInfo()->GetTypeInfo(
|
||||
std::get<info::type::DefinedType>(context_manager_.GetType(type)).type_id)->type);
|
||||
|
||||
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
||||
//Visit(&std::get<0>(parameter));
|
||||
// TODO: remove variable on move
|
||||
Visitor::Visit(std::get<2>(node->parameters[i]));
|
||||
//context_manager_.EqualTypes(/* TODO type_info->get_field(paramater).type */, current_type_);
|
||||
}
|
||||
out_ << ")\n";
|
||||
|
||||
current_type_ = type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(LambdaFunction* node) {
|
||||
out_ << "[LambdaFunction] (";
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
info::type::FunctionType type;
|
||||
|
||||
// for (auto& parameter : node->parameters) {
|
||||
// Visit(parameter.get());
|
||||
// }
|
||||
|
||||
type.argument_types.reserve(node->argument_graph_ids_.size());
|
||||
for (auto& argument_graph_id : node->argument_graph_ids_) {
|
||||
type.argument_types.push_back(context_manager_.AddType(info::type::AbstractType {argument_graph_id}));
|
||||
}
|
||||
if (!node->parameters.empty()) {
|
||||
out_ << ") : (";
|
||||
}
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(&argument);
|
||||
}
|
||||
out_ << ") -> (\n";
|
||||
|
||||
type.return_type = context_manager_.AddType(info::type::AbstractType {node->return_type_graph_id_});
|
||||
|
||||
Visitor::Visit(node->expression);
|
||||
out_ << ")\n";
|
||||
context_manager_.AddTypeRequirement(type.return_type, current_type_); // right order ??
|
||||
|
||||
current_type_ = context_manager_.AddType(std::move(type));
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ArrayExpression* node) {
|
||||
out_ << "[ArrayExpression] ([";
|
||||
for (auto& element : node->elements) {
|
||||
Visitor::Visit(element);
|
||||
out_ << ';';
|
||||
info::type::ArrayType type;
|
||||
|
||||
type.size = node->elements.size();
|
||||
|
||||
for (size_t i = 0; i < node->elements.size(); ++i) {
|
||||
Visitor::Visit(node->elements[i]);
|
||||
if (i == 0) {
|
||||
type.elements_type = current_type_;
|
||||
} else {
|
||||
context_manager_.EqualTypes(type.elements_type.value(), current_type_);
|
||||
}
|
||||
}
|
||||
out_ << "])";
|
||||
|
||||
current_type_ = context_manager_.AddType(std::move(type));
|
||||
}
|
||||
|
||||
// Name
|
||||
|
||||
void TypeCheckVisitor::Visit(NameExpression* node) {
|
||||
out_ << "[NameExpression] (";
|
||||
for (auto& variable_namespace : node->namespaces) {
|
||||
Visitor::Visit(variable_namespace);
|
||||
out_ << '.';
|
||||
}
|
||||
for (size_t i = 0; i < node->expressions.size(); ++i) {
|
||||
Visitor::Visit(node->expressions[i]);
|
||||
if (i + 1 < node->expressions.size()) {
|
||||
out_ << '.';
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(NameExpression* node) { // TODO: ?? functions without arguments ??
|
||||
std::vector<std::string> path;
|
||||
std::string type_name;
|
||||
|
||||
path.reserve(node->namespaces.size());
|
||||
for (size_t i = 0; i < node->namespaces.size(); ++i) {
|
||||
std::string current_name;
|
||||
if (std::holds_alternative<std::unique_ptr<std::string>>(node->namespaces[i])) {
|
||||
current_name = *std::get<std::unique_ptr<std::string>>(node->namespaces[i]);
|
||||
} else if (std::holds_alternative<std::unique_ptr<ParametrizedType>>(node->namespaces[i])) {
|
||||
Visit(std::get<std::unique_ptr<ParametrizedType>>(node->namespaces[i]).get());
|
||||
// TODO: use current_type_
|
||||
}
|
||||
if (i + 1 == node->namespaces.size()) {
|
||||
type_name = std::move(current_name);
|
||||
} else {
|
||||
path.push_back(std::move(current_name));
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
||||
// auto name_type = namespace_visitor_.FindType();
|
||||
path.push_back(type_name);
|
||||
auto name_namespace = namespace_visitor_.FindNamespace(path);
|
||||
|
||||
for (size_t i = 0; i < node->expressions.size(); ++i) {
|
||||
// Visitor::Visit(node->expressions[i]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TupleName* node) {
|
||||
utils::IdType type = current_type_;
|
||||
|
||||
auto type_value = std::get_if<info::type::TupleType>(context_manager_.GetType(type));
|
||||
|
||||
if (type_value = nullptr) {
|
||||
if (!std::holds_alternative<info::type::TupleType>(context_manager_.GetType(type))) {
|
||||
error_handling::HandleTypecheckError("Mismatched types in tuple variable definition");
|
||||
}
|
||||
|
||||
if (type_value->constructors.size() != node->names.size()) {
|
||||
info::type::TupleType type_value = std::get<info::type::TupleType>(context_manager_.GetType(type));
|
||||
|
||||
if (type_value.fields.size() != node->names.size()) {
|
||||
error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition");
|
||||
}
|
||||
for (auto& name : node->names) {
|
||||
current_type_ = type_value->fields[i];
|
||||
Visitor::Visit(name);
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
current_type_ = type_value.fields[i].second;
|
||||
Visitor::Visit(node->names[i]);
|
||||
}
|
||||
|
||||
current_type_ = type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(VariantName* node) { // TODO
|
||||
void TypeCheckVisitor::Visit(VariantName* node) {
|
||||
utils::IdType type = current_type_;
|
||||
|
||||
auto type_value = std::get_if<info::type::VariantType>(context_manager_.GetType(type));
|
||||
|
||||
if (type_value = nullptr) {
|
||||
if (!std::holds_alternative<info::type::VariantType>(context_manager_.GetType(type))) {
|
||||
error_handling::HandleTypecheckError("Mismatched types in variant variable definition");
|
||||
}
|
||||
|
||||
if (type_value->constructors.size() != node->names.size()) {
|
||||
info::type::VariantType type_value = std::get<info::type::VariantType>(context_manager_.GetType(type));
|
||||
|
||||
if (type_value.constructors.size() != node->names.size()) {
|
||||
error_handling::HandleTypecheckError("Mismatched variant count in variant variable definition");
|
||||
}
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
current_type_ = info::type::VariantType::MakeOptional(type_value->constructors[i]);
|
||||
Visitor::Visit(name);
|
||||
if (std::holds_alternative<std::string>(type_value.constructors[i])) {
|
||||
current_type_ = context_manager_.AddType(info::type::OptionalType {});
|
||||
} else if (std::holds_alternative<info::type::TupleType>(type_value.constructors[i])) {
|
||||
// TODO: optimize
|
||||
current_type_ = context_manager_.AddType(info::type::OptionalType { context_manager_.AddType(std::get<info::type::TupleType>(type_value.constructors[i])) });
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
||||
Visitor::Visit(node->names[i]);
|
||||
}
|
||||
|
||||
current_type_ = type;
|
||||
|
|
@ -428,9 +594,9 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
|
|||
void TypeCheckVisitor::Visit(FunctionType* node) {
|
||||
info::type::FunctionType type;
|
||||
|
||||
type.argument_type_ids.reserve(node->types.size());
|
||||
for (auto& type : node->types) {
|
||||
Visitor::Visit(type);
|
||||
type.argument_types.reserve(node->types.size());
|
||||
for (auto& argument_type : node->types) {
|
||||
Visitor::Visit(argument_type);
|
||||
type.argument_types.push_back(current_type_);
|
||||
}
|
||||
|
||||
|
|
@ -474,8 +640,7 @@ void TypeCheckVisitor::Visit(VariantType* node) {
|
|||
void TypeCheckVisitor::Visit(ParametrizedType* node) {
|
||||
info::type::DefinedType type;
|
||||
|
||||
Visit(node->type_expression.get());
|
||||
type.type = current_type_;
|
||||
type.type_id = node->type_expression->type_id_;
|
||||
|
||||
type.paramaters.reserve(node->parameters.size());
|
||||
for (auto& paramater : node->parameters) {
|
||||
|
|
|
|||
359
src/visitor.cpp
359
src/visitor.cpp
|
|
@ -319,4 +319,363 @@ void Visitor::Visit(Literal& node) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Sources -----------------
|
||||
|
||||
void Visitor::Visit(SourceFile* node) {
|
||||
for (auto& statement : node->statements) {
|
||||
if (std::holds_alternative<Partition>(statement)) {
|
||||
Visit(&std::get<Partition>(statement));
|
||||
} else if (std::holds_alternative<SourceStatement>(statement)) {
|
||||
Visit(std::get<SourceStatement>(statement));
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(Sources* node) {
|
||||
for (auto& statement : node->statements) {
|
||||
Visit(statement);
|
||||
}
|
||||
}
|
||||
|
||||
// Namespaces, partitions -----------------
|
||||
|
||||
void Visitor::Visit(Partition* node) {
|
||||
Visit(node->scope.get());
|
||||
}
|
||||
|
||||
void Visitor::Visit(Namespace* node) {
|
||||
if (node->name.has_value()) {
|
||||
Visit(&node->name.value());
|
||||
}
|
||||
Visit(&node->type);
|
||||
Visit(node->scope.get());
|
||||
}
|
||||
|
||||
// Definitions -----------------
|
||||
|
||||
void Visitor::Visit(ImportStatement* node) {
|
||||
for (auto& symbol : node->symbols) {
|
||||
Visit(&symbol);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(AliasDefinitionStatement* node) {
|
||||
Visit(&node->type);
|
||||
Visit(node->value.get());
|
||||
}
|
||||
|
||||
void Visitor::Visit(VariableDefinitionStatement* node) {
|
||||
Visit(node->name);
|
||||
Visit(node->value);
|
||||
}
|
||||
|
||||
void Visitor::Visit(FunctionDeclaration* node) {
|
||||
Visit(&node->name);
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
Visit(node->type.get());
|
||||
}
|
||||
|
||||
void Visitor::Visit(FunctionDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
Visit(node->value);
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
Visit(node->value);
|
||||
}
|
||||
|
||||
void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
Visit(node->type.get());
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
for (auto& requirement : node->requirements) {
|
||||
Visit(requirement.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Definition parts
|
||||
|
||||
void Visitor::Visit(FunctionDefinition* node) {
|
||||
Visit(&node->name);
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(&argument);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeDefinition* node) {
|
||||
Visit(node->type.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(AnyAnnotatedType* node) {
|
||||
Visit(&node->type);
|
||||
for (auto& typeclass : node->typeclasses) {
|
||||
Visit(typeclass);
|
||||
}
|
||||
}
|
||||
|
||||
// Flow control -----------------
|
||||
|
||||
void Visitor::Visit(MatchCase* node) {
|
||||
Visit(node->value);
|
||||
if (node->condition.has_value()) {
|
||||
Visit(node->condition.value());
|
||||
}
|
||||
if (node->statement.has_value()) {
|
||||
Visit(node->statement.value());
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(Match* node) {
|
||||
Visit(node->value);
|
||||
for (auto& match_case : node->matches) {
|
||||
Visit(&match_case);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(Condition* node) {
|
||||
for (size_t i = 0; i < node->conditions.size(); ++i) {
|
||||
Visit(node->conditions[i]);
|
||||
Visit(node->statements[i]);
|
||||
}
|
||||
if (node->statements.size() > node->conditions.size()) {
|
||||
Visit(node->statements[node->conditions.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(DoWhileLoop* node) {
|
||||
Visit(node->statement);
|
||||
Visit(node->condition);
|
||||
}
|
||||
|
||||
void Visitor::Visit(WhileLoop* node) {
|
||||
Visit(node->condition);
|
||||
Visit(node->statement);
|
||||
}
|
||||
void Visitor::Visit(ForLoop* node) {
|
||||
Visit(node->variable);
|
||||
Visit(node->interval);
|
||||
Visit(node->statement);
|
||||
}
|
||||
|
||||
void Visitor::Visit(LoopLoop* node) {
|
||||
Visit(node->statement);
|
||||
}
|
||||
|
||||
// Statements, expressions, blocks, etc. -----------------
|
||||
|
||||
void Visitor::Visit(Block* node) {
|
||||
for (auto& statement : node->statements) {
|
||||
Visit(statement);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(ScopedStatement* node) {
|
||||
Visit(node->statement);
|
||||
}
|
||||
|
||||
void Visitor::Visit(LoopControlExpression& node) {} // enum
|
||||
|
||||
// Operators
|
||||
|
||||
void Visitor::Visit(BinaryOperatorExpression* node) {
|
||||
Visit(node->left_expression);
|
||||
Visit(&node->operator_name);
|
||||
Visit(node->right_expression);
|
||||
}
|
||||
|
||||
void Visitor::Visit(UnaryOperatorExpression* node) {
|
||||
Visit(&node->operator_name);
|
||||
Visit(node->expression);
|
||||
}
|
||||
|
||||
void Visitor::Visit(ReferenceExpression* node) {
|
||||
Visit(node->expression.get());
|
||||
}
|
||||
|
||||
void Visitor::Visit(AccessExpression* node) {
|
||||
Visit(node->name.get());
|
||||
Visit(node->id);
|
||||
}
|
||||
|
||||
// Other Expressions
|
||||
|
||||
void Visitor::Visit(FunctionCallExpression* node) {
|
||||
Visit(node->name.get());
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(argument);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TupleExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(VariantExpression* node) {
|
||||
for (auto& expression : node->expressions) {
|
||||
Visit(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(ReturnExpression* node) {
|
||||
Visit(node->expression);
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeConstructor* node) {
|
||||
Visit(node->type.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(&std::get<0>(parameter));
|
||||
Visit(std::get<2>(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(LambdaFunction* node) {
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
}
|
||||
for (auto& argument : node->arguments) {
|
||||
Visit(&argument);
|
||||
}
|
||||
Visit(node->expression);
|
||||
}
|
||||
|
||||
void Visitor::Visit(ArrayExpression* node) {
|
||||
for (auto& element : node->elements) {
|
||||
Visit(element);
|
||||
}
|
||||
}
|
||||
|
||||
// Name
|
||||
|
||||
void Visitor::Visit(NameExpression* node) {
|
||||
for (auto& variable_namespace : node->namespaces) {
|
||||
Visit(variable_namespace);
|
||||
}
|
||||
for (size_t i = 0; i < node->expressions.size(); ++i) {
|
||||
Visit(&node->expressions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TupleName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visit(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(VariantName* node) {
|
||||
for (auto& name : node->names) {
|
||||
Visit(name);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(AnnotatedName* node) {
|
||||
Visit(&node->name);
|
||||
if (node->type.has_value()) {
|
||||
Visitor::Visit(node->type.value());
|
||||
}
|
||||
}
|
||||
|
||||
// Type, typeclass, etc. -----------------
|
||||
|
||||
// Type
|
||||
|
||||
void Visitor::Visit(FunctionType* node) {
|
||||
for (auto& type : node->types) {
|
||||
Visitor::Visit(type);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TupleType* node) {
|
||||
if (node->type.has_value()) {
|
||||
Visit(&node->type.value());
|
||||
}
|
||||
for (auto& entity : node->entities) {
|
||||
if (entity.first.has_value()) {
|
||||
Visit(&entity.first.value());
|
||||
}
|
||||
Visit(entity.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(VariantType* node) {
|
||||
if (node->type.has_value()) {
|
||||
Visit(&node->type.value());
|
||||
}
|
||||
for (auto& constructor : node->constructors) {
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
Visit(&std::get<Constructor>(constructor));
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(ParametrizedType* node) {
|
||||
Visit(node->type_expression.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeExpression* node) {
|
||||
for (auto& type_namespace : node->namespaces) {
|
||||
Visit(type_namespace);
|
||||
}
|
||||
Visit(&node->type);
|
||||
}
|
||||
|
||||
void Visitor::Visit(ExtendedScopedAnyType* node) {
|
||||
Visit(node->type);
|
||||
}
|
||||
|
||||
// Typeclass
|
||||
|
||||
void Visitor::Visit(ParametrizedTypeclass* node) {
|
||||
Visit(node->typeclass_expression.get());
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
void Visitor::Visit(TypeclassExpression* node) {
|
||||
for (auto& typeclass_namespace : node->namespaces) {
|
||||
Visit(typeclass_namespace);
|
||||
}
|
||||
Visit(&node->typeclass);
|
||||
}
|
||||
|
||||
// Identifiers, constants, etc. -----------------
|
||||
|
||||
void Visitor::Visit(ExtendedName* node) {}
|
||||
|
||||
void Visitor::Visit(std::string* node) {} // std::string
|
||||
|
||||
void Visitor::Visit(FloatNumberLiteral* node) {}
|
||||
|
||||
void Visitor::Visit(NumberLiteral* node) {}
|
||||
|
||||
void Visitor::Visit(StringLiteral* node) {}
|
||||
|
||||
void Visitor::Visit(CharLiteral* node) {}
|
||||
|
||||
} // namespace interpreter
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue