fixes, part of execute_visitor

This commit is contained in:
ProgramSnail 2023-05-09 23:36:47 +03:00
parent 7d96fe5a86
commit 802b736e15
7 changed files with 345 additions and 92 deletions

View file

@ -60,50 +60,82 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
// Flow control -----------------
// TODO
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
if (node->name.has_value()) {
// Visit(&node->name.value());
}
Visitor::Visit(node->value);
}
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {} // handled in TypeConstructorPattern
// TODO
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
// TODO: not only tuples
Visit(node->constructor.get());
for (auto& parameter : node->parameters) {
Visit(&parameter);
Visit(node->constructor.get()); // TODO: ?? check is same constructor_id ??
for (auto& parameter : node->parameters) { // TODO: pass parameters separately
Visitor::Visit(parameter.value); // handle TypeConstructorPatternParameter
}
}
// TODO
void ExecuteVisitor::Visit(MatchCase* node) {
Visitor::Visit(node->value);
if (node->condition.has_value()) {
Visitor::Visit(node->condition.value());
}
if (node->statement.has_value()) {
Visitor::Visit(node->statement.value());
}
}
void ExecuteVisitor::Visit(MatchCase* node) {} // handeled in Match
// TODO
void ExecuteVisitor::Visit(Match* node) {
context_manager_.EnterContext();
Visitor::Visit(node->value);
utils::IdType value = current_value_;
bool case_choosen = false;
bool statement_visited = false;
for (auto& match_case : node->matches) {
Visit(&match_case);
if (case_choosen) {
if (match_case.statement.has_value()) {
Visitor::Visit(match_case.statement.value());
statement_visited = true;
break;
}
} else {
current_value_ = value;
case_matched_ = true;
context_manager_.EnterContext();
Visitor::Visit(node->value);
if (case_matched_ && (match_case.condition.has_value() ? HandleCondition(match_case.condition.value(), match_case.base) : true)) {
case_choosen = true;
if (match_case.statement.has_value()) {
Visitor::Visit(match_case.statement.value());
statement_visited = true;
break;
}
} else {
context_manager_.ExitContext();
}
}
}
if (case_choosen) {
context_manager_.ExitContext();
}
if (statement_visited) {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
} else {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(Condition* node) {
context_manager_.EnterContext();
for (size_t i = 0; i < node->conditions.size(); ++i) {
if (HandleCondition(node->conditions[i], node->base)) {
Visitor::Visit(node->statements[i]);
if (node->statements.size() == node->conditions.size()) {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(current_value_),
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::ValueType::Tmp); // take value type from current_value_ ??
}
return; // current_value_ passed from statement
@ -113,12 +145,16 @@ void ExecuteVisitor::Visit(Condition* node) {
Visitor::Visit(node->statements[node->conditions.size()]);
} else {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(),
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(DoWhileLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
do {
Visitor::Visit(node->statement);
@ -135,11 +171,15 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) {
} while(HandleCondition(node->condition, node->base));
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
info::value::ArrayValue(std::move(result), false),
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<utils::IdType> result;
while(HandleCondition(node->condition, node->base)) {
Visitor::Visit(node->statement);
@ -156,10 +196,14 @@ void ExecuteVisitor::Visit(WhileLoop* node) {
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
info::value::ArrayValue(std::move(result), false),
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(ForLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
// TODO: extend to different interval types (not only array)
@ -184,11 +228,15 @@ void ExecuteVisitor::Visit(ForLoop* node) {
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
info::value::ArrayValue(std::move(result), false),
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<utils::IdType> result;
while(true) {
Visitor::Visit(node->statement);
@ -205,8 +253,10 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
info::value::ArrayValue(std::move(result), false),
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
}
// Statements, expressions, blocks, etc. -----------------
@ -297,7 +347,7 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
current_value_ = context_manager_.AddValue(
info::value::ReferenceToValue(node->references, current_value_),
info::value::ReferenceToValue(node->references, current_value_, context_manager_.GetValueManager()),
value_type);
}
@ -376,29 +426,29 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
}
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
info::value::TupleValue(std::move(fields)),
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
void ExecuteVisitor::Visit(VariantExpression* node) {
// TODO: decide about return type (variant)
for (auto& expression : node->expressions) {
Visitor::Visit(expression);
for (size_t i = 0; i < node->expressions.size(); ++i) {
Visitor::Visit(node->expressions[i]);
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
if (expression_value->value.has_value()) {
current_value_ = context_manager_.AddValue<info::value::VariantValue>(
info::value::VariantValue(expression_value->value.value()),
info::value::VariantValue(expression_value->value.value(), i, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(current_value_),
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
return;
}
}
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(),
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
@ -407,21 +457,27 @@ void ExecuteVisitor::Visit(ReturnExpression* node) {
return_value_ = current_value_;
}
// TODO
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {
if (node->name.has_value()) {
// Visit(&node->name.value());
}
Visitor::Visit(node->value);
}
// TODO
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {} // handled in TypeConstructor
void ExecuteVisitor::Visit(TypeConstructor* node) {
// TODO: not only tuples
Visit(node->constructor.get());
// TODO: support for non-tuples
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
// Visit(node->constructor.get()); // use parameters from type expression ??
fields.reserve(node->parameters.size());
for (auto& parameter : node->parameters) {
Visit(&parameter);
Visitor::Visit(parameter.value);
// TODO: copy/move parameters
fields.push_back(
{ parameter.name.has_value() ? std::optional<std::string>(parameter.name.value().name) : std::nullopt,
current_value_ });
}
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
// TODO
@ -440,7 +496,7 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
info::value::ArrayValue(std::move(elements), true), // maybe size not fixed??
info::value::ArrayValue(std::move(elements), true, context_manager_.GetValueManager()), // maybe size not fixed??
utils::ValueType::Tmp);
}
@ -513,6 +569,7 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
}
// TODO
// TODO: make variant of TupleValue
void ExecuteVisitor::Visit(VariantName* node) {
utils::IdType value = current_value_;
@ -522,6 +579,20 @@ void ExecuteVisitor::Visit(VariantName* node) {
error_handling::HandleRuntimeError("Mismatched value types in variant variable definition", node->base);
}
for (size_t i = 0; i < node->names.size(); ++i) {
if (i == maybe_variant_value.value()->current_constructor) {
// TODO if (fields_count.empty()) ... else ...
current_value_ = context_manager_.AddValue(
info::value::OptionalValue(maybe_variant_value.value()->value, context_manager_.GetValueManager()),
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
} else {
current_value_ = context_manager_.AddValue(
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::IsConstModifierToValueType(is_const_definition_.value()));
}
Visitor::Visit(node->names[i]);
}
// TODO: find out, which constructor used
// set value to that constructor and None (empty OptionalValue) to others
@ -633,6 +704,34 @@ void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
if (type.parameters[i]->type_id_.has_value()) {
context_manager_.DefineLocalType(type_info.parameters[i].type,
type.parameters[i]->type_id_.value());
}
}
}
// TODO
void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
utils::IdType value = current_value_;
switch (node.index()) {
case 0:
value = context_manager_.ToModifiedValue(value, utils::ValueType::Const); // ??
if (!context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
value)) {
error_handling::HandleRuntimeError("Can't redifine variable", base_node);
}
break;
case 1:
Visitor::Visit(*std::get<std::unique_ptr<Literal>>(node));
if (!context_manager_.EqualValues(current_value_, value)) { // TODO
case_matched_ = false;
}
break;
case 2:
Visit(std::get<std::unique_ptr<TypeConstructorPattern>>(node).get());
break;
default:
// error
break;
}
}