diff --git a/include/execute_visitor.hpp b/include/execute_visitor.hpp index 7efe385..5443290 100644 --- a/include/execute_visitor.hpp +++ b/include/execute_visitor.hpp @@ -174,8 +174,6 @@ private: utils::IdType current_value_; std::optional active_loop_control_expression_; - std::optional returned_value_; - std::optional brought_value_; std::optional is_const_definition_; bool case_matched_; }; diff --git a/include/utils.hpp b/include/utils.hpp index d0df08c..91c3838 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -16,6 +16,9 @@ using IdType = size_t; const std::string ClassInternalVarName = "self"; const size_t MaxOperatorPrecedence = 4; +struct ValueReturnedMarker {}; +struct ValueBroughtMarker {}; + enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 }; enum class IsConstModifier { Const = 0, Var = 1 }; enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2}; diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 09da633..5ce5122 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -12,31 +12,41 @@ namespace interpreter { // Sources ----------------- -void ExecuteVisitor::Visit(SourceFile* node) { // never used ?? - for (auto& statement : node->statements) { - Visitor::Visit(statement); - } +void ExecuteVisitor::Visit(SourceFile* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.SourceFile", + &node->base); } // Namespaces, partitions ----------------- -void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ?? - for (auto& statement : node->statements) { - Visitor::Visit(statement); - } +void ExecuteVisitor::Visit(NamespaceSources* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.NamespaceSources", + &node->base); } -void ExecuteVisitor::Visit(Namespace* node) { // never used ?? - // Visit(&node->type); - Visit(&node->scope); +void ExecuteVisitor::Visit(Namespace* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.Namespace", + &node->base); } // Definitions ----------------- -void ExecuteVisitor::Visit(ImportStatement*) {} // no value -void ExecuteVisitor::Visit(AliasDefinitionStatement*) {} // no value +void ExecuteVisitor::Visit(ImportStatement* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.ImportStatement", + &node->base); +} -void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call +void ExecuteVisitor::Visit(AliasDefinitionStatement* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.AliasDefinitionStatement", + &node->base); +} + +void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { Visitor::Visit(node->value); is_const_definition_ = node->modifier; @@ -44,28 +54,42 @@ void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on fu is_const_definition_ = std::nullopt; } -void ExecuteVisitor::Visit(FunctionDeclaration*) {} // no value +void ExecuteVisitor::Visit(FunctionDeclaration* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.FunctionDeclaration", + &node->base); +} void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call // Visit(node->definition.get()); context_manager_.EnterContext(); - returned_value_ = std::nullopt; - Visitor::Visit(node->value); + try { + Visitor::Visit(node->value); + } catch (utils::ValueReturnedMarker&) {} - if (returned_value_.has_value()) { - current_value_ = returned_value_.value(); - } // else returned type = current_type_ - - returned_value_ = std::nullopt; + // current_value_ passed from visited expression or from ReturnExpression context_manager_.ExitContext(); } -void ExecuteVisitor::Visit(TypeDefinitionStatement*) {} // no value -void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement*) {} // no value +void ExecuteVisitor::Visit(TypeDefinitionStatement* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TypeDefinitionStatement", + &node->base); +} -void ExecuteVisitor::Visit(TypeclassDefinitionStatement*) {} // no value +void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.AbstractTypeDefinitionStatement", + &node->base); +} + +void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TypeclassDefinitionStatement", + &node->base); +} void ExecuteVisitor::Visit(PartitionStatement* node) { Visitor::Visit(node->value); @@ -73,7 +97,11 @@ void ExecuteVisitor::Visit(PartitionStatement* node) { // Flow control ----------------- -void ExecuteVisitor::Visit(TypeConstructorPatternParameter*) {} // handled in TypeConstructorPattern +void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) { // handled in TypeConstructorPattern + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TypeConstructorPatternParameter", + &node->base); +} // TODO: check void ExecuteVisitor::Visit(TypeConstructorPattern* node) { @@ -113,7 +141,11 @@ void ExecuteVisitor::Visit(TypeConstructorPattern* node) { } } -void ExecuteVisitor::Visit(MatchCase*) {} // handeled in Match +void ExecuteVisitor::Visit(MatchCase* node) { // handeled in Match + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.MatchCase", + &node->base); +} void ExecuteVisitor::Visit(Match* node) { context_manager_.EnterContext(); @@ -316,24 +348,20 @@ void ExecuteVisitor::Visit(LoopLoop* node) { void ExecuteVisitor::Visit(Block* node) { context_manager_.EnterContext(); + bool value_brought = false; + for (auto& statement : node->statements) { - brought_value_ = std::nullopt; - Visitor::Visit(statement); - if (returned_value_.has_value()) { - brought_value_ = std::nullopt; - break; - } - if (brought_value_.has_value()) { + try { + Visitor::Visit(statement); + } catch (utils::ValueBroughtMarker&) { // current_value_ passed from ReturnExpression + value_brought = true; break; } } context_manager_.ExitContext(); - if (brought_value_.has_value()) { - current_value_ = brought_value_.value(); - brought_value_ = std::nullopt; - } else { + if (!value_brought) { current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -580,18 +608,18 @@ void ExecuteVisitor::Visit(VariantExpression* node) { void ExecuteVisitor::Visit(ReturnExpression* node) { Visitor::Visit(node->expression); if (node->is_from_definition) { - returned_value_ = current_value_; - } else { - brought_value_ = current_value_; + throw utils::ValueReturnedMarker(); } - current_value_ = context_manager_.AddValue( - info::value::InternalValue(info::value::Unit()), - utils::ValueType::Tmp); + throw utils::ValueBroughtMarker(); } -void ExecuteVisitor::Visit(TypeConstructorParameter*) {} // handled in TypeConstructor +void ExecuteVisitor::Visit(TypeConstructorParameter* node) { // handled in TypeConstructor + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TypeConstructorParameter", + &node->base); +} // TODO: check void ExecuteVisitor::Visit(TypeConstructor* node) { @@ -786,15 +814,43 @@ void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check // Type -void ExecuteVisitor::Visit(FunctionType*) {} // no value -void ExecuteVisitor::Visit(TupleType*) {} // no value -void ExecuteVisitor::Visit(VariantType*) {} // no value -void ExecuteVisitor::Visit(TypeExpression*) {} // no value -void ExecuteVisitor::Visit(ExtendedScopedAnyType*) {} // no value +void ExecuteVisitor::Visit(FunctionType* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.FunctionType", + &node->base); +} + +void ExecuteVisitor::Visit(TupleType* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TupleType", + &node->base); +} + +void ExecuteVisitor::Visit(VariantType* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.VariantType", + &node->base); +} + +void ExecuteVisitor::Visit(TypeExpression* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.TypeExpression", + &node->base); +} + +void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.ExtendedScopedAnyType", + &node->base); +} // Typeclass -void ExecuteVisitor::Visit(ParametrizedTypeclass*) {} // no value +void ExecuteVisitor::Visit(ParametrizedTypeclass* node) { + error_handling::HandleInternalError("Should be unreachable", + "TypeCheckVisitor.ParametrizedTypeclass", + &node->base); +} // Typeclass & Type ----------------- @@ -802,10 +858,6 @@ void ExecuteVisitor::Visit(ParametrizedType*) {} // no value // Identifiers, constants, etc. ----------------- -// void ExecuteVisitor::Visit(ExtendedName* node) {} - -// void ExecuteVisitor::Visit(std::string* node) {} // std::string - void ExecuteVisitor::Visit(FloatNumberLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 98aaf3b..0086ef6 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -661,6 +661,7 @@ void TypeCheckVisitor::Visit(Block* node) { // TODO: types can be different in statement all_branches_brought_value_ = true; + brought_type_ = std::nullopt; context_manager_.EnterContext(); for (auto& statement : node->statements) { diff --git a/tests/test_code.lang b/tests/test_code.lang index db8efe8..1c9f70d 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -143,7 +143,8 @@ def func : s = { exec main { for i in (,0 ,1 ,2 ,3) do func: "abacaba" ; print: ({ - if true then bring read: else () + if true then bring read: else { ; print: "aaa" } bring "nothing" + ; print: "aaa" }) }