execute_visitor value types fixed

This commit is contained in:
ProgramSnail 2023-05-22 18:33:56 +03:00
parent 9aaac90ef6
commit 6bf64acc4d
5 changed files with 146 additions and 128 deletions

View file

@ -49,11 +49,30 @@ public:
return value_manager_.GetValueType(value_id); 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) { utils::IdType ToModifiedValue(utils::IdType value_id, utils::ValueType new_value_type) {
Value value = *GetAnyValue(value_id); Value value = *GetAnyValue(value_id);
return AddAnyValue(std::move(value), new_value_type); 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() { ValueManager* GetValueManager() {
return &value_manager_; return &value_manager_;
} }

View file

@ -377,7 +377,7 @@ public:
return &types_.at(type_id).first; 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; return types_.at(type_id).second;
} }

View file

@ -34,7 +34,7 @@ public:
bool Same(const InternalValue& value) const; bool Same(const InternalValue& value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::variant<double, std::variant<double,
@ -45,7 +45,7 @@ public:
Unit> value; Unit> 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: public:
TupleValue() = default; TupleValue() = default;
@ -56,7 +56,7 @@ public:
bool Same(const TupleValue& other_value) const; bool Same(const TupleValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> 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: public:
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields; std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
@ -75,7 +75,7 @@ public:
bool Same(const VariantValue& other_value) const; bool Same(const VariantValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
TupleValue value; TupleValue value;
@ -94,7 +94,7 @@ public:
bool Same(const ReferenceToValue& other_value) const; bool Same(const ReferenceToValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::vector<utils::ReferenceModifier> references; std::vector<utils::ReferenceModifier> references;
@ -115,7 +115,7 @@ public:
bool Same(const FunctionValue& other_value) const; bool Same(const FunctionValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::variant<interpreter::tokens::FunctionDeclaration*, std::variant<interpreter::tokens::FunctionDeclaration*,
@ -138,7 +138,7 @@ public:
bool Same(const ArrayValue& other_value) const; bool Same(const ArrayValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::vector<utils::IdType> elements; std::vector<utils::IdType> elements;
@ -158,7 +158,7 @@ public:
bool Same(const OptionalValue& other_value) const; bool Same(const OptionalValue& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::optional<utils::IdType> value; std::optional<utils::IdType> value;
@ -177,7 +177,7 @@ public:
bool Same(const Value& other_value) const; bool Same(const Value& other_value) const;
std::optional<utils::IdType> GetFieldValue(const std::string& name) const; std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
utils::IdType DeepCopy(ValueManager* value_manager); utils::IdType DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type);
public: public:
std::variant<InternalValue, std::variant<InternalValue,
@ -223,7 +223,7 @@ public:
return &values_.at(value_id).first; 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; return values_.at(value_id).second;
} }

View file

@ -61,14 +61,14 @@ void ExecuteVisitor::Visit(FunctionDeclaration* node) {
} }
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call
// Visit(node->definition.get());
context_manager_.EnterContext(); context_manager_.EnterContext();
try { try {
Visitor::Visit(node->value); Visitor::Visit(node->value);
} catch (utils::ValueReturnedMarker&) {} } 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(); context_manager_.ExitContext();
} }
@ -187,16 +187,6 @@ void ExecuteVisitor::Visit(Match* node) {
context_manager_.ExitContext(); 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) { if (!statement_visited) {
error_handling::HandleRuntimeError("Value match option not found", node->base); error_handling::HandleRuntimeError("Value match option not found", node->base);
} }
@ -205,36 +195,41 @@ void ExecuteVisitor::Visit(Match* node) {
} }
void ExecuteVisitor::Visit(Condition* node) { void ExecuteVisitor::Visit(Condition* node) {
context_manager_.EnterContext(); bool branch_visited = false;
for (size_t i = 0; i < node->conditions.size(); ++i) { for (size_t i = 0; i < node->conditions.size(); ++i) {
if (HandleCondition(node->conditions[i], node->base)) { if (HandleCondition(node->conditions[i], node->base)) {
context_manager_.EnterContext();
Visitor::Visit(node->statements[i]); Visitor::Visit(node->statements[i]);
context_manager_.ExitContext();
if (node->statements.size() == node->conditions.size()) { 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()), 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);
}
if (!branch_visited) {
if (node->statements.size() > node->conditions.size()) {
context_manager_.EnterContext();
Visitor::Visit(node->statements[node->conditions.size()]);
context_manager_.ExitContext(); 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) { void ExecuteVisitor::Visit(DoWhileLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result; std::vector<utils::IdType> result;
do { do {
context_manager_.EnterContext();
Visitor::Visit(node->statement); Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
@ -245,21 +240,21 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) {
continue; continue;
} }
result.push_back(current_value_); result.push_back(context_manager_.ToTemporaryValue(current_value_));
context_manager_.ExitContext();
} while(HandleCondition(node->condition, node->base)); } while(HandleCondition(node->condition, node->base));
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
context_manager_.ExitContext();
} }
void ExecuteVisitor::Visit(WhileLoop* node) { void ExecuteVisitor::Visit(WhileLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result; std::vector<utils::IdType> result;
while(HandleCondition(node->condition, node->base)) { while(HandleCondition(node->condition, node->base)) {
context_manager_.EnterContext();
Visitor::Visit(node->statement); Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
@ -270,30 +265,31 @@ void ExecuteVisitor::Visit(WhileLoop* node) {
continue; continue;
} }
result.push_back(current_value_); result.push_back(context_manager_.ToTemporaryValue(current_value_));
context_manager_.ExitContext();
} }
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp); 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<utils::IdType> result; std::vector<utils::IdType> result;
// TODO: extend to different interval types (not only array)
Visitor::Visit(node->interval); Visitor::Visit(node->interval);
info::value::ArrayValue* interval = ExtractValue<info::value::ArrayValue>(current_value_, node->base); info::value::ArrayValue* interval = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
for (auto& value : interval->elements) { for (auto& value : interval->elements) { // TODO: reference to element
context_manager_.EnterContext(); // TODO context_manager_.EnterContext();
current_value_ = value; current_value_ = value;
is_const_definition_ = node->variable_modifier; 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; is_const_definition_ = std::nullopt;
Visitor::Visit(node->statement); Visitor::Visit(node->statement);
@ -306,23 +302,21 @@ void ExecuteVisitor::Visit(ForLoop* node) {
continue; 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( current_value_ = context_manager_.AddValue(
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
context_manager_.ExitContext();
} }
void ExecuteVisitor::Visit(LoopLoop* node) { void ExecuteVisitor::Visit(LoopLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result; std::vector<utils::IdType> result;
while(true) { while(true) {
context_manager_.EnterContext();
Visitor::Visit(node->statement); Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) { if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) { if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
@ -333,14 +327,14 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
continue; continue;
} }
result.push_back(current_value_); result.push_back(context_manager_.ToTemporaryValue(current_value_));
context_manager_.ExitContext();
} }
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()), info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
context_manager_.ExitContext();
} }
// Statements, expressions, blocks, etc. ----------------- // Statements, expressions, blocks, etc. -----------------
@ -387,7 +381,7 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
utils::ValueType value_type = context_manager_.GetValueType(current_value_); 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()), info::value::ReferenceToValue({node->reference}, current_value_, context_manager_.GetValueManager()),
value_type); value_type);
} }
@ -413,7 +407,7 @@ void ExecuteVisitor::Visit(AccessExpression* node) {
error_handling::HandleRuntimeError("Access index is out of range (string)", node->base); 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 { } else {
info::value::ArrayValue* array_value_info = ExtractValue<info::value::ArrayValue>(current_value_, node->base); info::value::ArrayValue* array_value_info = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
@ -428,7 +422,6 @@ void ExecuteVisitor::Visit(AccessExpression* node) {
// Other Expressions // Other Expressions
// TODO: refactor, separate to several functions // TODO: refactor, separate to several functions
// TODO: more builtin functions, better handling (??)
void ExecuteVisitor::Visit(FunctionCallExpression* node) { void ExecuteVisitor::Visit(FunctionCallExpression* node) {
context_manager_.EnterContext(); context_manager_.EnterContext();
@ -436,6 +429,10 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) { if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value())); Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(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_)) { if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) {
error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base);
} }
@ -456,6 +453,11 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
} else { } else {
if (node->is_method_of_first_argument_) { if (node->is_method_of_first_argument_) {
Visitor::Visit(node->arguments[0]); 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_)) { if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) {
error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); 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()) { if (!maybe_function_declaration_info.has_value()) {
error_handling::HandleRuntimeError("Function declaration not found (for namespace function)", node->base); error_handling::HandleRuntimeError("Function declaration not found (for namespace function)", node->base);
// always namespace function ??
} }
function_declaration = maybe_function_declaration_info.value().node; function_declaration = maybe_function_declaration_info.value().node;
@ -566,8 +567,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) {
type_id = maybe_parameter_type_id.value(); type_id = maybe_parameter_type_id.value();
} }
if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, if (!context_manager_.DefineLocalType(function_declaration->parameters[i]->type, type_id)) {
type_id)) {
error_handling::HandleRuntimeError("Type redefinition (function argument)", node->base); 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) { for (size_t i = (node->is_method_of_first_argument_ ? 1 : 0); i < node->arguments.size(); ++i) {
Visitor::Visit(node->arguments[i]); Visitor::Visit(node->arguments[i]);
// function arguments can't be changed inside function
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
if (!context_manager_.DefineVariable(function_definition->definition->arguments[i], if (!context_manager_.DefineVariable(function_definition->definition->arguments[i],
current_value_)) { current_value_)) {
@ -593,7 +594,7 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
fields.reserve(node->expressions.size()); fields.reserve(node->expressions.size());
for (auto& expression : node->expressions) { for (auto& expression : node->expressions) {
Visitor::Visit(expression); 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( current_value_ = context_manager_.AddValue(
@ -601,14 +602,16 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
utils::ValueType::Tmp); utils::ValueType::Tmp);
} }
// TODO: handle tuples separately ??
void ExecuteVisitor::Visit(VariantExpression* node) { void ExecuteVisitor::Visit(VariantExpression* node) {
// TODO: decide about return type (variant)
for (size_t i = 0; i < node->expressions.size(); ++i) { for (size_t i = 0; i < node->expressions.size(); ++i) {
Visitor::Visit(node->expressions[i]); Visitor::Visit(node->expressions[i]);
current_value_ = context_manager_.ToTemporaryValue(current_value_);
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base); info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
if (expression_value->value.has_value()) { if (expression_value->value.has_value()) {
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields std::vector<std::pair<std::optional<std::string>, 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 variant_tuple =
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()); info::value::TupleValue(std::move(fields), context_manager_.GetValueManager());
@ -645,7 +648,6 @@ void ExecuteVisitor::Visit(TypeConstructorParameter* node) { // handled in TypeC
&node->base); &node->base);
} }
// TODO: check
void ExecuteVisitor::Visit(TypeConstructor* node) { void ExecuteVisitor::Visit(TypeConstructor* node) {
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields; std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
@ -656,14 +658,12 @@ void ExecuteVisitor::Visit(TypeConstructor* node) {
utils::IdType constructor_id = node->constructor->constructor_id_.value(); utils::IdType constructor_id = node->constructor->constructor_id_.value();
info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id); info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id);
// Visit(node->constructor.get()); // use parameters from type expression ??
fields.reserve(node->parameters.size()); fields.reserve(node->parameters.size());
for (auto& parameter : node->parameters) { for (auto& parameter : node->parameters) {
Visitor::Visit(parameter.value); Visitor::Visit(parameter.value);
// TODO: copy/move parameters
fields.push_back( fields.push_back(
{ parameter.name.has_value() ? std::optional<std::string>(parameter.name.value()) : std::nullopt, { parameter.name.has_value() ? std::optional<std::string>(parameter.name.value()) : std::nullopt,
current_value_ }); context_manager_.ToTemporaryValue(current_value_) });
} }
if (constructor_info.order.has_value()) { // => variant if (constructor_info.order.has_value()) { // => variant
@ -692,7 +692,7 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
elements.reserve(node->elements.size()); elements.reserve(node->elements.size());
for (auto& element : node->elements) { for (auto& element : node->elements) {
Visitor::Visit(element); Visitor::Visit(element);
elements.push_back(current_value_); elements.push_back(context_manager_.ToTemporaryValue(current_value_));
} }
current_value_ = context_manager_.AddValue( 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_); utils::ValueType variable_value_type = context_manager_.GetValueType(current_value_);
for (size_t i = 1; i < node->names.size(); ++i) { for (size_t i = 1; i < node->names.size(); ++i) {
std::optional<utils::IdType> maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i]); // TODO std::optional<utils::IdType> maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i]);
if (!maybe_field_value.has_value()) { if (!maybe_field_value.has_value()) {
error_handling::HandleRuntimeError("Variable field not found", node->base); 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_; utils::IdType value = current_value_;
std::optional<info::value::TupleValue*> maybe_tuple_value = context_manager_.GetValue<info::value::TupleValue>(value); std::optional<info::value::TupleValue*> maybe_tuple_value = context_manager_.GetValue<info::value::TupleValue>(value);
@ -761,6 +761,8 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
void ExecuteVisitor::Visit(VariantName* node) { void ExecuteVisitor::Visit(VariantName* node) {
utils::IdType value = current_value_; utils::IdType value = current_value_;
auto value_type = context_manager_.GetValueType(value);
std::optional<info::value::VariantValue*> maybe_variant_value = context_manager_.GetValue<info::value::VariantValue>(value); std::optional<info::value::VariantValue*> maybe_variant_value = context_manager_.GetValue<info::value::VariantValue>(value);
if (!maybe_variant_value.has_value()) { if (!maybe_variant_value.has_value()) {
@ -772,49 +774,46 @@ void ExecuteVisitor::Visit(VariantName* node) {
if (maybe_variant_value.value()->value.fields.empty()) { if (maybe_variant_value.value()->value.fields.empty()) {
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()), info::value::InternalValue(info::value::Unit()),
utils::IsConstModifierToValueType(is_const_definition_.value())); utils::ValueType::Tmp);
// TODO: check, that same with typecheck
} else { } else {
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
maybe_variant_value.value()->value, 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()), info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::IsConstModifierToValueType(is_const_definition_.value())); value_type);
} else { } else {
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()), info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
utils::IsConstModifierToValueType(is_const_definition_.value())); utils::ValueType::Tmp);
} }
Visitor::Visit(node->names[i]); 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; current_value_ = value;
} }
void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check // TODO: move, etc.
utils::IdType value = current_value_; void ExecuteVisitor::Visit(AnnotatedName* node) {
if (!is_const_definition_.has_value()) { if (!is_const_definition_.has_value()) {
error_handling::HandleInternalError("No value in is_const_definition_", error_handling::HandleInternalError("No value in is_const_definition_",
"TypeCheckVisitor.AnnotatedName", "TypeCheckVisitor.AnnotatedName",
&node->base); &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::Tmp) {
// if (value_type == utils::ValueType::Const // consume temporary value
// && is_const_definition_.value() == utils::IsConstModifier::Var) { context_manager_.ModifiyValue(current_value_, IsConstModifierToValueType(is_const_definition_.value()));
// error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base); } 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_)) { if (!context_manager_.DefineVariable(node->name, current_value_)) {
error_handling::HandleRuntimeError("Variable name already present in context", node->base); 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()) { switch (node.index()) {
case 0: 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<std::unique_ptr<NameIdentifier>>(node), if (!context_manager_.DefineVariable(*std::get<std::unique_ptr<NameIdentifier>>(node),
value)) { value)) {
error_handling::HandleRuntimeError("Can't redifine variable", base_node); error_handling::HandleRuntimeError("Can't redifine variable", base_node);
@ -981,7 +981,7 @@ bool ExecuteVisitor::HandleBuiltinFunctionCall(FunctionCallExpression* node) {
} else if (node->name == "scan") { } else if (node->name == "scan") {
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()), current_value_ = context_manager_.AddValue(info::value::InternalValue(info::builtin::Read<std::string>()),
utils::ValueType::Tmp); 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()), current_value_ = context_manager_.AddValue(info::value::InternalValue(rand()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
} else { } else {
@ -1009,7 +1009,8 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base)); arguments.push_back(ExtractValue<info::value::InternalValue>(current_value_, node->base));
} }
error_handling::DebugPrint(info::type::ToString(type)); // error_handling::DebugPrint(info::type::ToString(type));
// std::cout << std::endl;
switch (type) { switch (type) {
case info::type::InternalType::Float: case info::type::InternalType::Float:
@ -1051,11 +1052,9 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node,
info::value::InternalValue(std::to_string(*arguments[0]->GetValue<int64_t>().value())), info::value::InternalValue(std::to_string(*arguments[0]->GetValue<int64_t>().value())),
utils::ValueType::Tmp); utils::ValueType::Tmp);
} else if (name == "<") { } else if (name == "<") {
error_handling::DebugPrint("_");/*
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() < *arguments[1]->GetValue<int64_t>().value()), info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() < *arguments[1]->GetValue<int64_t>().value()),
utils::ValueType::Tmp);*/ utils::ValueType::Tmp);
error_handling::DebugPrint("aaaaaaaa");
} else if (name == "==") { } else if (name == "==") {
current_value_ = context_manager_.AddValue( current_value_ = context_manager_.AddValue(
info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() == *arguments[1]->GetValue<int64_t>().value()), info::value::InternalValue(*arguments[0]->GetValue<int64_t>().value() == *arguments[1]->GetValue<int64_t>().value()),

View file

@ -37,8 +37,8 @@ std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string&) co
return std::nullopt; return std::nullopt;
} }
utils::IdType InternalValue::DeepCopy(ValueManager* value_manager) { utils::IdType InternalValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) {
return value_manager->ExplicitAddValue(InternalValue(value), utils::ValueType::Tmp); return value_manager->ExplicitAddValue(InternalValue(value), new_value_type);
} }
// //
@ -65,16 +65,16 @@ std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name)
return std::nullopt; return std::nullopt;
} }
utils::IdType TupleValue::DeepCopy(ValueManager* value_manager) { utils::IdType TupleValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) {
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_copy(fields.size()); std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_copy(fields.size());
for (size_t i = 0; i < fields.size(); ++i) { 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( return value_manager->ExplicitAddValue(
TupleValue(std::move(fields_copy), value_manager), TupleValue(std::move(fields_copy), value_manager),
utils::ValueType::Tmp); new_value_type);
} }
// //
@ -92,8 +92,8 @@ std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name
return value.GetFieldValue(name); return value.GetFieldValue(name);
} }
utils::IdType VariantValue::DeepCopy(ValueManager* value_manager) { utils::IdType VariantValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) {
auto maybe_tuple_deep_copy = value_manager->GetValue<TupleValue>(value.DeepCopy(value_manager)); auto maybe_tuple_deep_copy = value_manager->GetValue<TupleValue>(value.DeepCopy(value_manager, new_value_type));
if (!maybe_tuple_deep_copy) { if (!maybe_tuple_deep_copy) {
error_handling::HandleInternalError("Deep copied TupleType in not TupleType", error_handling::HandleInternalError("Deep copied TupleType in not TupleType",
@ -103,7 +103,7 @@ utils::IdType VariantValue::DeepCopy(ValueManager* value_manager) {
return value_manager->ExplicitAddValue( return value_manager->ExplicitAddValue(
VariantValue(TupleValue(*maybe_tuple_deep_copy.value()), current_constructor), VariantValue(TupleValue(*maybe_tuple_deep_copy.value()), current_constructor),
utils::ValueType::Tmp); new_value_type);
} }
// //
@ -124,10 +124,10 @@ std::optional<utils::IdType> ReferenceToValue::GetFieldValue(const std::string&
return value_manager_->GetAnyValue(value)->GetFieldValue(name); 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( return value_manager->ExplicitAddValue(
ReferenceToValue(references, value_manager_->GetAnyValue(value)->DeepCopy(value_manager), value_manager), ReferenceToValue(references, value_manager_->GetAnyValue(value)->DeepCopy(value_manager, new_value_type), value_manager),
utils::ValueType::Tmp); new_value_type);
} }
@ -156,10 +156,10 @@ std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string&) co
return std::nullopt; 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( return value_manager->ExplicitAddValue(
FunctionValue(function, value_manager), FunctionValue(function, value_manager),
utils::ValueType::Tmp); new_value_type);
} }
// //
@ -181,16 +181,16 @@ std::optional<utils::IdType> ArrayValue::GetFieldValue(const std::string&) const
return std::nullopt; return std::nullopt;
} }
utils::IdType ArrayValue::DeepCopy(ValueManager* value_manager) { utils::IdType ArrayValue::DeepCopy(ValueManager* value_manager, utils::ValueType new_value_type) {
std::vector<utils::IdType> elements_copy(elements.size()); std::vector<utils::IdType> elements_copy(elements.size());
for (size_t i = 0; i < elements.size(); ++i) { 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( return value_manager->ExplicitAddValue(
ArrayValue(std::move(elements_copy), is_constant_size, value_manager), ArrayValue(std::move(elements_copy), is_constant_size, value_manager),
utils::ValueType::Tmp); new_value_type);
} }
// //
@ -210,7 +210,7 @@ std::optional<utils::IdType> OptionalValue::GetFieldValue(const std::string&) co
return std::nullopt; 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()) { if (!value.has_value()) {
return value_manager->ExplicitAddValue( return value_manager->ExplicitAddValue(
OptionalValue(std::nullopt, value_manager), OptionalValue(std::nullopt, value_manager),
@ -218,8 +218,8 @@ utils::IdType OptionalValue::DeepCopy(ValueManager* value_manager) {
} }
return value_manager->ExplicitAddValue( return value_manager->ExplicitAddValue(
OptionalValue(value_manager_->GetAnyValue(value.value())->DeepCopy(value_manager), value_manager), OptionalValue(value_manager_->GetAnyValue(value.value())->DeepCopy(value_manager, new_value_type), value_manager),
utils::ValueType::Tmp); new_value_type);
} }
// //
@ -279,24 +279,24 @@ std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) const
return std::nullopt; 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(); size_t index = value.index();
switch (index) { switch (index) {
case 0: case 0:
return std::get<InternalValue>(value).DeepCopy(value_manager); return std::get<InternalValue>(value).DeepCopy(value_manager, new_value_type);
case 1: case 1:
return std::get<TupleValue>(value).DeepCopy(value_manager); return std::get<TupleValue>(value).DeepCopy(value_manager, new_value_type);
case 2: case 2:
return std::get<VariantValue>(value).DeepCopy(value_manager); return std::get<VariantValue>(value).DeepCopy(value_manager, new_value_type);
case 3: case 3:
return std::get<ReferenceToValue>(value).DeepCopy(value_manager); return std::get<ReferenceToValue>(value).DeepCopy(value_manager, new_value_type);
case 4: case 4:
return std::get<FunctionValue>(value).DeepCopy(value_manager); return std::get<FunctionValue>(value).DeepCopy(value_manager, new_value_type);
case 5: case 5:
return std::get<ArrayValue>(value).DeepCopy(value_manager); return std::get<ArrayValue>(value).DeepCopy(value_manager, new_value_type);
case 6: case 6:
return std::get<OptionalValue>(value).DeepCopy(value_manager); return std::get<OptionalValue>(value).DeepCopy(value_manager, new_value_type);
default: default:
// error // error
break; break;