From f4ffb11be49f157876ec66620d732a7e161ad27b Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 13 Dec 2019 17:49:21 +0100
Subject: [PATCH] print statement and redesign results of batches

---
 alib2cli/src/ast/command/PrintCommand.h       | 37 ++++++++++++++++
 .../src/ast/statements/ResultPrintStatement.h | 32 --------------
 alib2cli/src/parser/Parser.cpp                | 43 ++++++++-----------
 alib2cli/src/parser/Parser.h                  |  6 +--
 alib2cli/test-src/cli/CliTest.cpp             | 14 +++---
 .../test-src/tests/approximateMatching.cpp    |  2 +-
 .../test-src/tests/exactMatching.cpp          |  2 +-
 7 files changed, 67 insertions(+), 69 deletions(-)
 create mode 100644 alib2cli/src/ast/command/PrintCommand.h
 delete mode 100644 alib2cli/src/ast/statements/ResultPrintStatement.h

diff --git a/alib2cli/src/ast/command/PrintCommand.h b/alib2cli/src/ast/command/PrintCommand.h
new file mode 100644
index 0000000000..07deead9d6
--- /dev/null
+++ b/alib2cli/src/ast/command/PrintCommand.h
@@ -0,0 +1,37 @@
+#ifndef _CLI_PRINT_COMMAND_H_
+#define _CLI_PRINT_COMMAND_H_
+
+#include <ast/Command.h>
+#include <environment/Environment.h>
+#include <ast/Statement.h>
+
+#include <global/GlobalData.h>
+#include <registry/Registry.h>
+
+namespace cli {
+
+class PrintCommand : public Command {
+	std::shared_ptr < Statement > m_command;
+
+public:
+	PrintCommand ( std::shared_ptr < Statement > command ) : m_command ( std::move ( command ) ) {
+	}
+
+	CommandResult run ( Environment & environment ) const override {
+		std::shared_ptr < abstraction::Value > value = m_command->translateAndEval ( nullptr, environment );
+
+		std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getValuePrinterAbstraction ( value->getType ( ) );
+
+		res->attachInput ( value, 0, false );
+		res->attachInput ( std::make_shared < abstraction::ValueHolder < std::ostream & > > ( nullptr, common::Streams::out, false ), 1, false );
+		std::shared_ptr < abstraction::Value > result = res->eval ( );
+		if ( ! result )
+			throw std::invalid_argument ( "Eval of result print statement failed." );
+
+		return CommandResult::OK;
+	}
+};
+
+} /* namespace cli */
+
+#endif /* _CLI_PRINT_COMMAND_H_ */
diff --git a/alib2cli/src/ast/statements/ResultPrintStatement.h b/alib2cli/src/ast/statements/ResultPrintStatement.h
deleted file mode 100644
index dc0636a8d3..0000000000
--- a/alib2cli/src/ast/statements/ResultPrintStatement.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _CLI_RESULT_PRINT_STATEMENT_H_
-#define _CLI_RESULT_PRINT_STATEMENT_H_
-
-#include <ast/Statement.h>
-#include <global/GlobalData.h>
-#include <registry/Registry.h>
-
-namespace cli {
-
-class ResultPrintStatement final : public Statement {
-public:
-	ResultPrintStatement ( ) = default;
-
-	std::shared_ptr < abstraction::Value > translateAndEval ( const std::shared_ptr < abstraction::Value > & prev, Environment & ) const override {
-		std::shared_ptr < abstraction::OperationAbstraction > res = abstraction::Registry::getValuePrinterAbstraction ( prev->getType ( ) );
-
-		if ( res->numberOfParams ( ) == 0 )
-			return std::make_shared < abstraction::Void > ( nullptr );
-
-		res->attachInput ( prev, 0, false );
-		res->attachInput ( std::make_shared < abstraction::ValueHolder < std::ostream & > > ( nullptr, common::Streams::out, false ), 1, false );
-		std::shared_ptr < abstraction::Value > result = res->eval ( );
-		if ( ! result )
-			throw std::invalid_argument ( "Eval of result print statement failed." );
-		return result;
-	}
-
-};
-
-} /* namespace cli */
-
-#endif /* _CLI_RESULT_PRINT_STATEMENT_H_ */
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index 9adf10bf62..19e8628aaf 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -5,7 +5,6 @@
 #include <ast/statements/ContainerStatement.h>
 #include <ast/statements/ResultFileStatement.h>
 #include <ast/statements/ResultVariableStatement.h>
-#include <ast/statements/ResultPrintStatement.h>
 #include <ast/statements/VariableStatement.h>
 #include <ast/statements/ValueStatement.h>
 #include <ast/statements/FileStatement.h>
@@ -15,6 +14,7 @@
 #include <ast/args/BindedArg.h>
 #include <ast/args/ImmediateArg.h>
 
+#include <ast/command/PrintCommand.h>
 #include <ast/command/ExecuteCommand.h>
 #include <ast/command/QuitCommand.h>
 #include <ast/command/EOTCommand.h>
@@ -263,14 +263,19 @@ std::shared_ptr < Statement > Parser::statement ( ) {
 std::shared_ptr < StatementList > Parser::statement_list ( ) {
 	ext::vector < std::shared_ptr < Statement > > list;
 	list.emplace_back ( statement ( ) );
-	while ( check ( cli::Lexer::TokenType::PIPE_SIGN ) ) {
-		match ( cli::Lexer::TokenType::PIPE_SIGN );
-		list.emplace_back ( statement ( ) );
+	while ( check ( cli::Lexer::TokenType::PIPE_SIGN, cli::Lexer::TokenType::MORE_SIGN ) ) {
+		if ( check ( cli::Lexer::TokenType::PIPE_SIGN ) ) {
+			match ( cli::Lexer::TokenType::PIPE_SIGN );
+			list.emplace_back ( statement ( ) );
+		} else {
+			match ( cli::Lexer::TokenType::MORE_SIGN );
+			list.emplace_back ( out_redirect ( ) );
+		}
 	}
 	return std::make_shared < StatementList > ( std::move ( list ) );
 }
 
-void Parser::out_redirect_file ( std::shared_ptr < StatementList > & list ) {
+std::unique_ptr < Statement > Parser::out_redirect_file ( ) {
 	std::unique_ptr < Arg > fileType;
 
 	if ( check ( cli::Lexer::TokenType::LEFT_BRACKET ) ) {
@@ -279,29 +284,16 @@ void Parser::out_redirect_file ( std::shared_ptr < StatementList > & list ) {
 		match ( cli::Lexer::TokenType::RIGHT_BRACKET );
 	}
 
-	list->append ( std::make_unique < ResultFileStatement > ( file ( ), std::move ( fileType ) ) );
+	return std::make_unique < ResultFileStatement > ( file ( ), std::move ( fileType ) );
 }
 
-void Parser::out_redirect ( std::shared_ptr < StatementList > & list ) {
+std::unique_ptr < Statement > Parser::out_redirect ( ) {
 	if ( check ( cli::Lexer::TokenType::DOLAR_SIGN ) ) {
 		match ( cli::Lexer::TokenType::DOLAR_SIGN );
 		std::unique_ptr < Arg > name = arg ( );
-		list->append ( std::make_unique < ResultVariableStatement > ( std::move ( name ) ) );
-	} else if ( check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::EOT, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) {
-		return;
+		return std::make_unique < ResultVariableStatement > ( std::move ( name ) );
 	} else {
-		out_redirect_file ( list );
-	}
-}
-
-void Parser::result ( std::shared_ptr < StatementList > & list ) {
-	if ( check ( cli::Lexer::TokenType::MORE_SIGN ) ) {
-		match ( cli::Lexer::TokenType::MORE_SIGN );
-		out_redirect ( list );
-	} else if ( check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::EOT, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) {
-		list->append ( std::make_unique < ResultPrintStatement > ( ) );
-	} else {
-		return;
+		return out_redirect_file ( );
 	}
 }
 
@@ -381,8 +373,11 @@ std::unique_ptr < Command > Parser::command ( ) {
 	if ( check_nonreserved_kw ( "execute" ) ) {
 		match_nonreserved_kw ( "execute" );
 		std::shared_ptr < StatementList > res = statement_list ( );
-		result ( res );
-		return std::make_unique < ExecuteCommand > ( res );
+		return std::make_unique < ExecuteCommand > ( std::move ( res ) );
+	} else if ( check_nonreserved_kw ( "print" ) ) {
+		match_nonreserved_kw ( "print" );
+		std::shared_ptr < StatementList > res = statement_list ( );
+		return std::make_unique < PrintCommand > ( std::move ( res ) );
 	} else if ( check_nonreserved_kw ( "quit" ) ) {
 		match_nonreserved_kw ( "quit" );
 
diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h
index 87a079185a..4582901935 100644
--- a/alib2cli/src/parser/Parser.h
+++ b/alib2cli/src/parser/Parser.h
@@ -138,11 +138,9 @@ public:
 
 	std::shared_ptr < StatementList > statement_list ( );
 
-	void out_redirect_file ( std::shared_ptr < StatementList > & list );
+	std::unique_ptr < Statement > out_redirect_file ( );
 
-	void out_redirect ( std::shared_ptr < StatementList > & list );
-
-	void result ( std::shared_ptr < StatementList > & list );
+	std::unique_ptr < Statement > out_redirect ( );
 
 	std::pair < bool, bool > introspect_cast_from_to ( );
 
diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp
index 1754bd2c4e..087c0a286e 100644
--- a/alib2cli/test-src/cli/CliTest.cpp
+++ b/alib2cli/test-src/cli/CliTest.cpp
@@ -142,7 +142,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 		abstraction::AlgorithmRegistry::registerAlgorithm < Sink > ( Sink::sink, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 		cli::Environment environment;
-		testLine ( "execute Source | Sink ^ - >", environment );
+		testLine ( "execute Source | Sink ^ -", environment );
 	}
 
 	static std::unique_ptr < int > source;
@@ -170,7 +170,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 		{
 			source = std::make_unique < int > ( 1 );
 			cli::Environment environment;
-			testLine ( "execute RvalueReferenceProvider | RvalueReferenceAcceptor - >", environment );
+			testLine ( "execute RvalueReferenceProvider | RvalueReferenceAcceptor -", environment );
 		}
 
 		CHECK ( * target == 1 );
@@ -180,7 +180,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 			source = std::make_unique < int > ( 1 );
 			cli::Environment environment;
 			CHECK_NOTHROW ( testLine ( "execute RvalueReferenceProvider > $tmp", environment ) );
-			CHECK_NOTHROW ( testLine ( "execute $tmp | RvalueReferenceAcceptor ^ - >", environment ) );
+			CHECK_NOTHROW ( testLine ( "execute $tmp | RvalueReferenceAcceptor ^ -", environment ) );
 		}
 
 		CHECK ( * target == 1 );
@@ -190,7 +190,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 			source = std::make_unique < int > ( 1 );
 			cli::Environment environment;
 			CHECK_NOTHROW ( testLine ( "execute RvalueReferenceProvider > $tmp", environment ) );
-			CHECK_THROWS ( testLine ( "execute $tmp | RvalueReferenceAcceptor - >", environment ) );
+			CHECK_THROWS ( testLine ( "execute $tmp | RvalueReferenceAcceptor -", environment ) );
 		}
 
 	}
@@ -215,7 +215,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 		abstraction::AlgorithmRegistry::registerAlgorithm < ConstReferenceAcceptor > ( ConstReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 		cli::Environment environment;
-		testLine ( "execute ConstReferenceProvider | ConstReferenceAcceptor - >", environment );
+		testLine ( "execute ConstReferenceProvider | ConstReferenceAcceptor -", environment );
 	}
 
 	class ReferenceProvider {
@@ -237,7 +237,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 		abstraction::AlgorithmRegistry::registerAlgorithm < ReferenceAcceptor > ( ReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 		cli::Environment environment;
-		testLine ( "execute ReferenceProvider | ReferenceAcceptor - >", environment );
+		testLine ( "execute ReferenceProvider | ReferenceAcceptor -", environment );
 	}
 
 	class ConstRvalueReferenceProvider {
@@ -260,7 +260,7 @@ TEST_CASE ( "Cli", "[unit][cli]" ) {
 		abstraction::AlgorithmRegistry::registerAlgorithm < ConstRvalueReferenceAcceptor > ( ConstRvalueReferenceAcceptor::bar, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, std::array < std::string, 1 > ( ) );
 
 		cli::Environment environment;
-		testLine ( "execute ConstRvalueReferenceProvider | ConstRvalueReferenceAcceptor ^ - >", environment );
+		testLine ( "execute ConstRvalueReferenceProvider | ConstRvalueReferenceAcceptor ^ -", environment );
 	}
 
 	class Print {
diff --git a/alib2integrationtest/test-src/tests/approximateMatching.cpp b/alib2integrationtest/test-src/tests/approximateMatching.cpp
index ee92126662..82b443b631 100644
--- a/alib2integrationtest/test-src/tests/approximateMatching.cpp
+++ b/alib2integrationtest/test-src/tests/approximateMatching.cpp
@@ -18,7 +18,7 @@ static std::string qPrepareString ( const std::string &file, const std::string &
 }
 
 static std::string qExtendAlphabet ( const std::string & s1, const std::string & s2 ) {
-	return "execute string::GeneralAlphabet::add $" + s1 + " <( string::GeneralAlphabet::get $" + s2 + " ) >";
+	return "execute string::GeneralAlphabet::add $" + s1 + " <( string::GeneralAlphabet::get $" + s2 + " )";
 }
 
 static std::string qGenString ( const size_t & len, const size_t &alph_len, const std::string & var ) {
diff --git a/alib2integrationtest/test-src/tests/exactMatching.cpp b/alib2integrationtest/test-src/tests/exactMatching.cpp
index 41a6c7763d..8266d4a16e 100644
--- a/alib2integrationtest/test-src/tests/exactMatching.cpp
+++ b/alib2integrationtest/test-src/tests/exactMatching.cpp
@@ -10,7 +10,7 @@ const size_t ALPHABET_SIZE = 4;
 const size_t RANDOM_ITERATIONS = 20;
 
 static std::string qExtendAlphabet ( const std::string & s1, const std::string & s2 ) {
-	return "execute string::GeneralAlphabet::add $" + s1 + " <( string::GeneralAlphabet::get $" + s2 + " ) > ";
+	return "execute string::GeneralAlphabet::add $" + s1 + " <( string::GeneralAlphabet::get $" + s2 + " )";
 }
 
 static std::string qGenString ( const size_t & len, const size_t &alph_len, const std::string & var ) {
-- 
GitLab