From 94805c8662769143bea9b310f87d233c3bb96b77 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 17 May 2023 15:49:15 +0300 Subject: [PATCH] binary operator expression repalced with function call expression --- include/build_visitor.hpp | 6 +- include/execute_visitor.hpp | 1 - include/find_symbols_visitor.hpp | 1 - include/interpreter_tree.hpp | 33 ++--- include/link_symbols_visitor.hpp | 1 - include/print_visitor.hpp | 1 - include/type_check_visitor.hpp | 7 +- include/typed_print_visitor.hpp | 1 - include/visitor.hpp | 1 - src/build_visitor.cpp | 47 ++++--- src/execute_visitor.cpp | 57 ++++---- src/print_visitor.cpp | 14 +- src/type_check_visitor.cpp | 232 ++++++++++--------------------- src/typed_print_visitor.cpp | 21 +-- src/visitor.cpp | 11 +- 15 files changed, 165 insertions(+), 269 deletions(-) diff --git a/include/build_visitor.hpp b/include/build_visitor.hpp index aed992d..2d0b3e3 100644 --- a/include/build_visitor.hpp +++ b/include/build_visitor.hpp @@ -78,7 +78,6 @@ private: // Operators - void Visit(BinaryOperatorExpression* node) override; void Visit(ReferenceExpression* node) override; void Visit(AccessExpression* node) override; @@ -139,6 +138,11 @@ private: void Visit(BoolLiteral* node) override; void Visit(Literal& node) override; // variant + + // + + void VisitBinaryOperatorExpression(FunctionCallExpression* node); + private: const parser::ParseTree& parse_tree_; parser::ParseTree::Node current_node_; diff --git a/include/execute_visitor.hpp b/include/execute_visitor.hpp index b3a3057..b776ec8 100644 --- a/include/execute_visitor.hpp +++ b/include/execute_visitor.hpp @@ -80,7 +80,6 @@ private: // Operators - void Visit(BinaryOperatorExpression* node) override; void Visit(ReferenceExpression* node) override; void Visit(AccessExpression* node) override; diff --git a/include/find_symbols_visitor.hpp b/include/find_symbols_visitor.hpp index ac9588a..b5a6ef2 100644 --- a/include/find_symbols_visitor.hpp +++ b/include/find_symbols_visitor.hpp @@ -63,7 +63,6 @@ private: // Operators - // // void Visit(BinaryOperatorExpression* node) override; // // void Visit(ReferenceExpression* node) override; // // void Visit(AccessExpression* node) override; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index c4ac003..4532436 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -129,12 +129,10 @@ using SubExpressionToken = std::variant< std::unique_ptr>; // struct FunctionCallExpression; -struct BinaryOperatorExpression; struct ArrayExpression; struct ReferenceExpression; -using SubExpression = std::variant< +using SubExpression = std::variant< // BiaryOperatorExpression is FunctionCallExpression std::unique_ptr, - std::unique_ptr, std::unique_ptr, std::unique_ptr>; // @@ -171,7 +169,6 @@ struct ScopedStatement; // Operators -struct BinaryOperatorExpression; struct ReferenceExpression; // Other expressions @@ -482,17 +479,17 @@ struct ScopedStatement { // Operators ----------------- -struct BinaryOperatorExpression { - BaseNode base; - - OperatorIdentifier operator_name; - SubExpression left_expression; - SubExpression right_expression; - size_t precedence = utils::MaxOperatorPrecedence; - - utils::IdType function_id_; - bool is_method_ = false; -}; +// struct BinaryOperatorExpression { +// BaseNode base; +// +// OperatorIdentifier operator_name; +// SubExpression left_expression; +// SubExpression right_expression; +// size_t precedence = utils::MaxOperatorPrecedence; +// +// utils::IdType function_id_; +// bool is_method_ = false; +// }; struct ReferenceExpression { BaseNode base; @@ -517,11 +514,15 @@ struct FunctionCallExpression { std::unique_ptr>> prefix; NameOrOperatorIdentifier name; std::vector> parameters; - std::vector arguments; + std::vector arguments; + + std::optional precedence; // for operators + bool is_binary_operator_expression = false; // for operators // only one from two is present std::optional function_id_; std::optional typeclass_graph_id_; + bool is_method_of_first_argument_ = false; }; struct TupleExpression { diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp index f54aa5d..6adc3c9 100644 --- a/include/link_symbols_visitor.hpp +++ b/include/link_symbols_visitor.hpp @@ -69,7 +69,6 @@ private: // Operators - // // void Visit(BinaryOperatorExpression* node) override; // // void Visit(ReferenceExpression* node) override; // // void Visit(AccessExpression* node) override; diff --git a/include/print_visitor.hpp b/include/print_visitor.hpp index 02cbb04..c13aac1 100644 --- a/include/print_visitor.hpp +++ b/include/print_visitor.hpp @@ -61,7 +61,6 @@ private: // Operators - void Visit(BinaryOperatorExpression* node) override; void Visit(ReferenceExpression* node) override; void Visit(AccessExpression* node) override; diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 54a26cb..d7bf32b 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -71,7 +71,6 @@ private: // Operators - void Visit(BinaryOperatorExpression* node) override; void Visit(ReferenceExpression* node) override; void Visit(AccessExpression* node) override; @@ -142,14 +141,16 @@ private: std::optional - FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, - SubExpressionToken* expression_node); + FindExpressionMethodAndUpdate(FunctionCallExpression* node, + utils::IdType expression_type); std::optional FindTypeFunctionAndUpdate(FunctionCallExpression* node, TypeExpression* type_node, std::unordered_map& context); + std::optional FindFunctionAndUpdate(FunctionCallExpression* node); + std::optional FindAbstractTypeTypeclassFunctionAndUpdate( FunctionCallExpression* node, diff --git a/include/typed_print_visitor.hpp b/include/typed_print_visitor.hpp index 10450a3..faf7012 100644 --- a/include/typed_print_visitor.hpp +++ b/include/typed_print_visitor.hpp @@ -63,7 +63,6 @@ private: // Operators - void Visit(BinaryOperatorExpression* node) override; void Visit(ReferenceExpression* node) override; void Visit(AccessExpression* node) override; diff --git a/include/visitor.hpp b/include/visitor.hpp index acfbded..3ba14b3 100644 --- a/include/visitor.hpp +++ b/include/visitor.hpp @@ -75,7 +75,6 @@ protected: // Operators - virtual void Visit(BinaryOperatorExpression* node); virtual void Visit(ReferenceExpression* node); virtual void Visit(AccessExpression* node); diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 6a209d3..947357c 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -763,8 +763,8 @@ void BuildVisitor::Visit(SubExpression& node) { node = std::make_unique(); Visit(std::get>(node).get()); } else if (current_node_type == parser::tokens::BinaryOperatorExpression) { - node = std::make_unique(); - Visit(std::get>(node).get()); + node = std::make_unique(); + VisitBinaryOperatorExpression(std::get>(node).get()); } else if (current_node_type == parser::tokens::SubExpressionToken) { node = std::make_unique(); Visit(*std::get>(node)); @@ -869,38 +869,39 @@ void BuildVisitor::Visit(ScopedStatement* node) { // Operators -void BuildVisitor::Visit(BinaryOperatorExpression* node) { +void BuildVisitor::VisitBinaryOperatorExpression(FunctionCallExpression* node) { SetPosition(node->base, current_node_); auto parse_node = current_node_; - current_node_ = parse_node.ChildByFieldName("left_expression"); - Visit(node->left_expression); + node->is_binary_operator_expression = true; + node->arguments.resize(2); - node->operator_name = parse_node.ChildByFieldName("operator_name").GetValue(); + current_node_ = parse_node.ChildByFieldName("left_expression"); + Visit(node->arguments[0]); + + node->name = parse_node.ChildByFieldName("operator_name").GetValue(); { // remove operator precedence markers size_t operator_size = 0; - for (; operator_size < node->operator_name.size() && node->operator_name[operator_size] != '.'; ++operator_size) {} - - node->precedence = utils::MaxOperatorPrecedence - (node->operator_name.size() - operator_size); - - node->operator_name = node->operator_name.substr(0, operator_size); + for (; operator_size < node->name.size() && node->name[operator_size] != '.'; ++operator_size) {} + node->precedence = utils::MaxOperatorPrecedence - (node->name.size() - operator_size); + node->name = node->name.substr(0, operator_size); } current_node_ = parse_node.ChildByFieldName("right_expression"); - Visit(node->right_expression); + Visit(node->arguments[1]); // ?? - if (std::holds_alternative>(node->left_expression) - && std::get>(node->left_expression)->precedence >= node->precedence) { - error_handling::HandleParsingError("Operators can't be chained", node->base.start_position, node->base.end_position); - } - - // ?? - if (std::holds_alternative>(node->right_expression) - && std::get>(node->right_expression)->precedence >= node->precedence) { - error_handling::HandleParsingError("Operators can't be chained", node->base.start_position, node->base.end_position); + for (size_t i = 0; i < node->arguments.size(); ++i) { + if (std::holds_alternative>(node->arguments[i])) { + FunctionCallExpression* argument_node = std::get>(node->arguments[i]).get(); + if (argument_node->is_binary_operator_expression + && argument_node->precedence.has_value() + && argument_node->precedence.value() >= node->precedence.value()) { + error_handling::HandleParsingError("Operators can't be chained (left argument)", node->base.start_position, node->base.end_position); + } + } } current_node_ = parse_node; @@ -991,8 +992,8 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { node->parameters.push_back(std::make_unique()); Visit(node->parameters.back().get()); } else { - node->arguments.emplace_back(); - Visit(node->arguments.back()); + node->arguments.push_back(std::make_unique()); + Visit(*std::get>(node->arguments.back())); } } } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index 70e14f8..f64c98a 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -315,32 +315,35 @@ void ExecuteVisitor::Visit(LoopControlExpression& node) { // Operators -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(); -} +// 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(); +// } +///////////////////////////////////////////////// void ExecuteVisitor::Visit(ReferenceExpression* node) { // TODO: check, that there is no references to "Tmp"?? @@ -371,6 +374,8 @@ void ExecuteVisitor::Visit(AccessExpression* node) { // Other Expressions +// TODO: typeclass methods +// TODO: binary operator expression void ExecuteVisitor::Visit(FunctionCallExpression* node) { context_manager_.EnterContext(); if (node->prefix.has_value()) { diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index d362f5f..e5fef7c 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -380,16 +380,6 @@ void PrintVisitor::Visit(LoopControlExpression& node) { // enum // Operators -void PrintVisitor::Visit(BinaryOperatorExpression* node) { - out_ << "[BinaryOperator] ("; - Visitor::Visit(node->left_expression); - out_ << ") ["; - Visit(&node->operator_name); - out_ << "] ("; - Visitor::Visit(node->right_expression); - out_ << ')'; -} - void PrintVisitor::Visit(ReferenceExpression* node) { out_ << "[ReferenceExpression "; for (auto& reference : node->references) { @@ -423,6 +413,10 @@ void PrintVisitor::Visit(AccessExpression* node) { void PrintVisitor::Visit(FunctionCallExpression* node) { out_ << "[FunctionCall "; + if (node->is_binary_operator_expression) { + out_ << "(binary operation) "; + } + if (node->prefix.has_value()) { out_ << '('; if (std::holds_alternative>(node->prefix.value())) { diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 1c909e9..6bbff14 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -665,102 +665,6 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum // Operators -// TODO: better structure -void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { - // TODO: Check, that type is not abstract ?? - auto maybe_operator_id = namespace_visitor_.FindFunctionId(std::nullopt, node->operator_name); - info::definition::Function* operator_info = nullptr; - - node->is_method_ = false; - - if (maybe_operator_id.has_value()) { - operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value()); - node->is_method_ = false; - } else { - Visitor::Visit(node->left_expression); - auto maybe_left_type = context_manager_.GetValue(current_type_); - - utils::ValueType left_value_type = context_manager_.GetValueType(current_type_); - - if (!maybe_left_type.has_value()) { - error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base); - } - - auto maybe_left_type_info = global_info_.GetTypeInfo(maybe_left_type.value()->GetTypeId()); - - std::string left_type_name = maybe_left_type_info.value()->type.type; - - auto maybe_const_operator_id = namespace_visitor_.FindMethodId(std::nullopt, - left_type_name, - node->operator_name, - utils::IsConstModifier::Const); - - if (left_value_type != utils::ValueType::Const) { - maybe_operator_id = namespace_visitor_.FindMethodId(std::nullopt, - left_type_name, - node->operator_name, - utils::IsConstModifier::Var); - } - - if (!maybe_operator_id.has_value() && !maybe_const_operator_id.has_value()) { - error_handling::HandleTypecheckError("Operator not found (method name not found)", node->base); - } - - if (maybe_operator_id.has_value() && maybe_const_operator_id.has_value()) { - error_handling::HandleTypecheckError("Ambigious operator (const and var method)", node->base); - } - - if (!maybe_operator_id.has_value()) { - maybe_operator_id = maybe_const_operator_id; - } - - operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value()); - node->is_method_ = true; - } - - if (!operator_info->declaration.has_value()) { - error_handling::HandleTypecheckError("Operator declaration not found", node->base); - } - - if (!operator_info->definition.has_value()) { // TODO: builtin, etc. - error_handling::HandleTypecheckError("Operator definition not found", node->base); - } - - if (operator_info->argument_count != (node->is_method_ ? 2 : 3)) { // 2 + return type - error_handling::HandleTypecheckError("Operator wrong argument count", node->base); - } - - if (operator_info->declaration->parameters.size() > 0) { - error_handling::HandleTypecheckError("Operator with parameters", node->base); - } - - if (!node->is_method_) { - - Visitor::Visit(*operator_info->declaration.value().argument_types[0]); - utils::IdType left_expression_type = current_type_; - - Visitor::Visit(node->left_expression); - if (!context_manager_.AddValueRequirement(current_type_, left_expression_type)) { - error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base); - } - - } - - Visitor::Visit(*operator_info->declaration.value().argument_types[node->is_method_ ? 0 : 1]); - utils::IdType right_expression_type = current_type_; - - Visitor::Visit(node->right_expression); - if (!context_manager_.AddValueRequirement(current_type_, right_expression_type)) { - error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base); - } - - node->function_id_ = maybe_operator_id.value(); // IMPORTANT - - Visitor::Visit(*operator_info->declaration.value().argument_types.back()); - - node->base.type_ = current_type_; -} - void TypeCheckVisitor::Visit(ReferenceExpression* node) { Visit(node->expression.get()); @@ -808,9 +712,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { // try to find function declaration if (node->prefix.has_value()) { if (std::holds_alternative>(node->prefix.value())) { - maybe_function_declaration = FindSubExpressionMethodAndUpdate( - node, - std::get>(node->prefix.value()).get()); + Visitor::Visit(*std::get>(node->prefix.value())); + maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_); } else if (std::holds_alternative>(node->prefix.value())) { maybe_function_declaration = FindTypeFunctionAndUpdate( node, @@ -821,58 +724,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { "TypeCheckVisitor.FunctionCallExpression"); } } else { - std::optional maybe_function_id; - - if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { - std::string namespace_name = - namespace_visitor_.GetCurrentNamespace()->type_name; - utils::ClassInternalsModifier namespace_modifier = - namespace_visitor_.GetCurrentNamespace()->modifier; - namespace_visitor_.ExitNamespace(); - - maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); - if (!maybe_function_id.has_value()) { - // call functions from static namespace of current type - std::vector current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name }; - maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!! - } - - namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier); - } else { - maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); - } - - if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) { - node->function_id_ = maybe_function_id.value(); - maybe_function_declaration = - global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; - } else { - maybe_function_declaration = std::nullopt; - } - - // try to find typeclass function in for parent namespaces (check definition ??) - if (!maybe_function_declaration.has_value()) { - // TODO: check - auto path_types = namespace_visitor_.GetCurrentPathTypes(); - if (!path_types.empty()) { - for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize - auto maybe_type_info = global_info_.GetTypeInfo(path_types[i]); - if (!maybe_type_info.has_value()) { - error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType", - "TypeCheckVisitor.FindTypeFunctionAndUpdate"); - } - - maybe_function_declaration = - FindDefinedTypeTypeclassFunctionAndUpdate(node, - maybe_type_info.value(), - false); - - if (maybe_function_declaration.has_value()) { - break; - } - } - } - } + maybe_function_declaration = FindFunctionAndUpdate(node); } // function declaration check @@ -898,10 +750,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } // check arguments - if (function_declaration->type->types.size() != node->arguments.size() + 1) { + if (function_declaration->type->types.size() != node->arguments.size() + (node->is_method_of_first_argument_ ? 0 : 1)) { error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base); } - for (size_t i = 0; i < node->arguments.size(); ++i) { + for (size_t i = (node->is_method_of_first_argument_ ? 1 : 0); i < node->arguments.size(); ++i) { Visitor::Visit(function_declaration->type->types[i]); utils::IdType argument_type = TypeInContext(current_type_, context); @@ -1494,13 +1346,10 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) { // TODO: internal types ?? std::optional - TypeCheckVisitor::FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, - SubExpressionToken* expression_node) { + TypeCheckVisitor::FindExpressionMethodAndUpdate(FunctionCallExpression* node, + utils::IdType expression_type) { std::optional maybe_function_declaration; - Visitor::Visit(*expression_node); - utils::IdType expression_type = current_type_; - auto maybe_abstract_type_info = context_manager_.GetValue(expression_type); if (maybe_abstract_type_info.has_value()) { @@ -1615,6 +1464,73 @@ std::optional return maybe_function_declaration; } +std::optional TypeCheckVisitor::FindFunctionAndUpdate(FunctionCallExpression* node) { + std::optional maybe_function_declaration; + std::optional maybe_function_id; + + if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { + std::string namespace_name = + namespace_visitor_.GetCurrentNamespace()->type_name; + utils::ClassInternalsModifier namespace_modifier = + namespace_visitor_.GetCurrentNamespace()->modifier; + namespace_visitor_.ExitNamespace(); + + maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); + if (!maybe_function_id.has_value()) { + // call functions from static namespace of current type + std::vector current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name }; + maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!! + } + + namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier); + } else { + maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); + } + + if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) { + node->function_id_ = maybe_function_id.value(); + maybe_function_declaration = + global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; + } else { + maybe_function_declaration = std::nullopt; + } + + // call as method of first argument // TODO: earlier?? + if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0) { + Visitor::Visit(node->arguments[0]); + maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_); + if (maybe_function_declaration.has_value()) { + node->is_method_of_first_argument_ = true; + } + } + + // try to find typeclass function in for parent namespaces (check definition ??) + if (!maybe_function_declaration.has_value()) { + // TODO: check + auto path_types = namespace_visitor_.GetCurrentPathTypes(); + if (!path_types.empty()) { + for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize + auto maybe_type_info = global_info_.GetTypeInfo(path_types[i]); + if (!maybe_type_info.has_value()) { + error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType", + "TypeCheckVisitor.FindTypeFunctionAndUpdate"); + } + + maybe_function_declaration = + FindDefinedTypeTypeclassFunctionAndUpdate(node, + maybe_type_info.value(), + false); + + if (maybe_function_declaration.has_value()) { + break; + } + } + } + } + + return maybe_function_declaration; +} + std::optional TypeCheckVisitor::FindAbstractTypeTypeclassFunctionAndUpdate( FunctionCallExpression* node, diff --git a/src/typed_print_visitor.cpp b/src/typed_print_visitor.cpp index 9cb18ee..7234403 100644 --- a/src/typed_print_visitor.cpp +++ b/src/typed_print_visitor.cpp @@ -531,22 +531,6 @@ void TypedPrintVisitor::Visit(LoopControlExpression& node) { // enum // Operators -void TypedPrintVisitor::Visit(BinaryOperatorExpression* node) { - out_ << "[BinaryOperator : "; - - if (node->base.type_.has_value()) { - out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName(); - } - - out_ << "] ("; - Visitor::Visit(node->left_expression); - out_ << ") ["; - Visit(&node->operator_name); - out_ << "] ("; - Visitor::Visit(node->right_expression); - out_ << ')'; -} - void TypedPrintVisitor::Visit(ReferenceExpression* node) { out_ << "[ReferenceExpression : ("; @@ -597,6 +581,11 @@ void TypedPrintVisitor::Visit(FunctionCallExpression* node) { } out_ << ") "; + + if (node->is_binary_operator_expression) { + out_ << "(binary operation) "; + } + if (node->prefix.has_value()) { out_ << '('; if (std::holds_alternative>(node->prefix.value())) { diff --git a/src/visitor.cpp b/src/visitor.cpp index 967d168..b5d7220 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -146,12 +146,9 @@ void Visitor::Visit(SubExpression& node) { Visit(std::get>(node).get()); break; case 1: - Visit(std::get>(node).get()); - break; - case 2: Visit(*std::get>(node)); break; - case 3: + case 2: Visit(std::get>(node).get()); break; default: @@ -468,12 +465,6 @@ void Visitor::Visit(LoopControlExpression& node) {} // enum // Operators -void Visitor::Visit(BinaryOperatorExpression* node) { - Visit(node->left_expression); - Visit(&node->operator_name); - Visit(node->right_expression); -} - void Visitor::Visit(ReferenceExpression* node) { Visit(node->expression.get()); }