From 43b2993e2a894de9ab9514915ba519c639a3ea2c Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Mon, 22 May 2023 19:14:17 +0300 Subject: [PATCH] type_check_visitor value types maybe fixed --- include/contexts.hpp | 4 +- include/types.hpp | 6 ++- include/values.hpp | 6 ++- src/execute_visitor.cpp | 45 +++++++++++++++------ src/type_check_visitor.cpp | 80 +++++++++++++++----------------------- 5 files changed, 76 insertions(+), 65 deletions(-) diff --git a/include/contexts.hpp b/include/contexts.hpp index f33a7d6..6cda970 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -50,7 +50,7 @@ public: } void ModifiyValue(utils::IdType value_id, utils::ValueType new_value_type) { - GetValueType(value_id) = new_value_type; + value_manager_.SetValueType(value_id, new_value_type); } utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) { @@ -61,7 +61,7 @@ public: utils::IdType ToModifiedValueCopy(utils::IdType value_id, utils::ValueType new_value_type) { Value* value = GetAnyValue(value_id); - return value->DeepCopy(value_manager_, new_value_type); + return value->DeepCopy(&value_manager_, new_value_type); } // make deep copy if not temporary diff --git a/include/types.hpp b/include/types.hpp index a88bff9..3756856 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -377,10 +377,14 @@ public: return &types_.at(type_id).first; } - utils::ValueType& GetValueType(utils::IdType type_id) { + utils::ValueType GetValueType(utils::IdType type_id) { return types_.at(type_id).second; } + void SetValueType(utils::IdType type_id, utils::ValueType value_type) { + types_.at(type_id).second = value_type; + } + bool EqualValues(utils::IdType first_type, utils::IdType second_type) { return GetAnyValue(first_type)->Same(*GetAnyValue(second_type)); } diff --git a/include/values.hpp b/include/values.hpp index 3a77fdc..3925ef9 100644 --- a/include/values.hpp +++ b/include/values.hpp @@ -223,10 +223,14 @@ public: return &values_.at(value_id).first; } - utils::ValueType& GetValueType(utils::IdType value_id) { + utils::ValueType GetValueType(utils::IdType value_id) { return values_.at(value_id).second; } + void SetValueType(utils::IdType value_id, utils::ValueType value_type) { + values_.at(value_id).second = value_type; + } + bool EqualValues(utils::IdType first_value, utils::IdType second_value) { return GetAnyValue(first_value)->Same(*GetAnyValue(second_value)); } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 0275fd6..53df44f 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -509,7 +509,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { if (maybe_internal_type.has_value()) { if (HandleBuiltinTypeFunctionCall(node, maybe_internal_type.value())) { context_manager_.ExitContext(); - return; // TODO: always return from end of function + return; // TODO: return from end of function } error_handling::HandleRuntimeError("Type function definition not found (builtin type)", node->base); } @@ -995,6 +995,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::type::InternalType type) { const std::string& name = node->name; + error_handling::DebugPrint(name); + if (utils::IsBuiltinFunction(name)) { std::vector arguments; arguments.reserve(node->arguments.size()); @@ -1009,8 +1011,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, arguments.push_back(ExtractValue(current_value_, node->base)); } - // error_handling::DebugPrint(info::type::ToString(type)); - // std::cout << std::endl; + error_handling::DebugPrint(info::type::ToString(type)); + std::cout << std::endl; switch (type) { case info::type::InternalType::Float: @@ -1035,10 +1037,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1.0), utils::ValueType::Tmp); } else if (name == "+=") { - // TODO - error_handling::HandleInternalError("+= not implemented yet (float)", - "ExecuteVisitor.HandleBuiltinTypeFunctionCall", - &node->base); + *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); + } else if (name == "-=") { + *arguments[0]->GetValue().value() -= *arguments[1]->GetValue().value(); + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); + } else if (name == "*=") { + *arguments[0]->GetValue().value() *= *arguments[1]->GetValue().value(); + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); + } else if (name == "/=") { + *arguments[0]->GetValue().value() /= *arguments[1]->GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1063,7 +1077,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() / *arguments[1]->GetValue().value()), utils::ValueType::Tmp); - } else if (name == "mod") { // TODO: best implementation of mod (read % specification) + } else if (name == "mod") { // TODO: better implementation of mod (read % specification) current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() % *arguments[1]->GetValue().value()), utils::ValueType::Tmp); @@ -1076,10 +1090,17 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1), utils::ValueType::Tmp); } else if (name == "+=") { - // TODO - error_handling::HandleInternalError("+= not implemented yet (int)", - "ExecuteVisitor.HandleBuiltinTypeFunctionCall", - &node->base); + *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); + } else if (name == "-=") { + *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); + current_value_ = context_manager_.AddValue( + info::value::InternalValue(info::value::Unit()), + utils::ValueType::Tmp); + } else if (name == "*=") { + *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index f06d920..5d1be60 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -34,11 +34,11 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { } void TypeCheckVisitor::Visit(Namespace* node) { + context_manager_.EnterContext(); + if (node->link_typeclass_id_.has_value()) { utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_; - context_manager_.EnterContext(); - utils::IdType abstract_type = AddGraphIdLocalAbstractTypes(graph_id); abstract_type = context_manager_.ToModifiedValue(abstract_type, ClassInternalsModifierToValueType(node->modifier)); @@ -67,11 +67,10 @@ void TypeCheckVisitor::Visit(Namespace* node) { ClassInternalsModifierToValueType(node->modifier)); if (node->modifier != utils::ClassInternalsModifier::Static) { - context_manager_.EnterVariableContext(utils::ClassInternalVarName, type); - } else { - context_manager_.EnterContext(); + context_manager_.DefineVariable(utils::ClassInternalVarName, type); } + type = context_manager_.ToModifiedValue(type, utils::ValueType::Tmp); AddGraphIdLocalTypes(type_info->type.node->graph_id_, type); if (type_namespaces_.count(node->link_type_id_.value()) != 0) { @@ -106,16 +105,12 @@ void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { &node->base); } +// TODO: move, etc. void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { - // TODO: remove variable on move is_in_statement_ = true; Visitor::Visit(node->value); // current_type from value automatically passed to name definitions - if (node->assignment_modifier == utils::AssignmentModifier::Assign) { - current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); - // TODO: make type tmp recursively ?? - } is_const_definition_ = node->modifier; Visitor::Visit(node->name); @@ -127,7 +122,7 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { node->base.type_ = current_type_; } -void TypeCheckVisitor::Visit(FunctionDeclaration* node) { +void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaration check needed ?? bool was_in_statement = is_in_statement_; is_in_statement_ = true; @@ -141,7 +136,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { } context_manager_.EnterContext(); - for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? + for (auto& parameter : node->parameters) { current_type_ = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->graph_id_, @@ -212,7 +207,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { &node->base); } - declaration = maybe_function_info.value()->declaration; // TODO: save declaration to global info ?? + declaration = maybe_function_info.value()->declaration; } context_manager_.EnterContext(); @@ -233,7 +228,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { for (size_t i = 0; i < node->definition->arguments.size(); ++i) { Visitor::Visit(declaration->type->types[i]); - current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const); // TODO: Var?? + current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const); if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) { error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base); } @@ -277,7 +272,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { std::string& type_name = node->definition->type->type; for (auto& function : required_functions) { - if (function.second.definition.has_value()) { // TODO: check + if (function.second.definition.has_value()) { continue; } @@ -326,9 +321,11 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = false; - // --- can't work always, because "visit" can be called for internal types - // current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); - // node->base.type_ = current_type_; + // otherwise function called from VisitSourceFile + if (!maybe_internal_type.has_value()) { + current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); + node->base.type_ = current_type_; + } } void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) { @@ -376,8 +373,7 @@ void TypeCheckVisitor::Visit(AnyAnnotatedType* node) { void TypeCheckVisitor::Visit(TypeConstructorPatternParameter*) {} // Handled in TypeConstructorPattern -// TODO -// TODO: check for tuples +// TODO: check ?? void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match named constructor if (!node->constructor->constructor_id_.has_value()) { error_handling::HandleTypecheckError("Type constructor pattern constructor name not found", node->base); @@ -450,7 +446,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name void TypeCheckVisitor::Visit(MatchCase* node) { // value type passed as current_type_ - is_const_definition_ = utils::IsConstModifier::Const; // TODO: or var?? + is_const_definition_ = utils::IsConstModifier::Const; Visitor::Visit(node->value); current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); @@ -473,7 +469,8 @@ void TypeCheckVisitor::Visit(MatchCase* node) { node->base.type_ = current_type_; } -void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match +// TODO: move, etc. +void TypeCheckVisitor::Visit(Match* node) { // TODO: types can be different in block statement context_manager_.EnterContext(); @@ -484,9 +481,8 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match Visitor::Visit(node->value); utils::IdType value_type = current_type_; - // TODO: several matches with one statement typecheck <- check proposed solution std::optional nearest_statement; - for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) { // TODO: internal contexts ?? + for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) { ResetReturnedAndBroughtTypes(); current_type_ = value_type; @@ -570,7 +566,7 @@ void TypeCheckVisitor::Visit(Condition* node) { } else { current_type_ = context_manager_.AddValue( info::type::OptionalType(type, context_manager_.GetValueManager()), - utils::ValueType::Tmp); // ?? + context_manager_.GetValueType(type)); // optional with "reference" to result type } context_manager_.ExitContext(); @@ -616,6 +612,7 @@ void TypeCheckVisitor::Visit(WhileLoop* node) { node->base.type_ = current_type_; } +// TODO: variable with reference to interval element + check void TypeCheckVisitor::Visit(ForLoop* node) { context_manager_.EnterContext(); @@ -707,7 +704,7 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) { info::type::ReferenceToType({node->reference}, current_type_, context_manager_.GetValueManager()), - context_manager_.GetValueType(current_type_)); // ?? + context_manager_.GetValueType(current_type_)); } // TODO: redifinitions for other types and tuples (with const index) ?? @@ -723,7 +720,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { auto maybe_type_value = context_manager_.GetValue(current_type_); if (maybe_type_value.has_value()) { - current_type_ = maybe_type_value.value()->GetElementsType(); + current_type_ = maybe_type_value.value()->GetElementsType(); // "reference" to element } else { auto maybe_internal_type_value = context_manager_.GetValue(current_type_); @@ -740,7 +737,6 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { // Other Expressions -// TODO: more builtin functions, better handling (??) void TypeCheckVisitor::Visit(FunctionCallExpression* node) { context_manager_.EnterContext(); @@ -842,7 +838,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { Visitor::Visit(function_declaration->type->types.back()); current_type_ = TypeInContext(current_type_, context); - node->base.type_ = current_type_; + node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); } void TypeCheckVisitor::Visit(TupleExpression* node) { @@ -916,6 +912,7 @@ void TypeCheckVisitor::Visit(ReturnExpression* node) { void TypeCheckVisitor::Visit(TypeConstructorParameter*) {} // Handeled in TypeConstructor visit // TODO: check for tuples +// TODO: move, etc. void TypeCheckVisitor::Visit(TypeConstructor* node) { if (!node->constructor->constructor_id_.has_value()) { error_handling::HandleTypecheckError("Type constructor name not found", node->base); @@ -929,7 +926,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { utils::IdType constructor_id = node->constructor->constructor_id_.value(); - // TODO: take type_id_ ?? info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id); utils::IdType type_id = constructor_info.type_id; @@ -940,7 +936,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { std::optional maybe_type_info = global_info_.GetTypeInfo(type_id); - if (!maybe_type_info.has_value()) { // TODO + if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.TypeConstructor", &node->base); @@ -957,7 +953,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { } for (size_t i = 0; i < node->parameters.size(); ++i) { - // TODO: remove variable on move if (node->parameters[i].name.has_value()) { if (!constructor_fields->entities[i].first.has_value() || constructor_fields->entities[i].first.value() != node->parameters[i].name.value()) { @@ -1088,6 +1083,7 @@ void TypeCheckVisitor::Visit(NameExpression* node) { node->base.type_ = current_type_; } +// TODO: move, etc. void TypeCheckVisitor::Visit(TupleName* node) { utils::IdType type = current_type_; @@ -1113,15 +1109,11 @@ void TypeCheckVisitor::Visit(TupleName* node) { } utils::ValueType value_type = context_manager_.GetValueType(type); - if (value_type == utils::ValueType::Const - && is_const_definition_.value() == utils::IsConstModifier::Var) { - error_handling::HandleTypecheckError("TupleName: value type expression not match variable definition modifier", node->base); - } for (size_t i = 0; i < node->names.size(); ++i) { current_type_ = type_value->GetFields()[i].second; - if (value_type == utils::ValueType::Tmp) { // TODO: ?? + if (value_type == utils::ValueType::Tmp) { // TODO: instead of recusive modification ?? current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); } @@ -1133,6 +1125,7 @@ void TypeCheckVisitor::Visit(TupleName* node) { node->base.type_ = current_type_; } +// TODO: move, etc. void TypeCheckVisitor::Visit(VariantName* node) { utils::IdType type = current_type_; @@ -1157,12 +1150,6 @@ void TypeCheckVisitor::Visit(VariantName* node) { &node->base); } - utils::ValueType value_type = context_manager_.GetValueType(type); - if (value_type == utils::ValueType::Const - && is_const_definition_.value() == utils::IsConstModifier::Var) { - error_handling::HandleTypecheckError("VariantName: value type of type and value type are different", node->base); - } - for (size_t i = 0; i < node->names.size(); ++i) { if (type_value->GetConstructors()[i].GetFields().empty()) { current_type_ = context_manager_.AddValue( @@ -1189,6 +1176,7 @@ void TypeCheckVisitor::Visit(VariantName* node) { node->base.type_ = current_type_; } +// TODO: move, etc. void TypeCheckVisitor::Visit(AnnotatedName* node) { utils::IdType type = current_type_; @@ -1198,12 +1186,6 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) { &node->base); } - utils::ValueType value_type = context_manager_.GetValueType(type); - if (value_type == utils::ValueType::Const - && is_const_definition_.value() == utils::IsConstModifier::Var) { - error_handling::HandleTypecheckError("AnnotatedName: value type expression not match variable definition modifier", node->base); - } - type = context_manager_.ToModifiedValue(type, utils::IsConstModifierToValueType(is_const_definition_.value())); if (!context_manager_.DefineVariable(node->name, type)) { error_handling::HandleTypecheckError("Variable name already present in context", node->base);