mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
returned / brounght value handling in execute_visitor (fixes)
This commit is contained in:
parent
f6b50b16ae
commit
bad48a1da0
5 changed files with 113 additions and 58 deletions
|
|
@ -174,8 +174,6 @@ private:
|
||||||
|
|
||||||
utils::IdType current_value_;
|
utils::IdType current_value_;
|
||||||
std::optional<LoopControlExpression> active_loop_control_expression_;
|
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_;
|
std::optional<utils::IsConstModifier> is_const_definition_;
|
||||||
bool case_matched_;
|
bool case_matched_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ using IdType = size_t;
|
||||||
const std::string ClassInternalVarName = "self";
|
const std::string ClassInternalVarName = "self";
|
||||||
const size_t MaxOperatorPrecedence = 4;
|
const size_t MaxOperatorPrecedence = 4;
|
||||||
|
|
||||||
|
struct ValueReturnedMarker {};
|
||||||
|
struct ValueBroughtMarker {};
|
||||||
|
|
||||||
enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 };
|
enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 };
|
||||||
enum class IsConstModifier { Const = 0, Var = 1 };
|
enum class IsConstModifier { Const = 0, Var = 1 };
|
||||||
enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2};
|
enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2};
|
||||||
|
|
|
||||||
|
|
@ -12,31 +12,41 @@ namespace interpreter {
|
||||||
|
|
||||||
// Sources -----------------
|
// Sources -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(SourceFile* node) { // never used ??
|
void ExecuteVisitor::Visit(SourceFile* node) {
|
||||||
for (auto& statement : node->statements) {
|
error_handling::HandleInternalError("Should be unreachable",
|
||||||
Visitor::Visit(statement);
|
"TypeCheckVisitor.SourceFile",
|
||||||
}
|
&node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespaces, partitions -----------------
|
// Namespaces, partitions -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ??
|
void ExecuteVisitor::Visit(NamespaceSources* node) {
|
||||||
for (auto& statement : node->statements) {
|
error_handling::HandleInternalError("Should be unreachable",
|
||||||
Visitor::Visit(statement);
|
"TypeCheckVisitor.NamespaceSources",
|
||||||
}
|
&node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(Namespace* node) { // never used ??
|
void ExecuteVisitor::Visit(Namespace* node) {
|
||||||
// Visit(&node->type);
|
error_handling::HandleInternalError("Should be unreachable",
|
||||||
Visit(&node->scope);
|
"TypeCheckVisitor.Namespace",
|
||||||
|
&node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definitions -----------------
|
// Definitions -----------------
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ImportStatement*) {} // no value
|
void ExecuteVisitor::Visit(ImportStatement* node) {
|
||||||
void ExecuteVisitor::Visit(AliasDefinitionStatement*) {} // no value
|
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);
|
Visitor::Visit(node->value);
|
||||||
|
|
||||||
is_const_definition_ = node->modifier;
|
is_const_definition_ = node->modifier;
|
||||||
|
|
@ -44,28 +54,42 @@ void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on fu
|
||||||
is_const_definition_ = std::nullopt;
|
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
|
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call
|
||||||
// Visit(node->definition.get());
|
// Visit(node->definition.get());
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
returned_value_ = std::nullopt;
|
try {
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
|
} catch (utils::ValueReturnedMarker&) {}
|
||||||
|
|
||||||
if (returned_value_.has_value()) {
|
// current_value_ passed from visited expression or from ReturnExpression
|
||||||
current_value_ = returned_value_.value();
|
|
||||||
} // else returned type = current_type_
|
|
||||||
|
|
||||||
returned_value_ = std::nullopt;
|
|
||||||
|
|
||||||
context_manager_.ExitContext();
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeDefinitionStatement*) {} // no value
|
void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement*) {} // no value
|
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) {
|
void ExecuteVisitor::Visit(PartitionStatement* node) {
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
|
|
@ -73,7 +97,11 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
|
||||||
|
|
||||||
// Flow control -----------------
|
// 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
|
// TODO: check
|
||||||
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
|
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) {
|
void ExecuteVisitor::Visit(Match* node) {
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
|
|
@ -316,24 +348,20 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
|
||||||
void ExecuteVisitor::Visit(Block* node) {
|
void ExecuteVisitor::Visit(Block* node) {
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
|
bool value_brought = false;
|
||||||
|
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
brought_value_ = std::nullopt;
|
try {
|
||||||
Visitor::Visit(statement);
|
Visitor::Visit(statement);
|
||||||
if (returned_value_.has_value()) {
|
} catch (utils::ValueBroughtMarker&) { // current_value_ passed from ReturnExpression
|
||||||
brought_value_ = std::nullopt;
|
value_brought = true;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (brought_value_.has_value()) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context_manager_.ExitContext();
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
if (brought_value_.has_value()) {
|
if (!value_brought) {
|
||||||
current_value_ = brought_value_.value();
|
|
||||||
brought_value_ = std::nullopt;
|
|
||||||
} else {
|
|
||||||
current_value_ = context_manager_.AddValue(
|
current_value_ = context_manager_.AddValue(
|
||||||
info::value::InternalValue(info::value::Unit()),
|
info::value::InternalValue(info::value::Unit()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
@ -580,18 +608,18 @@ void ExecuteVisitor::Visit(VariantExpression* node) {
|
||||||
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
||||||
Visitor::Visit(node->expression);
|
Visitor::Visit(node->expression);
|
||||||
if (node->is_from_definition) {
|
if (node->is_from_definition) {
|
||||||
returned_value_ = current_value_;
|
throw utils::ValueReturnedMarker();
|
||||||
} else {
|
|
||||||
brought_value_ = current_value_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue(
|
throw utils::ValueBroughtMarker();
|
||||||
info::value::InternalValue(info::value::Unit()),
|
|
||||||
utils::ValueType::Tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
// TODO: check
|
||||||
void ExecuteVisitor::Visit(TypeConstructor* node) {
|
void ExecuteVisitor::Visit(TypeConstructor* node) {
|
||||||
|
|
@ -786,15 +814,43 @@ void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FunctionType*) {} // no value
|
void ExecuteVisitor::Visit(FunctionType* node) {
|
||||||
void ExecuteVisitor::Visit(TupleType*) {} // no value
|
error_handling::HandleInternalError("Should be unreachable",
|
||||||
void ExecuteVisitor::Visit(VariantType*) {} // no value
|
"TypeCheckVisitor.FunctionType",
|
||||||
void ExecuteVisitor::Visit(TypeExpression*) {} // no value
|
&node->base);
|
||||||
void ExecuteVisitor::Visit(ExtendedScopedAnyType*) {} // no value
|
}
|
||||||
|
|
||||||
|
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
|
// Typeclass
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(ParametrizedTypeclass*) {} // no value
|
void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {
|
||||||
|
error_handling::HandleInternalError("Should be unreachable",
|
||||||
|
"TypeCheckVisitor.ParametrizedTypeclass",
|
||||||
|
&node->base);
|
||||||
|
}
|
||||||
|
|
||||||
// Typeclass & Type -----------------
|
// Typeclass & Type -----------------
|
||||||
|
|
||||||
|
|
@ -802,10 +858,6 @@ void ExecuteVisitor::Visit(ParametrizedType*) {} // no value
|
||||||
|
|
||||||
// Identifiers, constants, etc. -----------------
|
// Identifiers, constants, etc. -----------------
|
||||||
|
|
||||||
// void ExecuteVisitor::Visit(ExtendedName* node) {}
|
|
||||||
|
|
||||||
// void ExecuteVisitor::Visit(std::string* node) {} // std::string
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {
|
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {
|
||||||
current_value_ = context_manager_.AddValue(
|
current_value_ = context_manager_.AddValue(
|
||||||
info::value::InternalValue(node->value),
|
info::value::InternalValue(node->value),
|
||||||
|
|
|
||||||
|
|
@ -661,6 +661,7 @@ void TypeCheckVisitor::Visit(Block* node) {
|
||||||
// TODO: types can be different in statement
|
// TODO: types can be different in statement
|
||||||
|
|
||||||
all_branches_brought_value_ = true;
|
all_branches_brought_value_ = true;
|
||||||
|
brought_type_ = std::nullopt;
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,8 @@ def func : s = {
|
||||||
exec main {
|
exec main {
|
||||||
for i in (,0 ,1 ,2 ,3) do func: "abacaba"
|
for i in (,0 ,1 ,2 ,3) do func: "abacaba"
|
||||||
; print: ({
|
; print: ({
|
||||||
if true then bring read: else ()
|
if true then bring read: else { ; print: "aaa" }
|
||||||
bring "nothing"
|
bring "nothing"
|
||||||
|
; print: "aaa"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue