From bb8b32a7c8418c7e482ab410766436c7203d911b Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Thu, 6 Jul 2023 16:15:15 +0300 Subject: [PATCH] bug fixes --- include/contexts.hpp | 6 +- src/build_visitor.cpp | 4 +- src/execute_visitor.cpp | 184 ++++++++++++++++++++++------------------ src/main.cpp | 4 +- tests/test_code.lang | 47 +++++----- 5 files changed, 136 insertions(+), 109 deletions(-) diff --git a/include/contexts.hpp b/include/contexts.hpp index 853701b..f5737aa 100644 --- a/include/contexts.hpp +++ b/include/contexts.hpp @@ -175,9 +175,9 @@ public: return maybe_type.value(); } - if (contexts_[i].IsHidingPrevious()) { - break; - } + // if (contexts_[i].IsHidingPrevious()) { // TODO: old types automatically shadowed by new ?? + // break; + // } } return std::nullopt; } diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index 124c118..92987c4 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -1009,7 +1009,8 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { Visit(node->parameters.back().get()); } else { if (!current_node_.PreviousSibling().IsNull() && current_node_.PreviousSibling().GetValue() == "::") { // annotation - node->arguments.push_back({current_node_.GetValue(), SubExpression()}); + node->arguments.emplace_back(); + node->arguments.back().first = current_node_.GetValue(); last_child_is_annotation = true; } else if (last_child_is_annotation) { // argument after annotation node->arguments.back().second = std::make_unique(); @@ -1018,7 +1019,6 @@ void BuildVisitor::Visit(FunctionCallExpression* node) { } else { // argument without annotation node->arguments.push_back({std::nullopt, std::make_unique()}); Visit(*std::get>(node->arguments.back().second)); - last_child_is_annotation = false; } } } diff --git a/src/execute_visitor.cpp b/src/execute_visitor.cpp index c3e002f..491bd90 100644 --- a/src/execute_visitor.cpp +++ b/src/execute_visitor.cpp @@ -178,7 +178,7 @@ void ExecuteVisitor::Visit(Match* node) { bool case_choosen = false; bool statement_visited = false; for (auto& match_case : node->matches) { - if (case_choosen) { + if (case_choosen && !statement_visited) { if (match_case.statement.has_value()) { Visitor::Visit(match_case.statement.value()); statement_visited = true; @@ -189,9 +189,10 @@ void ExecuteVisitor::Visit(Match* node) { case_matched_ = true; context_manager_.EnterContext(); - Visitor::Visit(node->value); + CheckPattern(match_case.value, match_case.base); - if (case_matched_ && (match_case.condition.has_value() ? HandleCondition(match_case.condition.value(), match_case.base) : true)) { + if (case_matched_ && (!match_case.condition.has_value() || + HandleCondition(match_case.condition.value(), match_case.base))) { case_choosen = true; if (match_case.statement.has_value()) { Visitor::Visit(match_case.statement.value()); @@ -218,7 +219,9 @@ void ExecuteVisitor::Visit(Match* node) { void ExecuteVisitor::Visit(Condition* node) { bool branch_visited = false; for (size_t i = 0; i < node->conditions.size(); ++i) { + error_handling::DebugPrint("in loop"); if (HandleCondition(node->conditions[i], node->base)) { + error_handling::DebugPrint("in condition"); context_manager_.EnterContext(); Visitor::Visit(node->statements[i]); context_manager_.ExitContext(); @@ -231,8 +234,11 @@ void ExecuteVisitor::Visit(Condition* node) { branch_visited = true; break; } + error_handling::DebugPrint("out of condition"); } + error_handling::DebugPrint("after conditions"); + if (!branch_visited) { if (node->statements.size() > node->conditions.size()) { context_manager_.EnterContext(); @@ -448,47 +454,9 @@ void ExecuteVisitor::Visit(AccessExpression* node) { // TODO: refactor, separate to several functions void ExecuteVisitor::Visit(FunctionCallExpression* node) { + context_manager_.EnterContext(); - if (node->prefix.has_value()) { - if (std::holds_alternative>(node->prefix.value())) { - Visitor::Visit(*std::get>(node->prefix.value())); - - if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { - // temporary value can't be modified inside - context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); - } - if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { - error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); - } - } else if (std::holds_alternative>(node->prefix.value())) { - TypeExpression& prefix = *std::get>(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); - } else { - error_handling::HandleInternalError("Unexpected prefix type", - "ExecuteVisitor.FunctionCallExpression", - &node->base); - } - } else { - if (node->is_method_of_first_argument_) { - Visitor::Visit(node->arguments[0].second); - - if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { - // temporary value can't be modified inside - context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); - } - if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { - error_handling::HandleRuntimeError("Variable redefinition (self var)", node->base); - } - } - } - FunctionDeclaration* function_declaration = nullptr; FunctionDefinitionStatement* function_definition = nullptr; @@ -569,7 +537,50 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { } } - // handle choosen type typclasses + // + + // // TODO: check move (was double calculation for builtin functions) + if (node->prefix.has_value()) { + if (std::holds_alternative>(node->prefix.value())) { + Visitor::Visit(*std::get>(node->prefix.value())); + + if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { + // temporary value can't be modified inside + context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); + } + if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { + error_handling::HandleRuntimeError("Variable redefinition (mathod caller var)", node->base); + } + } else if (std::holds_alternative>(node->prefix.value())) { + TypeExpression& prefix = *std::get>(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); + } else { + error_handling::HandleInternalError("Unexpected prefix type", + "ExecuteVisitor.FunctionCallExpression", + &node->base); + } + } else { + if (node->is_method_of_first_argument_) { + Visitor::Visit(node->arguments[0].second); + + if (context_manager_.GetValueType(current_value_) == utils::ValueType::Tmp) { + // temporary value can't be modified inside + context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const); + } + if (!context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_)) { + error_handling::HandleRuntimeError("Variable redefinition (self var)", node->base); + } + } + } + // // + + // handle choosen type typeclasses // handle parameters for (size_t i = 0; i < node->parameters.size(); ++i) { @@ -581,6 +592,7 @@ void ExecuteVisitor::Visit(FunctionCallExpression* node) { auto maybe_parameter_graph_id = context_manager_.FindLocalType(node->parameters[i]->type.type); if (!maybe_parameter_graph_id.has_value()) { + error_handling::DebugPrint(node->parameters[i]->type.type); error_handling::HandleInternalError("Parameter type not found", "ExecuteVisitor.FunctionCallExpression", &node->base); @@ -982,7 +994,9 @@ void ExecuteVisitor::Visit(BoolLiteral* node) { // bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node) { + error_handling::DebugPrint("handle condition begin"); Visitor::Visit(node); + error_handling::DebugPrint("handle condition end"); return *ExtractInternalValue(current_value_, base_node); } @@ -1076,17 +1090,17 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, const std::string& name = node->name; if (utils::IsBuiltinFunction(name)) { - std::vector arguments; + std::vector arguments; arguments.reserve(node->arguments.size()); if (node->prefix.has_value() && std::holds_alternative>(node->prefix.value())) { Visitor::Visit(*std::get>(node->prefix.value())); - arguments.push_back(ExtractValue(current_value_, node->base)); + arguments.push_back(*ExtractValue(current_value_, node->base)); } for (auto& argument : node->arguments) { Visitor::Visit(argument.second); - arguments.push_back(ExtractValue(current_value_, node->base)); + arguments.push_back(*ExtractValue(current_value_, node->base)); } switch (type) { @@ -1094,22 +1108,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, if (name == "show") { try { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), + info::value::InternalValue(std::to_string(*arguments[0].GetValue().value())), utils::ValueType::Tmp); } catch(...) { error_handling::HandleRuntimeError("Can't read Float", node->base); } } else if (name == "read") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::stod(*arguments[0]->GetValue().value())), + info::value::InternalValue(std::stod(*arguments[0].GetValue().value())), utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() == *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "zero") { current_value_ = context_manager_.AddValue( @@ -1120,27 +1134,27 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1.0), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "+=") { - *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() += *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "-=") { - *arguments[0]->GetValue().value() -= *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() -= *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "*=") { - *arguments[0]->GetValue().value() *= *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() *= *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "/=") { - *arguments[0]->GetValue().value() /= *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() /= *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1151,31 +1165,35 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Int: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::to_string(*arguments[0]->GetValue().value())), + info::value::InternalValue(std::to_string(*arguments[0].GetValue().value())), utils::ValueType::Tmp); } else if (name == "read") { try { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::stoi(*arguments[0]->GetValue().value())), + info::value::InternalValue(std::stoi(*arguments[0].GetValue().value())), utils::ValueType::Tmp); } catch(...) { error_handling::HandleRuntimeError("Can't read Int", node->base); } } else if (name == "<") { + error_handling::DebugPrint("< Args:"); + error_handling::DebugPrint(*arguments[0].GetValue().value()); + error_handling::DebugPrint(*arguments[1].GetValue().value()); current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), utils::ValueType::Tmp); + error_handling::DebugPrint(*ExtractInternalValue(current_value_, node->base)); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() == *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "div") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() / *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() / *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "mod") { // TODO: better implementation of mod (read "%" specification) current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() % *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() % *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "zero") { current_value_ = context_manager_.AddValue( @@ -1186,22 +1204,22 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue(1), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "+=") { - *arguments[0]->GetValue().value() += *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() += *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "-=") { - *arguments[0]->GetValue().value() -= *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() -= *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } else if (name == "*=") { - *arguments[0]->GetValue().value() *= *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() *= *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1212,30 +1230,30 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::String: if (name == "show") { // do not copy ?? current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value()), utils::ValueType::Tmp); } else if (name == "read") { // do not copy ?? current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value()), utils::ValueType::Tmp); } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() == *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "size") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(static_cast(arguments[0]->GetValue().value()->size())), + info::value::InternalValue(static_cast(arguments[0].GetValue().value()->size())), utils::ValueType::Tmp); } else if (name == "at") { current_value_ = context_manager_.AddValue( - info::value::InternalValue((*arguments[0]->GetValue().value())[*arguments[1]->GetValue().value()]), + info::value::InternalValue((*arguments[0].GetValue().value())[*arguments[1].GetValue().value()]), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1246,26 +1264,26 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Char: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(std::string{*arguments[0]->GetValue().value()}), + info::value::InternalValue(std::string{*arguments[0].GetValue().value()}), utils::ValueType::Tmp); } else if (name == "read") { - if (arguments[0]->GetValue().value()->size() != 1) { + if (arguments[0].GetValue().value()->size() != 1) { error_handling::HandleRuntimeError("Can't read Char", node->base); } else { current_value_ = context_manager_.AddValue( - info::value::InternalValue((*arguments[0]->GetValue().value())[0]), + info::value::InternalValue((*arguments[0].GetValue().value())[0]), utils::ValueType::Tmp); } } else if (name == "<") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() < *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() < *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "==") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() == *arguments[1]->GetValue().value()), + info::value::InternalValue(*arguments[0].GetValue().value() == *arguments[1].GetValue().value()), utils::ValueType::Tmp); } else if (name == "=") { - *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1276,14 +1294,14 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, case info::type::InternalType::Bool: if (name == "show") { current_value_ = context_manager_.AddValue( - info::value::InternalValue(*arguments[0]->GetValue().value() ? "true" : "false"), + info::value::InternalValue(*arguments[0].GetValue().value() ? "true" : "false"), utils::ValueType::Tmp); } else if (name == "read") { - if (*arguments[0]->GetValue().value() == "true") { + if (*arguments[0].GetValue().value() == "true") { current_value_ = context_manager_.AddValue( info::value::InternalValue(true), utils::ValueType::Tmp); - } else if (*arguments[0]->GetValue().value() == "false") { + } else if (*arguments[0].GetValue().value() == "false") { current_value_ = context_manager_.AddValue( info::value::InternalValue(false), utils::ValueType::Tmp); @@ -1291,7 +1309,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, error_handling::HandleRuntimeError("Can't read Bool", node->base); } } else if (name == "=") { - *arguments[0]->GetValue().value() = *arguments[1]->GetValue().value(); + *arguments[0].GetValue().value() = *arguments[1].GetValue().value(); current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); @@ -1305,7 +1323,7 @@ bool ExecuteVisitor::HandleBuiltinTypeFunctionCall(FunctionCallExpression* node, info::value::InternalValue("()"), utils::ValueType::Tmp); } else if (name == "read") { - if (*arguments[0]->GetValue().value() != "()") { + if (*arguments[0].GetValue().value() != "()") { error_handling::HandleRuntimeError("Can't read Unit", node->base); } current_value_ = context_manager_.AddValue( diff --git a/src/main.cpp b/src/main.cpp index 63d259b..13eb48e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -86,9 +86,9 @@ int main(int argc, char** argv) { // TODO, only test version type_context_manager, context_manager); - try { + //try { execute_visitor.ExecutePartition(main_partition.node); - } catch (...) { error_handling::HandleInternalError("execute_visitor exception", "main", std::nullopt); } + //} catch (...) { error_handling::HandleInternalError("execute_visitor exception", "main", std::nullopt); } // std::cout << "\n---------------------------------- Typed -------------------------------------\n\n"; // typed_print_visitor.VisitSourceFile(source_file.get()); diff --git a/tests/test_code.lang b/tests/test_code.lang index 3f27fc7..bcb91ca 100644 --- a/tests/test_code.lang +++ b/tests/test_code.lang @@ -19,10 +19,17 @@ decl error : \string -> \unit // decl not : \bool -> \bool -def not : x = - (match x with +def not : x = { + ; print-anything:[bool] x + ; print-anything:[bool] + (match x with + | true -> false + | false -> true) + + return (match x with | true -> false | false -> true) +} // @@ -188,6 +195,10 @@ decl ( -- ) : \int -> \int -> \int`0 def ( -- ) : begin end = { var current = begin return (while current < end do { + ; print-anything:[string] "iteration:" + ; print-anything:[int] begin + ; print-anything:[int] current + ; print-anything:[int] end ; current += 1 bring current - 1 }) @@ -258,24 +269,22 @@ decl scan-three : -> (& \string & \string & \string) def scan-three = & \io..scan: & \io..scan: & \io..scan: exec main { - var n = scan-anything:[int] + var n = \int..read: (\io..scan:) - ; print-anything:[bool] (n < 2) // TODO: fix exception (arguments not present ??) + if n <= 0 then error: "n can't be less then 1" - if n > 1 then print-anything:[string] "aaa" // not work (??) + // var x = (for _ in 0--n do scan-int:) // $array[int] & 0 - var x = (for _ in 0--n do scan-int:) // $array[int] & 0 - - var k? = if n < 2 then n * 2 +. 3 in - , print-anything:[string] "n < 2" - , print-anything:[int] k - - ; print-anything:[int] n - - ; print-int: ::x 123 - - var & a & b & c = scan-three-t: - ; \io..print: b - var & d & e & f = scan-three: - ; \io..print: e +// var k? = if n < 2 then n * 2 +. 3 in +// , print-anything:[string] "n < 2" +// , print-anything:[int] k +// +// ; print-anything:[int] n +// +// ; print-int: ::x 123 +// +// var & a & b & c = scan-three-t: +// ; \io..print: b +// var & d & e & f = scan-three: +// ; \io..print: e }