2023-05-07 20:21:19 +03:00
// for clangd
# include "../include/execute_visitor.hpp"
2023-05-09 14:55:04 +03:00
# include <cwchar>
# include <optional>
# include <variant>
2023-05-07 20:21:19 +03:00
// TODO
namespace interpreter {
// Sources -----------------
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( SourceFile * node ) { // never used ??
2023-05-07 20:21:19 +03:00
for ( auto & statement : node - > statements ) {
Visitor : : Visit ( statement ) ;
}
}
// Namespaces, partitions -----------------
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( NamespaceSources * node ) { // never used ??
2023-05-07 20:21:19 +03:00
for ( auto & statement : node - > statements ) {
Visitor : : Visit ( statement ) ;
}
}
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( Namespace * node ) { // never used ??
// Visit(&node->type);
2023-05-07 20:21:19 +03:00
Visit ( & node - > scope ) ;
}
// Definitions -----------------
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( ImportStatement * node ) { } // no value
void ExecuteVisitor : : Visit ( AliasDefinitionStatement * node ) { } // no value
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
void ExecuteVisitor : : Visit ( VariableDefinitionStatement * node ) { // visited on function call
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > value ) ;
2023-05-09 17:42:35 +03:00
is_const_definition_ = node - > modifier ;
Visitor : : Visit ( node - > name ) ; // current_type_ passed from value
is_const_definition_ = std : : nullopt ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( FunctionDeclaration * node ) { } // no value
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
void ExecuteVisitor : : Visit ( FunctionDefinitionStatement * node ) { // visited on function call
2023-05-09 14:55:04 +03:00
// Visit(node->definition.get());
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > value ) ;
}
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( TypeDefinitionStatement * node ) { } // no value
void ExecuteVisitor : : Visit ( AbstractTypeDefinitionStatement * node ) { } // no value
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( TypeclassDefinitionStatement * node ) { } // no value
2023-05-07 20:21:19 +03:00
2023-05-08 20:34:36 +03:00
void ExecuteVisitor : : Visit ( PartitionStatement * node ) {
2023-05-07 22:58:15 +03:00
Visitor : : Visit ( node - > value ) ;
}
2023-05-07 20:21:19 +03:00
// Flow control -----------------
2023-05-09 23:36:47 +03:00
void ExecuteVisitor : : Visit ( TypeConstructorPatternParameter * node ) { } // handled in TypeConstructorPattern
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
// TODO
2023-05-17 17:57:56 +03:00
// TODO: tuples
2023-05-10 23:13:50 +03:00
// TODO: non-variant constructor patterns
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( TypeConstructorPattern * node ) {
2023-05-10 23:13:50 +03:00
if ( ! node - > constructor - > constructor_id_ . has_value ( ) ) { // checked in typeckeck visitor ??
error_handling : : HandleRuntimeError ( " Type constructor pattern constructor name not found " , node - > base ) ;
}
utils : : IdType constructor_id = node - > constructor - > constructor_id_ . value ( ) ;
// TODO: not only variants
info : : value : : VariantValue * value_info =
ExtractValue < info : : value : : VariantValue > ( current_value_ , node - > base ) ;
if ( constructor_id ! = value_info - > current_constructor ) {
case_matched_ = false ;
return ;
}
// <--
// extract named parameters ??
for ( size_t i = 0 ; i < node - > parameters . size ( ) ; + + i ) { // not visit if case not matched inside ??
current_value_ = value_info - > value . fields [ i ] . second ;
Visitor : : Visit ( node - > parameters [ i ] . value ) ;
2023-05-07 20:21:19 +03:00
}
}
2023-05-09 23:36:47 +03:00
void ExecuteVisitor : : Visit ( MatchCase * node ) { } // handeled in Match
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( Match * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > value ) ;
2023-05-09 23:36:47 +03:00
utils : : IdType value = current_value_ ;
bool case_choosen = false ;
bool statement_visited = false ;
2023-05-07 20:21:19 +03:00
for ( auto & match_case : node - > matches ) {
2023-05-09 23:36:47 +03:00
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 ( ) ;
}
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
if ( case_choosen ) {
context_manager_ . ExitContext ( ) ;
}
2023-05-13 22:40:33 +03:00
// --- instead of optional return value or throw runtime error ---
// 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(std::nullopt, context_manager_.GetValueManager()),
// utils::ValueType::Tmp);
// }
if ( ! statement_visited ) {
error_handling : : HandleRuntimeError ( " Value match option not found " , node - > base ) ;
2023-05-09 23:36:47 +03:00
}
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( Condition * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-07 20:21:19 +03:00
for ( size_t i = 0 ; i < node - > conditions . size ( ) ; + + i ) {
2023-05-09 15:24:19 +03:00
if ( HandleCondition ( node - > conditions [ i ] , node - > base ) ) {
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > statements [ i ] ) ;
2023-05-09 15:24:19 +03:00
if ( node - > statements . size ( ) = = node - > conditions . size ( ) ) {
current_value_ = context_manager_ . AddValue < info : : value : : OptionalValue > (
2023-05-09 23:36:47 +03:00
info : : value : : OptionalValue ( current_value_ , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 15:24:19 +03:00
utils : : ValueType : : Tmp ) ; // take value type from current_value_ ??
}
return ; // current_value_ passed from statement
}
2023-05-07 20:21:19 +03:00
}
if ( node - > statements . size ( ) > node - > conditions . size ( ) ) {
Visitor : : Visit ( node - > statements [ node - > conditions . size ( ) ] ) ;
2023-05-09 15:24:19 +03:00
} else {
current_value_ = context_manager_ . AddValue < info : : value : : OptionalValue > (
2023-05-10 23:13:50 +03:00
info : : value : : OptionalValue ( std : : nullopt , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 15:24:19 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( DoWhileLoop * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-09 14:55:04 +03:00
std : : vector < utils : : IdType > result ;
do {
Visitor : : Visit ( node - > statement ) ;
if ( active_loop_control_expression_ . has_value ( ) ) {
if ( active_loop_control_expression_ . value ( ) = = LoopControlExpression : : Break ) {
active_loop_control_expression_ = std : : nullopt ;
break ;
}
active_loop_control_expression_ = std : : nullopt ;
continue ;
}
result . push_back ( current_value_ ) ;
} while ( HandleCondition ( node - > condition , node - > base ) ) ;
current_value_ = context_manager_ . AddValue < info : : value : : ArrayValue > (
2023-05-09 23:36:47 +03:00
info : : value : : ArrayValue ( std : : move ( result ) , false , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 14:55:04 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-09 23:36:47 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( WhileLoop * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-09 14:55:04 +03:00
std : : vector < utils : : IdType > result ;
while ( HandleCondition ( node - > condition , node - > base ) ) {
Visitor : : Visit ( node - > statement ) ;
if ( active_loop_control_expression_ . has_value ( ) ) {
if ( active_loop_control_expression_ . value ( ) = = LoopControlExpression : : Break ) {
active_loop_control_expression_ = std : : nullopt ;
break ;
}
active_loop_control_expression_ = std : : nullopt ;
continue ;
}
result . push_back ( current_value_ ) ;
}
current_value_ = context_manager_ . AddValue < info : : value : : ArrayValue > (
2023-05-09 23:36:47 +03:00
info : : value : : ArrayValue ( std : : move ( result ) , false , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 14:55:04 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-09 23:36:47 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( ForLoop * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-09 14:55:04 +03:00
std : : vector < utils : : IdType > result ;
2023-05-09 17:42:35 +03:00
// TODO: extend to different interval types (not only array)
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > interval ) ;
2023-05-09 14:55:04 +03:00
info : : value : : ArrayValue * interval = ExtractValue < info : : value : : ArrayValue > ( current_value_ , node - > base ) ;
for ( auto & value : interval - > elements ) {
current_value_ = value ;
Visitor : : Visit ( node - > variable ) ;
Visitor : : Visit ( node - > statement ) ;
if ( active_loop_control_expression_ . has_value ( ) ) {
if ( active_loop_control_expression_ . value ( ) = = LoopControlExpression : : Break ) {
active_loop_control_expression_ = std : : nullopt ;
break ;
}
active_loop_control_expression_ = std : : nullopt ;
continue ;
}
result . push_back ( current_value_ ) ;
}
current_value_ = context_manager_ . AddValue < info : : value : : ArrayValue > (
2023-05-09 23:36:47 +03:00
info : : value : : ArrayValue ( std : : move ( result ) , false , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 14:55:04 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-09 23:36:47 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( LoopLoop * node ) {
2023-05-09 23:36:47 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-09 14:55:04 +03:00
std : : vector < utils : : IdType > result ;
while ( true ) {
Visitor : : Visit ( node - > statement ) ;
if ( active_loop_control_expression_ . has_value ( ) ) {
if ( active_loop_control_expression_ . value ( ) = = LoopControlExpression : : Break ) {
active_loop_control_expression_ = std : : nullopt ;
break ;
}
active_loop_control_expression_ = std : : nullopt ;
continue ;
}
result . push_back ( current_value_ ) ;
}
current_value_ = context_manager_ . AddValue < info : : value : : ArrayValue > (
2023-05-09 23:36:47 +03:00
info : : value : : ArrayValue ( std : : move ( result ) , false , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 14:55:04 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-09 23:36:47 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
// Statements, expressions, blocks, etc. -----------------
void ExecuteVisitor : : Visit ( Block * node ) {
2023-05-09 15:24:19 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-07 20:21:19 +03:00
for ( auto & statement : node - > statements ) {
2023-05-13 22:40:33 +03:00
returned_value_ = std : : nullopt ;
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( statement ) ;
2023-05-13 22:40:33 +03:00
if ( returned_value_ . has_value ( ) ) {
current_value_ = returned_value_ . value ( ) ;
returned_value_ = std : : nullopt ; // ??
2023-05-09 14:55:04 +03:00
return ;
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-09 15:24:19 +03:00
2023-05-09 14:55:04 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( info : : value : : Unit ( ) ) ,
utils : : ValueType : : Tmp ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( ScopedStatement * node ) {
2023-05-09 17:42:35 +03:00
Visitor : : Visit ( node - > statement ) ; // current_value_ passed from statement
2023-05-07 20:21:19 +03:00
}
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( LoopControlExpression & node ) {
active_loop_control_expression_ = node ;
current_value_ = context_manager_ . AddValue ( info : : value : : InternalValue ( info : : value : : Unit ( ) ) ,
utils : : ValueType : : Tmp ) ; // ??
}
2023-05-07 20:21:19 +03:00
// Operators
2023-05-17 15:49:15 +03:00
// TODO: function call expression used instead
/////////////////////////////////////////////////
// void ExecuteVisitor::Visit(BinaryOperatorExpression* node) {
// context_manager_.EnterContext();
//
// auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
//
// if (maybe_function_definition.has_value()) {
// Visitor::Visit(node->left_expression);
// // TODO: custom argument value types, references, etc.
// current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
// context_manager_.DefineVariable(
// node->is_method_ ? utils::ClassInternalVarName : maybe_function_definition.value().argument_names[0],
// current_value_);
//
// Visitor::Visit(node->left_expression);
// // TODO: custom argument value types, references, etc.
// current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
// context_manager_.DefineVariable(maybe_function_definition.value().argument_names[node->is_method_ ? 0 : 1], current_value_);
//
// Visit(maybe_function_definition.value().node);
// } else {
// // TODO: builtin operators, etc. (imports?)
// error_handling::HandleRuntimeError("Binary operator definition not found", node->base);
// }
//
// context_manager_.ExitContext();
// }
/////////////////////////////////////////////////
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( ReferenceExpression * node ) {
2023-05-09 17:42:35 +03:00
// TODO: check, that there is no references to "Tmp"??
2023-05-07 20:21:19 +03:00
Visit ( node - > expression . get ( ) ) ;
2023-05-09 14:55:04 +03:00
utils : : ValueType value_type = context_manager_ . GetValueType ( current_value_ ) ;
current_value_ = context_manager_ . AddValue (
2023-05-09 23:36:47 +03:00
info : : value : : ReferenceToValue ( node - > references , current_value_ , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 14:55:04 +03:00
value_type ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( AccessExpression * node ) {
2023-05-09 14:55:04 +03:00
// TODO: extend to other types
2023-05-07 20:21:19 +03:00
Visit ( node - > name . get ( ) ) ;
2023-05-09 14:55:04 +03:00
info : : value : : ArrayValue * array_value = ExtractValue < info : : value : : ArrayValue > ( current_value_ , node - > base ) ;
utils : : ValueType value_type = context_manager_ . GetValueType ( current_value_ ) ;
2023-05-07 20:21:19 +03:00
Visitor : : Visit ( node - > id ) ;
2023-05-09 14:55:04 +03:00
long long index = * ExtractInternalValue < long long > ( current_value_ , node - > base ) ; // TODO: size_t
2023-05-10 23:13:50 +03:00
if ( index < 0 | | index > = ( long long ) array_value - > elements . size ( ) ) {
2023-05-09 14:55:04 +03:00
error_handling : : HandleRuntimeError ( " Access index out of range " , node - > base ) ;
}
current_value_ = context_manager_ . ToModifiedValue ( array_value - > elements [ index ] , value_type ) ; // needed ??
2023-05-07 20:21:19 +03:00
}
// Other Expressions
2023-05-17 15:49:15 +03:00
// TODO: typeclass methods
// TODO: binary operator expression
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( FunctionCallExpression * node ) {
2023-05-09 17:42:35 +03:00
context_manager_ . EnterContext ( ) ;
2023-05-07 20:21:19 +03:00
if ( node - > prefix . has_value ( ) ) {
if ( std : : holds_alternative < std : : unique_ptr < SubExpressionToken > > ( node - > prefix . value ( ) ) ) {
Visitor : : Visit ( * std : : get < std : : unique_ptr < SubExpressionToken > > ( node - > prefix . value ( ) ) ) ;
2023-05-09 17:42:35 +03:00
// modify value on const methods, etc. ??
context_manager_ . DefineVariable ( utils : : ClassInternalVarName , current_value_ ) ;
2023-05-07 20:21:19 +03:00
} else if ( std : : holds_alternative < std : : unique_ptr < TypeExpression > > ( node - > prefix . value ( ) ) ) {
2023-05-09 17:42:35 +03:00
TypeExpression & prefix = * std : : get < std : : unique_ptr < TypeExpression > > ( node - > prefix . value ( ) ) ;
// TODO: abstract types, local abstract types, abstract types, ... as path entities
for ( auto & path_type : prefix . path ) {
CollectTypeContext ( path_type ) ;
}
CollectTypeContext ( prefix . type ) ;
2023-05-07 20:21:19 +03:00
} else {
// error
}
}
2023-05-17 11:51:14 +03:00
// TODO: typeclass functions
auto function_declaration = namespace_visitor_ . GetGlobalInfo ( ) - > GetFunctionInfo ( node - > function_id_ . value ( ) ) . declaration . value ( ) ; // checked in type_check_visitor
2023-05-07 20:21:19 +03:00
2023-05-09 17:42:35 +03:00
for ( size_t i = 0 ; i < node - > parameters . size ( ) ; + + i ) {
2023-05-17 11:51:14 +03:00
// TODO: local abstract types, absract types, etc.
2023-05-09 17:42:35 +03:00
context_manager_ . DefineLocalType ( function_declaration . parameters [ i ] . type , node - > parameters [ i ] - > type_id_ . value ( ) ) ; // TODO: check
2023-05-07 20:21:19 +03:00
}
2023-05-17 11:51:14 +03:00
// TODO: typeclass functions
auto maybe_function_definition = namespace_visitor_ . GetGlobalInfo ( ) - > GetFunctionInfo ( node - > function_id_ . value ( ) ) . definition ;
2023-05-09 17:42:35 +03:00
if ( maybe_function_definition . has_value ( ) ) {
for ( size_t i = 0 ; i < node - > arguments . size ( ) ; + + i ) {
Visitor : : Visit ( node - > arguments [ i ] ) ;
// TODO: custom argument value types, references, etc.
current_value_ = context_manager_ . ToModifiedValue ( current_value_ , utils : : ValueType : : Const ) ;
context_manager_ . DefineVariable ( maybe_function_definition . value ( ) . argument_names [ i ] , current_value_ ) ;
}
Visit ( maybe_function_definition . value ( ) . node ) ;
} else {
// TODO: builtin functions, etc. (imports?)
error_handling : : HandleRuntimeError ( " Function definition not found " , node - > base ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
context_manager_ . ExitContext ( ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( TupleExpression * node ) {
2023-05-09 14:55:04 +03:00
std : : vector < std : : pair < std : : optional < std : : string > , utils : : IdType > > fields ;
fields . reserve ( node - > expressions . size ( ) ) ;
2023-05-07 20:21:19 +03:00
for ( auto & expression : node - > expressions ) {
Visitor : : Visit ( expression ) ;
2023-05-09 14:55:04 +03:00
fields . push_back ( { std : : nullopt , current_value_ } ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 14:55:04 +03:00
2023-05-09 15:24:19 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : TupleValue > (
2023-05-09 23:36:47 +03:00
info : : value : : TupleValue ( std : : move ( fields ) , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 15:24:19 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor : : Visit ( VariantExpression * node ) {
// TODO: decide about return type (variant)
2023-05-09 23:36:47 +03:00
for ( size_t i = 0 ; i < node - > expressions . size ( ) ; + + i ) {
Visitor : : Visit ( node - > expressions [ i ] ) ;
2023-05-09 14:55:04 +03:00
info : : value : : OptionalValue * expression_value = ExtractValue < info : : value : : OptionalValue > ( current_value_ , node - > base ) ;
if ( expression_value - > value . has_value ( ) ) {
2023-05-10 23:13:50 +03:00
std : : vector < std : : pair < std : : optional < std : : string > , utils : : IdType > > fields
{ { std : : nullopt , expression_value - > value . value ( ) } } ;
info : : value : : TupleValue variant_tuple =
info : : value : : TupleValue ( std : : move ( fields ) , context_manager_ . GetValueManager ( ) ) ;
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : VariantValue > (
2023-05-10 23:13:50 +03:00
info : : value : : VariantValue ( std : : move ( variant_tuple ) , i ) ,
2023-05-09 17:42:35 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-09 14:55:04 +03:00
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : OptionalValue > (
2023-05-09 23:36:47 +03:00
info : : value : : OptionalValue ( current_value_ , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 17:42:35 +03:00
utils : : ValueType : : Tmp ) ;
return ;
2023-05-09 14:55:04 +03:00
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : OptionalValue > (
2023-05-10 23:13:50 +03:00
info : : value : : OptionalValue ( std : : nullopt , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 17:42:35 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( ReturnExpression * node ) {
Visitor : : Visit ( node - > expression ) ;
2023-05-13 22:40:33 +03:00
returned_value_ = current_value_ ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
void ExecuteVisitor : : Visit ( TypeConstructorParameter * node ) { } // handled in TypeConstructor
2023-05-17 17:57:56 +03:00
// TODO: variants, etc.
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( TypeConstructor * node ) {
2023-05-09 23:36:47 +03:00
// 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 ( ) ) ;
2023-05-07 20:21:19 +03:00
for ( auto & parameter : node - > parameters ) {
2023-05-09 23:36:47 +03:00
Visitor : : Visit ( parameter . value ) ;
// TODO: copy/move parameters
fields . push_back (
2023-05-13 13:11:12 +03:00
{ parameter . name . has_value ( ) ? std : : optional < std : : string > ( parameter . name . value ( ) ) : std : : nullopt ,
2023-05-09 23:36:47 +03:00
current_value_ } ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : TupleValue > (
info : : value : : TupleValue ( std : : move ( fields ) , context_manager_ . GetValueManager ( ) ) ,
utils : : ValueType : : Tmp ) ;
2023-05-17 17:57:56 +03:00
// if (constructor_info.order.has_value()) {
// // TODO: construct variant value
// }
2023-05-07 20:21:19 +03:00
}
2023-05-09 14:55:04 +03:00
// TODO
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( LambdaFunction * node ) {
2023-05-09 14:55:04 +03:00
error_handling : : HandleInternalError ( " Lambda function are not implemented yet " ,
" ExecuteVisitor.LambdaFunction " ) ;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor : : Visit ( ArrayExpression * node ) {
2023-05-09 15:24:19 +03:00
std : : vector < utils : : IdType > elements ;
elements . reserve ( node - > elements . size ( ) ) ;
2023-05-07 20:21:19 +03:00
for ( auto & element : node - > elements ) {
Visitor : : Visit ( element ) ;
2023-05-09 15:24:19 +03:00
elements . push_back ( current_value_ ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 15:24:19 +03:00
current_value_ = context_manager_ . AddValue < info : : value : : ArrayValue > (
2023-05-09 23:36:47 +03:00
info : : value : : ArrayValue ( std : : move ( elements ) , true , context_manager_ . GetValueManager ( ) ) , // maybe size not fixed??
2023-05-09 15:24:19 +03:00
utils : : ValueType : : Tmp ) ;
2023-05-07 20:21:19 +03:00
}
// Name
2023-05-09 17:47:43 +03:00
void ExecuteVisitor : : Visit ( NameExpression * node ) { // TODO: check
2023-05-09 17:42:35 +03:00
if ( node - > names . empty ( ) ) {
error_handling : : HandleInternalError ( " Names array is empty " , " ExecuteVisitor.NameExpression " ) ;
}
std : : optional < utils : : IdType > maybe_variable_value =
2023-05-13 13:11:12 +03:00
context_manager_ . GetVariableInfo ( node - > names [ 0 ] ) ;
2023-05-09 17:42:35 +03:00
if ( ! maybe_variable_value . has_value ( ) ) {
error_handling : : HandleRuntimeError ( " Variable not found " , node - > base ) ;
}
current_value_ = maybe_variable_value . value ( ) ;
if ( node - > names . size ( ) > 1 ) {
utils : : ValueType variable_value_type = context_manager_ . GetValueType ( current_value_ ) ;
for ( size_t i = 1 ; i < node - > names . size ( ) ; + + i ) {
2023-05-13 13:11:12 +03:00
std : : optional < utils : : IdType > maybe_field_value = context_manager_ . GetAnyValue ( current_value_ ) - > GetFieldValue ( node - > names [ i ] ) ; // TODO
2023-05-09 17:42:35 +03:00
if ( ! maybe_field_value . has_value ( ) ) {
2023-05-13 13:11:12 +03:00
error_handling : : HandleRuntimeError ( " Variable field not found " , node - > base ) ;
2023-05-09 17:42:35 +03:00
}
current_value_ = maybe_field_value . value ( ) ;
}
current_value_ = context_manager_ . ToModifiedValue ( current_value_ , variable_value_type ) ;
2023-05-07 20:21:19 +03:00
}
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor : : Visit ( TupleName * node ) { // TODO: check
utils : : IdType value = current_value_ ;
std : : optional < info : : value : : TupleValue * > maybe_tuple_value = context_manager_ . GetValue < info : : value : : TupleValue > ( value ) ;
if ( maybe_tuple_value . has_value ( ) ) {
error_handling : : HandleRuntimeError ( " Mismatched value types in tuple variable definition " , node - > base ) ;
}
if ( maybe_tuple_value . value ( ) - > fields . size ( ) ! = node - > names . size ( ) ) {
error_handling : : HandleRuntimeError ( " Mismatched field count in tuple variable definition " , node - > base ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
if ( ! is_const_definition_ . has_value ( ) ) {
error_handling : : HandleInternalError ( " No value in is_const_definition_ " , " TypeCheckVisitor.TupleName " ) ;
}
utils : : ValueType value_type = context_manager_ . GetValueType ( value ) ;
if ( value_type = = utils : : ValueType : : Const
& & is_const_definition_ . value ( ) = = utils : : IsConstModifier : : Var ) {
error_handling : : HandleRuntimeError ( " TupleName: value type expression not match variable definition modifier " , node - > base ) ;
}
for ( size_t i = 0 ; i < node - > names . size ( ) ; + + i ) {
current_value_ = maybe_tuple_value . value ( ) - > fields [ i ] . second ;
if ( value_type = = utils : : ValueType : : Tmp ) { // TODO: ??
current_value_ = context_manager_ . ToModifiedValue ( current_value_ , utils : : ValueType : : Tmp ) ;
}
Visitor : : Visit ( node - > names [ i ] ) ;
}
current_value_ = value ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
// TODO
2023-05-09 23:36:47 +03:00
// TODO: make variant of TupleValue
2023-05-07 20:21:19 +03:00
void ExecuteVisitor : : Visit ( VariantName * node ) {
2023-05-09 17:42:35 +03:00
utils : : IdType value = current_value_ ;
std : : optional < info : : value : : VariantValue * > maybe_variant_value = context_manager_ . GetValue < info : : value : : VariantValue > ( value ) ;
if ( ! maybe_variant_value . has_value ( ) ) {
error_handling : : HandleRuntimeError ( " Mismatched value types in variant variable definition " , node - > base ) ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
2023-05-09 23:36:47 +03:00
for ( size_t i = 0 ; i < node - > names . size ( ) ; + + i ) {
if ( i = = maybe_variant_value . value ( ) - > current_constructor ) {
2023-05-10 23:13:50 +03:00
if ( maybe_variant_value . value ( ) - > value . fields . empty ( ) ) {
current_value_ = context_manager_ . AddValue (
info : : value : : InternalValue ( info : : value : : Unit ( ) ) ,
utils : : IsConstModifierToValueType ( is_const_definition_ . value ( ) ) ) ;
// TODO: check, that same with typecheck
} else {
current_value_ = context_manager_ . AddValue (
maybe_variant_value . value ( ) - > value ,
utils : : IsConstModifierToValueType ( is_const_definition_ . value ( ) ) ) ;
}
2023-05-09 23:36:47 +03:00
current_value_ = context_manager_ . AddValue (
2023-05-10 23:13:50 +03:00
info : : value : : OptionalValue ( current_value_ , context_manager_ . GetValueManager ( ) ) ,
utils : : IsConstModifierToValueType ( is_const_definition_ . value ( ) ) ) ;
2023-05-09 23:36:47 +03:00
} else {
current_value_ = context_manager_ . AddValue (
2023-05-10 23:13:50 +03:00
info : : value : : OptionalValue ( std : : nullopt , context_manager_ . GetValueManager ( ) ) ,
2023-05-09 23:36:47 +03:00
utils : : IsConstModifierToValueType ( is_const_definition_ . value ( ) ) ) ;
}
Visitor : : Visit ( node - > names [ i ] ) ;
}
2023-05-09 17:42:35 +03:00
// TODO: find out, which constructor used
// set value to that constructor and None (empty OptionalValue) to others
current_value_ = value ;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor : : Visit ( AnnotatedName * node ) { // TODO: check
utils : : IdType value = current_value_ ;
if ( ! is_const_definition_ . has_value ( ) ) {
error_handling : : HandleInternalError ( " No value in is_const_definition_ " ,
" TypeCheckVisitor.AnnotatedName " ) ;
}
utils : : ValueType value_type = context_manager_ . GetValueType ( current_value_ ) ;
if ( value_type = = utils : : ValueType : : Const
& & is_const_definition_ . value ( ) = = utils : : IsConstModifier : : Var ) {
error_handling : : HandleRuntimeError ( " AnnotatedName: value type expression not match variable definition modifier " , node - > base ) ;
}
current_value_ = context_manager_ . ToModifiedValue ( value , utils : : IsConstModifierToValueType ( is_const_definition_ . value ( ) ) ) ;
if ( ! context_manager_ . DefineVariable ( node - > name , current_value_ ) ) {
error_handling : : HandleRuntimeError ( " Variable name already present in context " , node - > base ) ;
2023-05-07 20:21:19 +03:00
}
}
// Type, typeclass, etc. -----------------
// Type
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( FunctionType * node ) { } // no value
void ExecuteVisitor : : Visit ( TupleType * node ) { } // no value
void ExecuteVisitor : : Visit ( VariantType * node ) { } // no value
void ExecuteVisitor : : Visit ( TypeExpression * node ) { } // no value
void ExecuteVisitor : : Visit ( ExtendedScopedAnyType * node ) { } // no value
2023-05-07 20:21:19 +03:00
// Typeclass
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( ParametrizedTypeclass * node ) { } // no value
2023-05-07 20:21:19 +03:00
// Typeclass & Type -----------------
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( ParametrizedType * node ) { } // no value
2023-05-07 20:21:19 +03:00
// Identifiers, constants, etc. -----------------
2023-05-09 14:55:04 +03:00
// void ExecuteVisitor::Visit(ExtendedName* node) {}
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
// void ExecuteVisitor::Visit(std::string* node) {} // std::string
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( FloatNumberLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( node - > value ) ,
utils : : ValueType : : Tmp ) ;
}
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( NumberLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( node - > value ) ,
utils : : ValueType : : Tmp ) ;
}
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( StringLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( node - > value ) ,
utils : : ValueType : : Tmp ) ;
}
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( CharLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( node - > value ) ,
utils : : ValueType : : Tmp ) ;
}
void ExecuteVisitor : : Visit ( UnitLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( info : : value : : Unit ( ) ) ,
utils : : ValueType : : Tmp ) ;
}
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
void ExecuteVisitor : : Visit ( BoolLiteral * node ) {
current_value_ = context_manager_ . AddValue < info : : value : : InternalValue > (
info : : value : : InternalValue ( node - > value ) ,
utils : : ValueType : : Tmp ) ;
}
//
2023-05-07 20:21:19 +03:00
2023-05-09 14:55:04 +03:00
bool ExecuteVisitor : : HandleCondition ( Expression & node , const BaseNode & base_node ) {
Visitor : : Visit ( node ) ;
return * ExtractInternalValue < bool > ( current_value_ , base_node ) ;
}
2023-05-08 20:34:36 +03:00
2023-05-09 17:42:35 +03:00
// TODO: handle abstract types, handle local abstract types, etc.
void ExecuteVisitor : : CollectTypeContext ( const ParametrizedType & type ) {
if ( ! type . type_id_ . has_value ( ) ) {
return ;
}
auto maybe_type_info = namespace_visitor_ . GetGlobalInfo ( ) - > GetTypeInfo < info : : definition : : AnyType > ( type . type_id_ . value ( ) ) ;
if ( ! maybe_type_info . has_value ( ) ) {
error_handling : : HandleInternalError ( " CollectTypeContext unimplemented anything except AnyType " , " ExecuteVisitor.CollectTYpeContext " ) ;
}
info : : definition : : AnyType & type_info = * maybe_type_info . value ( ) ; // check, that has value ??
for ( size_t i = 0 ; i < type . parameters . size ( ) ; + + i ) {
if ( type . parameters [ i ] - > type_id_ . has_value ( ) ) {
context_manager_ . DefineLocalType ( type_info . parameters [ i ] . type ,
type . parameters [ i ] - > type_id_ . value ( ) ) ;
2023-05-09 23:36:47 +03:00
}
}
}
// 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 ) ; // ??
2023-05-13 13:11:12 +03:00
if ( ! context_manager_ . DefineVariable ( * std : : get < std : : unique_ptr < NameIdentifier > > ( node ) ,
2023-05-09 23:36:47 +03:00
value ) ) {
error_handling : : HandleRuntimeError ( " Can't redifine variable " , base_node ) ;
}
break ;
case 1 :
Visitor : : Visit ( * std : : get < std : : unique_ptr < Literal > > ( node ) ) ;
2023-05-10 23:13:50 +03:00
error_handling : : HandleInternalError ( " Unimplemented EqualValues " , " ExecuteVisitor.CheckPattern " ) ;
// if (!context_manager_.EqualValues(current_value_, value)) { // TODO
// case_matched_ = false;
// }
2023-05-09 23:36:47 +03:00
break ;
case 2 :
Visit ( std : : get < std : : unique_ptr < TypeConstructorPattern > > ( node ) . get ( ) ) ;
break ;
default :
// error
break ;
2023-05-09 17:42:35 +03:00
}
}
2023-05-07 20:21:19 +03:00
} // namespace interpreter