mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +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_;
|
||||
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_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
Visitor::Visit(node->value);
|
||||
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;
|
||||
Visitor::Visit(statement);
|
||||
if (returned_value_.has_value()) {
|
||||
brought_value_ = std::nullopt;
|
||||
break;
|
||||
}
|
||||
if (brought_value_.has_value()) {
|
||||
try {
|
||||
Visitor::Visit(statement);
|
||||
} 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),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue