returned / brounght value handling in execute_visitor (fixes)

This commit is contained in:
ProgramSnail 2023-05-21 11:58:23 +03:00
parent f6b50b16ae
commit bad48a1da0
5 changed files with 113 additions and 58 deletions

View file

@ -174,8 +174,6 @@ private:
utils::IdType current_value_;
std::optional<LoopControlExpression> active_loop_control_expression_;
std::optional<utils::IdType> returned_value_;
std::optional<utils::IdType> brought_value_;
std::optional<utils::IsConstModifier> is_const_definition_;
bool case_matched_;
};

View file

@ -16,6 +16,9 @@ using IdType = size_t;
const std::string ClassInternalVarName = "self";
const size_t MaxOperatorPrecedence = 4;
struct ValueReturnedMarker {};
struct ValueBroughtMarker {};
enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 };
enum class IsConstModifier { Const = 0, Var = 1 };
enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2};

View file

@ -12,31 +12,41 @@ namespace interpreter {
// Sources -----------------
void ExecuteVisitor::Visit(SourceFile* node) { // never used ??
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
void ExecuteVisitor::Visit(SourceFile* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.SourceFile",
&node->base);
}
// Namespaces, partitions -----------------
void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ??
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
void ExecuteVisitor::Visit(NamespaceSources* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.NamespaceSources",
&node->base);
}
void ExecuteVisitor::Visit(Namespace* node) { // never used ??
// Visit(&node->type);
Visit(&node->scope);
void ExecuteVisitor::Visit(Namespace* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.Namespace",
&node->base);
}
// Definitions -----------------
void ExecuteVisitor::Visit(ImportStatement*) {} // no value
void ExecuteVisitor::Visit(AliasDefinitionStatement*) {} // no value
void ExecuteVisitor::Visit(ImportStatement* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.ImportStatement",
&node->base);
}
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call
void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.AliasDefinitionStatement",
&node->base);
}
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) {
Visitor::Visit(node->value);
is_const_definition_ = node->modifier;
@ -44,28 +54,42 @@ void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on fu
is_const_definition_ = std::nullopt;
}
void ExecuteVisitor::Visit(FunctionDeclaration*) {} // no value
void ExecuteVisitor::Visit(FunctionDeclaration* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.FunctionDeclaration",
&node->base);
}
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call
// Visit(node->definition.get());
context_manager_.EnterContext();
returned_value_ = std::nullopt;
try {
Visitor::Visit(node->value);
} catch (utils::ValueReturnedMarker&) {}
if (returned_value_.has_value()) {
current_value_ = returned_value_.value();
} // else returned type = current_type_
returned_value_ = std::nullopt;
// current_value_ passed from visited expression or from ReturnExpression
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(TypeDefinitionStatement*) {} // no value
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement*) {} // no value
void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TypeDefinitionStatement",
&node->base);
}
void ExecuteVisitor::Visit(TypeclassDefinitionStatement*) {} // no value
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.AbstractTypeDefinitionStatement",
&node->base);
}
void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TypeclassDefinitionStatement",
&node->base);
}
void ExecuteVisitor::Visit(PartitionStatement* node) {
Visitor::Visit(node->value);
@ -73,7 +97,11 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
// Flow control -----------------
void ExecuteVisitor::Visit(TypeConstructorPatternParameter*) {} // handled in TypeConstructorPattern
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) { // handled in TypeConstructorPattern
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TypeConstructorPatternParameter",
&node->base);
}
// TODO: check
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
@ -113,7 +141,11 @@ void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
}
}
void ExecuteVisitor::Visit(MatchCase*) {} // handeled in Match
void ExecuteVisitor::Visit(MatchCase* node) { // handeled in Match
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.MatchCase",
&node->base);
}
void ExecuteVisitor::Visit(Match* node) {
context_manager_.EnterContext();
@ -316,24 +348,20 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
void ExecuteVisitor::Visit(Block* node) {
context_manager_.EnterContext();
bool value_brought = false;
for (auto& statement : node->statements) {
brought_value_ = std::nullopt;
try {
Visitor::Visit(statement);
if (returned_value_.has_value()) {
brought_value_ = std::nullopt;
break;
}
if (brought_value_.has_value()) {
} catch (utils::ValueBroughtMarker&) { // current_value_ passed from ReturnExpression
value_brought = true;
break;
}
}
context_manager_.ExitContext();
if (brought_value_.has_value()) {
current_value_ = brought_value_.value();
brought_value_ = std::nullopt;
} else {
if (!value_brought) {
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
@ -580,18 +608,18 @@ void ExecuteVisitor::Visit(VariantExpression* node) {
void ExecuteVisitor::Visit(ReturnExpression* node) {
Visitor::Visit(node->expression);
if (node->is_from_definition) {
returned_value_ = current_value_;
} else {
brought_value_ = current_value_;
throw utils::ValueReturnedMarker();
}
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
throw utils::ValueBroughtMarker();
}
void ExecuteVisitor::Visit(TypeConstructorParameter*) {} // handled in TypeConstructor
void ExecuteVisitor::Visit(TypeConstructorParameter* node) { // handled in TypeConstructor
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TypeConstructorParameter",
&node->base);
}
// TODO: check
void ExecuteVisitor::Visit(TypeConstructor* node) {
@ -786,15 +814,43 @@ void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
// Type
void ExecuteVisitor::Visit(FunctionType*) {} // no value
void ExecuteVisitor::Visit(TupleType*) {} // no value
void ExecuteVisitor::Visit(VariantType*) {} // no value
void ExecuteVisitor::Visit(TypeExpression*) {} // no value
void ExecuteVisitor::Visit(ExtendedScopedAnyType*) {} // no value
void ExecuteVisitor::Visit(FunctionType* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.FunctionType",
&node->base);
}
void ExecuteVisitor::Visit(TupleType* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TupleType",
&node->base);
}
void ExecuteVisitor::Visit(VariantType* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.VariantType",
&node->base);
}
void ExecuteVisitor::Visit(TypeExpression* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.TypeExpression",
&node->base);
}
void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.ExtendedScopedAnyType",
&node->base);
}
// Typeclass
void ExecuteVisitor::Visit(ParametrizedTypeclass*) {} // no value
void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {
error_handling::HandleInternalError("Should be unreachable",
"TypeCheckVisitor.ParametrizedTypeclass",
&node->base);
}
// Typeclass & Type -----------------
@ -802,10 +858,6 @@ void ExecuteVisitor::Visit(ParametrizedType*) {} // no value
// Identifiers, constants, etc. -----------------
// void ExecuteVisitor::Visit(ExtendedName* node) {}
// void ExecuteVisitor::Visit(std::string* node) {} // std::string
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {
current_value_ = context_manager_.AddValue(
info::value::InternalValue(node->value),

View file

@ -661,6 +661,7 @@ void TypeCheckVisitor::Visit(Block* node) {
// TODO: types can be different in statement
all_branches_brought_value_ = true;
brought_type_ = std::nullopt;
context_manager_.EnterContext();
for (auto& statement : node->statements) {

View file

@ -143,7 +143,8 @@ def func : s = {
exec main {
for i in (,0 ,1 ,2 ,3) do func: "abacaba"
; print: ({
if true then bring read: else ()
if true then bring read: else { ; print: "aaa" }
bring "nothing"
; print: "aaa"
})
}