diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index dd55f59..bead6c2 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -130,8 +130,6 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { } } - -// TODO void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { is_in_statement_ = true; @@ -193,8 +191,6 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = true; - // basic types ?? - std::vector requirements; requirements.reserve(node->type->typeclasses.size()); for (auto& typeclass : node->type->typeclasses) { @@ -215,7 +211,6 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { is_in_statement_ = true; - // check definition correctness ?? current_type_ = context_manager_.AddType(info::type::InternalType::Unit); is_in_statement_ = false; @@ -224,27 +219,27 @@ void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { // Definition parts void TypeCheckVisitor::Visit(FunctionDefinition* node) { - // check definition correctness ?? current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } void TypeCheckVisitor::Visit(TypeDefinition* node) { - // check definition correctness ?? current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } void TypeCheckVisitor::Visit(AnyAnnotatedType* node) { - // check definition correctness ?? current_type_ = context_manager_.AddType(info::type::InternalType::Unit); } // Flow control ----------------- +// TODO <----- | current position | + // TODO void Visitor::Visit(TypeConstructorPatternParameter* node) { if (node->name.has_value()) { Visit(&node->name.value()); } + node-> Visit(node->value); } @@ -257,11 +252,17 @@ void Visitor::Visit(TypeConstructorPattern* node) { } void TypeCheckVisitor::Visit(MatchCase* node) { - Visitor::Visit(node->value); // TODO: literal & name instead of expression + // value type passed as current_type_ + is_const_definition_ = true; // TODO: or var?? + Visitor::Visit(node->value); + is_const_definition_ = std::nullopt; + if (node->condition.has_value()) { Visitor::Visit(node->condition.value()); } - context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_); + if (!context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_)) { + error_handling::HandleTypecheckError("Match case condition is not bool expression", node->base); + } if (node->statement.has_value()) { Visitor::Visit(node->statement.value()); @@ -270,17 +271,34 @@ void TypeCheckVisitor::Visit(MatchCase* node) { } void TypeCheckVisitor::Visit(Match* node) { // TODO return variant type ?? (problems with same types) - // TODO: types can be different in statement + // TODO: types can be different in block statement utils::IdType type; + bool is_type_found = false; + Visitor::Visit(node->value); + utils::IdType value_type = current_type_; + for (size_t i = 0; i < node->matches.size(); ++i) { + current_type_ = value_type; Visit(&node->matches[i]); - if (i == 0) { - type = current_type_; - } else { - context_manager_.EqualTypes(type, current_type_); + + if (!node->matches[i].statement.has_value()) { + continue; } + + if (!is_type_found) { + type = current_type_; + is_type_found = true; + } else { + if (!context_manager_.EqualTypes(type, current_type_)) { + error_handling::HandleTypecheckError("Match statement cases have different types", node->base); + } + } + } + + if (!is_type_found) { + type = context_manager_.AddType(info::type::InternalType::Unit); } current_type_ = type; @@ -292,19 +310,25 @@ void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant 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_); + if (!context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_)) { + error_handling::HandleTypecheckError("Condition statement condition is not bool expression", node->base); + } Visitor::Visit(node->statements[i]); if (i == 0) { type = current_type_; } else { - context_manager_.EqualTypes(type, current_type_); + if (!context_manager_.EqualTypes(type, current_type_)) { + error_handling::HandleTypecheckError("Condition statement cases have different types", node->base); + } } } if (node->statements.size() > node->conditions.size()) { Visitor::Visit(node->statements[node->conditions.size()]); - context_manager_.EqualTypes(type, current_type_); + if (!context_manager_.EqualTypes(type, current_type_)) { + error_handling::HandleTypecheckError("Condition statement else have different type from other cases", node->base); + } current_type_ = type; } else { current_type_ = context_manager_.AddType( @@ -314,7 +338,9 @@ void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant type ?? ( void TypeCheckVisitor::Visit(DoWhileLoop* node) { Visitor::Visit(node->condition); - context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_); + if (!context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_)) { + error_handling::HandleTypecheckError("Do while loop statement condition is not bool expression", node->base); + } Visitor::Visit(node->statement); @@ -324,7 +350,9 @@ void TypeCheckVisitor::Visit(DoWhileLoop* node) { void TypeCheckVisitor::Visit(WhileLoop* node) { Visitor::Visit(node->condition); - context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_); + if (!context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_)) { + error_handling::HandleTypecheckError("While loop statement condition is not bool expression", node->base); + } Visitor::Visit(node->statement);