From 6bf64acc4df75f48ed855ddfddaab59c69ed02b6 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Mon, 22 May 2023 18:33:56 +0300 Subject: [PATCH] execute_visitor value types fixed --- include/contexts.hpp | 19 +++++ include/types.hpp | 2 +- include/values.hpp | 20 ++--- src/execute_visitor.cpp | 179 ++++++++++++++++++++-------------------- src/values.cpp | 54 ++++++------ 5 files changed, 146 insertions(+), 128 deletions(-) diff --git a/include/contexts.hpp b/include/contexts.hpp index ae3825f..f33a7d6 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -49,11 +49,30 @@ public: return value_manager_.GetValueType(value_id); } + void ModifiyValue(utils::IdType value_id, utils::ValueType new_value_type) { + GetValueType(value_id) = new_value_type; + } + utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) { Value value = *GetAnyValue(value_id); return AddAnyValue(std::move(value), new_value_type); } + 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); + } + + // make deep copy if not temporary + utils::IdType ToTemporaryValue(utils::IdType value_id) { + if (GetValueType(value_id) == utils::ValueType::Tmp) { + return value_id; + } + + return ToModifiedValueCopy(value_id, utils::ValueType::Tmp); + } + ValueManager* GetValueManager() { return &value_manager_; } diff --git a/include/types.hpp b/include/types.hpp index d5397ee..a88bff9 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -377,7 +377,7 @@ 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; } diff --git a/include/values.hpp b/include/values.hpp index 6665f81..3a77fdc 100644 --- a/include/values.hpp +++ b/include/values.hpp @@ -34,7 +34,7 @@ public: bool Same(const InternalValue& value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::variant value; }; -struct TupleValue { /// TODO: no need to store strings (only store associated type) ?? +struct TupleValue { /// no need to store strings (only store associated type) ?? public: TupleValue() = default; @@ -56,7 +56,7 @@ public: bool Same(const TupleValue& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); // TODO + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); // TODO public: std::vector, utils::IdType>> fields; @@ -75,7 +75,7 @@ public: bool Same(const VariantValue& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: TupleValue value; @@ -94,7 +94,7 @@ public: bool Same(const ReferenceToValue& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::vector references; @@ -115,7 +115,7 @@ public: bool Same(const FunctionValue& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::variant GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::vector elements; @@ -158,7 +158,7 @@ public: bool Same(const OptionalValue& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::optional value; @@ -177,7 +177,7 @@ public: bool Same(const Value& other_value) const; std::optional GetFieldValue(const std::string& name) const; - utils::IdType DeepCopy(ValueManager* value_manager); + utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type); public: std::variantdefinition.get()); context_manager_.EnterContext(); try { Visitor::Visit(node->value); } catch (utils::ValueReturnedMarker&) {} - // current_value_ passed from visited expression or from ReturnExpression + // TODO: sometimes return references, choose by declaration + current_value_ = context_manager_.ToTemporaryValue(current_value_); context_manager_.ExitContext(); } @@ -187,16 +187,6 @@ void ExecuteVisitor::Visit(Match* node) { context_manager_.ExitContext(); } - // --- instead of optional return value or throw runtime error --- - // if (statement_visited) { - // current_value_ = context_manager_.AddValue( - // info::value::OptionalValue(current_value_, context_manager_.GetValueManager()), - // utils::ValueType::Tmp); - // } else { - // current_value_ = context_manager_.AddValue( - // info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()), - // utils::ValueType::Tmp); - // } if (!statement_visited) { error_handling::HandleRuntimeError("Value match option not found", node->base); } @@ -205,36 +195,41 @@ void ExecuteVisitor::Visit(Match* node) { } void ExecuteVisitor::Visit(Condition* node) { - context_manager_.EnterContext(); - + bool branch_visited = false; for (size_t i = 0; i < node->conditions.size(); ++i) { if (HandleCondition(node->conditions[i], node->base)) { + context_manager_.EnterContext(); Visitor::Visit(node->statements[i]); + context_manager_.ExitContext(); if (node->statements.size() == node->conditions.size()) { - current_value_ = context_manager_.AddValue( + current_value_ = context_manager_.AddValue( // optional with "reference" to value info::value::OptionalValue(current_value_, context_manager_.GetValueManager()), - utils::ValueType::Tmp); // take value type from current_value_ ?? + context_manager_.GetValueType(current_value_)); } - return; // current_value_ passed from statement + branch_visited = true; + break; } } - if (node->statements.size() > node->conditions.size()) { - Visitor::Visit(node->statements[node->conditions.size()]); - } else { - current_value_ = context_manager_.AddValue( - info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()), - utils::ValueType::Tmp); - } - context_manager_.ExitContext(); + if (!branch_visited) { + if (node->statements.size() > node->conditions.size()) { + context_manager_.EnterContext(); + Visitor::Visit(node->statements[node->conditions.size()]); + context_manager_.ExitContext(); + } else { + current_value_ = context_manager_.AddValue( // optional with "reference" to value + info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()), + context_manager_.GetValueType(current_value_)); + } + } } void ExecuteVisitor::Visit(DoWhileLoop* node) { - context_manager_.EnterContext(); - std::vector result; do { + context_manager_.EnterContext(); + Visitor::Visit(node->statement); if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) { @@ -245,21 +240,21 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) { continue; } - result.push_back(current_value_); + result.push_back(context_manager_.ToTemporaryValue(current_value_)); + + context_manager_.ExitContext(); } while(HandleCondition(node->condition, node->base)); current_value_ = context_manager_.AddValue( info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), utils::ValueType::Tmp); - - context_manager_.ExitContext(); } void ExecuteVisitor::Visit(WhileLoop* node) { - context_manager_.EnterContext(); - std::vector result; while(HandleCondition(node->condition, node->base)) { + context_manager_.EnterContext(); + Visitor::Visit(node->statement); if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) { @@ -270,30 +265,31 @@ void ExecuteVisitor::Visit(WhileLoop* node) { continue; } - result.push_back(current_value_); + result.push_back(context_manager_.ToTemporaryValue(current_value_)); + + context_manager_.ExitContext(); } current_value_ = context_manager_.AddValue( info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), utils::ValueType::Tmp); - - context_manager_.ExitContext(); } -void ExecuteVisitor::Visit(ForLoop* node) { - context_manager_.EnterContext(); +// TODO: extend to different interval types (not only array) +// TODO: assign to variable, instead of making new ?? +void ExecuteVisitor::Visit(ForLoop* node) { std::vector result; - // TODO: extend to different interval types (not only array) Visitor::Visit(node->interval); info::value::ArrayValue* interval = ExtractValue(current_value_, node->base); - for (auto& value : interval->elements) { - context_manager_.EnterContext(); // TODO + for (auto& value : interval->elements) { // TODO: reference to element + context_manager_.EnterContext(); current_value_ = value; + is_const_definition_ = node->variable_modifier; - Visitor::Visit(node->variable); // TODO: assign variable, instead of making new + Visitor::Visit(node->variable); is_const_definition_ = std::nullopt; Visitor::Visit(node->statement); @@ -306,23 +302,21 @@ void ExecuteVisitor::Visit(ForLoop* node) { continue; } - result.push_back(current_value_); + result.push_back(context_manager_.ToTemporaryValue(current_value_)); - context_manager_.ExitContext(); // TODO + context_manager_.ExitContext(); } current_value_ = context_manager_.AddValue( info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), utils::ValueType::Tmp); - - context_manager_.ExitContext(); } void ExecuteVisitor::Visit(LoopLoop* node) { - context_manager_.EnterContext(); - std::vector result; while(true) { + context_manager_.EnterContext(); + Visitor::Visit(node->statement); if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) { @@ -333,14 +327,14 @@ void ExecuteVisitor::Visit(LoopLoop* node) { continue; } - result.push_back(current_value_); + result.push_back(context_manager_.ToTemporaryValue(current_value_)); + + context_manager_.ExitContext(); } current_value_ = context_manager_.AddValue( info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), utils::ValueType::Tmp); - - context_manager_.ExitContext(); } // Statements, expressions, blocks, etc. ----------------- @@ -387,7 +381,7 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) { utils::ValueType value_type = context_manager_.GetValueType(current_value_); - current_value_ = context_manager_.AddValue( + current_value_ = context_manager_.AddValue( // "reference" to type (save const / var) info::value::ReferenceToValue({node->reference}, current_value_, context_manager_.GetValueManager()), value_type); } @@ -413,7 +407,7 @@ void ExecuteVisitor::Visit(AccessExpression* node) { error_handling::HandleRuntimeError("Access index is out of range (string)", node->base); } - current_value_ = context_manager_.ToModifiedValue((*string_value_info)[index], value_type); + current_value_ = context_manager_.ToModifiedValue((*string_value_info)[index], utils::ValueType::Tmp); } else { info::value::ArrayValue* array_value_info = ExtractValue(current_value_, node->base); @@ -428,7 +422,6 @@ void ExecuteVisitor::Visit(AccessExpression* node) { // Other Expressions // TODO: refactor, separate to several functions -// TODO: more builtin functions, better handling (??) void ExecuteVisitor::Visit(FunctionCallExpression* node) { context_manager_.EnterContext(); @@ -436,6 +429,10 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { if (std::holds_alternative>(node->prefix.value())) { Visitor::Visit(*std::get>(node->prefix.value())); + if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { + // temporary value can't be modified inside + context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); + } if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); } @@ -456,6 +453,11 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { } else { if (node->is_method_of_first_argument_) { Visitor::Visit(node->arguments[0]); + + if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { + // temporary value can't be modified inside + context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); + } if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); } @@ -470,7 +472,6 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { if (!maybe_function_declaration_info.has_value()) { error_handling::HandleRuntimeError("Function declaration not found (for namespace function)", node->base); - // always namespace function ?? } function_declaration = maybe_function_declaration_info.value().node; @@ -566,8 +567,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { type_id = maybe_parameter_type_id.value(); } - if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, - type_id)) { + if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, type_id)) { error_handling::HandleRuntimeError("Type redefinition (function argument)", node->base); } } @@ -575,6 +575,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { for (size_t i = (node->is_method_of_first_argument_ ? 1 : 0); i < node->arguments.size(); ++i) { Visitor::Visit(node->arguments[i]); + // function arguments can't be changed inside function current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); if (!context_manager_.DefineVariable(function_definition->definition->arguments[i], current_value_)) { @@ -593,7 +594,7 @@ void ExecuteVisitor::Visit(TupleExpression* node) { fields.reserve(node->expressions.size()); for (auto& expression : node->expressions) { Visitor::Visit(expression); - fields.push_back({std::nullopt, current_value_}); + fields.push_back({std::nullopt, context_manager_.ToTemporaryValue(current_value_)}); } current_value_ = context_manager_.AddValue( @@ -601,14 +602,16 @@ void ExecuteVisitor::Visit(TupleExpression* node) { utils::ValueType::Tmp); } +// TODO: handle tuples separately ?? void ExecuteVisitor::Visit(VariantExpression* node) { - // TODO: decide about return type (variant) for (size_t i = 0; i < node->expressions.size(); ++i) { Visitor::Visit(node->expressions[i]); + current_value_ = context_manager_.ToTemporaryValue(current_value_); + info::value::OptionalValue* expression_value = ExtractValue(current_value_, node->base); if (expression_value->value.has_value()) { std::vector, utils::IdType>> fields - {{std::nullopt, expression_value->value.value()}}; + {{std::nullopt, expression_value->value.value()}}; // TODO: any type instead tuple in variant type ?? info::value::TupleValue variant_tuple = info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()); @@ -645,7 +648,6 @@ void ExecuteVisitor::Visit(TypeConstructorParameter* node) { // handled in TypeC &node->base); } -// TODO: check void ExecuteVisitor::Visit(TypeConstructor* node) { std::vector, utils::IdType>> fields; @@ -656,14 +658,12 @@ void ExecuteVisitor::Visit(TypeConstructor* node) { utils::IdType constructor_id = node->constructor->constructor_id_.value(); info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id); - // Visit(node->constructor.get()); // use parameters from type expression ?? fields.reserve(node->parameters.size()); for (auto& parameter : node->parameters) { Visitor::Visit(parameter.value); - // TODO: copy/move parameters fields.push_back( { parameter.name.has_value() ? std::optional(parameter.name.value()) : std::nullopt, - current_value_ }); + context_manager_.ToTemporaryValue(current_value_) }); } if (constructor_info.order.has_value()) { // => variant @@ -692,7 +692,7 @@ void ExecuteVisitor::Visit(ArrayExpression* node) { elements.reserve(node->elements.size()); for (auto& element : node->elements) { Visitor::Visit(element); - elements.push_back(current_value_); + elements.push_back(context_manager_.ToTemporaryValue(current_value_)); } current_value_ = context_manager_.AddValue( @@ -722,7 +722,7 @@ void ExecuteVisitor::Visit(NameExpression* node) { // TODO: check utils::ValueType variable_value_type = context_manager_.GetValueType(current_value_); for (size_t i = 1; i < node->names.size(); ++i) { - std::optional maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i]); // TODO + std::optional maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i]); if (!maybe_field_value.has_value()) { error_handling::HandleRuntimeError("Variable field not found", node->base); } @@ -734,7 +734,7 @@ void ExecuteVisitor::Visit(NameExpression* node) { // TODO: check } } -void ExecuteVisitor::Visit(TupleName* node) { // TODO: check +void ExecuteVisitor::Visit(TupleName* node) { utils::IdType value = current_value_; std::optional maybe_tuple_value = context_manager_.GetValue(value); @@ -761,6 +761,8 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check void ExecuteVisitor::Visit(VariantName* node) { utils::IdType value = current_value_; + auto value_type = context_manager_.GetValueType(value); + std::optional maybe_variant_value = context_manager_.GetValue(value); if (!maybe_variant_value.has_value()) { @@ -772,49 +774,46 @@ void ExecuteVisitor::Visit(VariantName* node) { if (maybe_variant_value.value()->value.fields.empty()) { current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), - utils::IsConstModifierToValueType(is_const_definition_.value())); - // TODO: check, that same with typecheck + utils::ValueType::Tmp); } else { current_value_ = context_manager_.AddValue( maybe_variant_value.value()->value, - utils::IsConstModifierToValueType(is_const_definition_.value())); + value_type); } - current_value_ = context_manager_.AddValue( + current_value_ = context_manager_.AddValue( // make optional value "reference" info::value::OptionalValue(current_value_, context_manager_.GetValueManager()), - utils::IsConstModifierToValueType(is_const_definition_.value())); + value_type); } else { current_value_ = context_manager_.AddValue( info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()), - utils::IsConstModifierToValueType(is_const_definition_.value())); + utils::ValueType::Tmp); } Visitor::Visit(node->names[i]); } - // TODO: find out, which constructor used - // set value to that constructor and None (empty OptionalValue) to others current_value_ = value; } -void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check - utils::IdType value = current_value_; - +// TODO: move, etc. +void ExecuteVisitor::Visit(AnnotatedName* node) { if (!is_const_definition_.has_value()) { error_handling::HandleInternalError("No value in is_const_definition_", "TypeCheckVisitor.AnnotatedName", &node->base); } - // utils::ValueType value_type = context_manager_.GetValueType(current_value_); + auto value_type = context_manager_.GetValueType(current_value_); - // TODO: only on move - // if (value_type == utils::ValueType::Const - // && is_const_definition_.value() == utils::IsConstModifier::Var) { - // error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base); - // } + if (value_type == utils::ValueType::Tmp) { + // consume temporary value + context_manager_.ModifiyValue(current_value_, IsConstModifierToValueType(is_const_definition_.value())); + } else { + // make value copy + current_value_ = context_manager_.ToModifiedValueCopy(current_value_, IsConstModifierToValueType(is_const_definition_.value())); + } - current_value_ = context_manager_.ToModifiedValue(value, utils::IsConstModifierToValueType(is_const_definition_.value())); if (!context_manager_.DefineVariable(node->name, current_value_)) { error_handling::HandleRuntimeError("Variable name already present in context", node->base); } @@ -948,7 +947,8 @@ void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) { switch (node.index()) { case 0: - value = context_manager_.ToModifiedValue(value, utils::ValueType::Const); // ?? + // always copy, because case can not match value + value = context_manager_.ToModifiedValueCopy(value, utils::ValueType::Const); if (!context_manager_.DefineVariable(*std::get>(node), value)) { error_handling::HandleRuntimeError("Can't redifine variable", base_node); @@ -981,7 +981,7 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) { } else if (node->name == "scan") { current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read()), utils::ValueType::Tmp); - } else if (node->name == "random") { // TODO + } else if (node->name == "random") { // TODO: different types, better random, seed, etc. current_value_ = context_manager_.AddValue(info::value::InternalValue(rand()), utils::ValueType::Tmp); } else { @@ -1009,7 +1009,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, arguments.push_back(ExtractValue(current_value_, node->base)); } - error_handling::DebugPrint(info::type::ToString(type)); + // error_handling::DebugPrint(info::type::ToString(type)); + // std::cout << std::endl; switch (type) { case info::type::InternalType::Float: @@ -1051,11 +1052,9 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), utils::ValueType::Tmp); } else if (name == "<") { - error_handling::DebugPrint("_");/* current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), - utils::ValueType::Tmp);*/ - error_handling::DebugPrint("aaaaaaaa"); + utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( info::value::InternalValue(*arguments[0]->GetValue().value() == *arguments[1]->GetValue().value()), diff --git a/src/values.cpp b/src/values.cpp index 2e90e04..676d358 100644 --- a/src/values.cpp +++ b/src/values.cpp @@ -37,8 +37,8 @@ std::optional InternalValue::GetFieldValue(const std::string&) co return std::nullopt; } -utils::IdType InternalValue::DeepCopy(ValueManager* value_manager) { - return value_manager->ExplicitAddValue(InternalValue(value), utils::ValueType::Tmp); +utils::IdType InternalValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { + return value_manager->ExplicitAddValue(InternalValue(value), new_value_type); } // @@ -65,16 +65,16 @@ std::optional TupleValue::GetFieldValue(const std::string& name) return std::nullopt; } -utils::IdType TupleValue::DeepCopy(ValueManager* value_manager) { +utils::IdType TupleValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { std::vector, utils::IdType>> fields_copy(fields.size()); for (size_t i = 0; i < fields.size(); ++i) { - fields_copy[i] = {fields[i].first, value_manager_->GetAnyValue(fields[i].second)->DeepCopy(value_manager)}; + fields_copy[i] = {fields[i].first, value_manager_->GetAnyValue(fields[i].second)->DeepCopy(value_manager, new_value_type)}; } return value_manager->ExplicitAddValue( TupleValue(std::move(fields_copy), value_manager), - utils::ValueType::Tmp); + new_value_type); } // @@ -92,8 +92,8 @@ std::optional VariantValue::GetFieldValue(const std::string& name return value.GetFieldValue(name); } -utils::IdType VariantValue::DeepCopy(ValueManager* value_manager) { - auto maybe_tuple_deep_copy = value_manager->GetValue(value.DeepCopy(value_manager)); +utils::IdType VariantValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { + auto maybe_tuple_deep_copy = value_manager->GetValue(value.DeepCopy(value_manager, new_value_type)); if (!maybe_tuple_deep_copy) { error_handling::HandleInternalError("Deep copied TupleType in not TupleType", @@ -103,7 +103,7 @@ utils::IdType VariantValue::DeepCopy(ValueManager* value_manager) { return value_manager->ExplicitAddValue( VariantValue(TupleValue(*maybe_tuple_deep_copy.value()), current_constructor), - utils::ValueType::Tmp); + new_value_type); } // @@ -124,10 +124,10 @@ std::optional ReferenceToValue::GetFieldValue(const std::string& return value_manager_->GetAnyValue(value)->GetFieldValue(name); } -utils::IdType ReferenceToValue::DeepCopy(ValueManager* value_manager) { +utils::IdType ReferenceToValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { return value_manager->ExplicitAddValue( - ReferenceToValue(references, value_manager_->GetAnyValue(value)->DeepCopy(value_manager), value_manager), - utils::ValueType::Tmp); + ReferenceToValue(references, value_manager_->GetAnyValue(value)->DeepCopy(value_manager, new_value_type), value_manager), + new_value_type); } @@ -156,10 +156,10 @@ std::optional FunctionValue::GetFieldValue(const std::string&) co return std::nullopt; } -utils::IdType FunctionValue::DeepCopy(ValueManager* value_manager) { +utils::IdType FunctionValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { return value_manager->ExplicitAddValue( FunctionValue(function, value_manager), - utils::ValueType::Tmp); + new_value_type); } // @@ -181,16 +181,16 @@ std::optional ArrayValue::GetFieldValue(const std::string&) const return std::nullopt; } -utils::IdType ArrayValue::DeepCopy(ValueManager* value_manager) { +utils::IdType ArrayValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { std::vector elements_copy(elements.size()); for (size_t i = 0; i < elements.size(); ++i) { - elements_copy[i] = value_manager_->GetAnyValue(elements[i])->DeepCopy(value_manager); + elements_copy[i] = value_manager_->GetAnyValue(elements[i])->DeepCopy(value_manager, new_value_type); } return value_manager->ExplicitAddValue( ArrayValue(std::move(elements_copy), is_constant_size, value_manager), - utils::ValueType::Tmp); + new_value_type); } // @@ -210,7 +210,7 @@ std::optional OptionalValue::GetFieldValue(const std::string&) co return std::nullopt; } -utils::IdType OptionalValue::DeepCopy(ValueManager* value_manager) { +utils::IdType OptionalValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { if (!value.has_value()) { return value_manager->ExplicitAddValue( OptionalValue(std::nullopt, value_manager), @@ -218,8 +218,8 @@ utils::IdType OptionalValue::DeepCopy(ValueManager* value_manager) { } return value_manager->ExplicitAddValue( - OptionalValue(value_manager_->GetAnyValue(value.value())->DeepCopy(value_manager), value_manager), - utils::ValueType::Tmp); + OptionalValue(value_manager_->GetAnyValue(value.value())->DeepCopy(value_manager, new_value_type), value_manager), + new_value_type); } // @@ -279,24 +279,24 @@ std::optional Value::GetFieldValue(const std::string& name) const return std::nullopt; } -utils::IdType Value::DeepCopy(ValueManager* value_manager) { +utils::IdType Value::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) { size_t index = value.index(); switch (index) { case 0: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 1: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 2: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 3: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 4: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 5: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); case 6: - return std::get(value).DeepCopy(value_manager); + return std::get(value).DeepCopy(value_manager, new_value_type); default: // error break;