mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-07 07:28:44 +00:00
fixes, part of execute_visitor
This commit is contained in:
parent
7d96fe5a86
commit
802b736e15
7 changed files with 345 additions and 92 deletions
|
|
@ -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(¶meter);
|
||||
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(¶meter);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue