From e4da49eae9296abc3bc85eee93d4430f3660d048 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 5 Sep 2017 15:12:30 +0200
Subject: [PATCH] revise cli options+use in algorithm categorisation

---
 alib2cli/src/ast/options/CategoryOption.h     | 24 +++++++++++++++++++
 alib2cli/src/ast/options/HL3Option.h          |  4 ++--
 .../src/ast/statements/SingleStatement.cpp    |  8 +++++--
 alib2cli/src/ast/statements/SingleStatement.h |  7 +++---
 alib2cli/src/parser/Parser.cpp                | 21 ++++++++++++++--
 alib2cli/src/parser/Parser.h                  |  6 +++--
 alib2cli/test-src/cli/CliTest.cpp             |  1 -
 7 files changed, 59 insertions(+), 12 deletions(-)
 create mode 100644 alib2cli/src/ast/options/CategoryOption.h

diff --git a/alib2cli/src/ast/options/CategoryOption.h b/alib2cli/src/ast/options/CategoryOption.h
new file mode 100644
index 0000000000..594a587d6f
--- /dev/null
+++ b/alib2cli/src/ast/options/CategoryOption.h
@@ -0,0 +1,24 @@
+#ifndef _CLI_CATEGORY_OPTION_H_
+#define _CLI_CATEGORY_OPTION_H_
+
+#include <ast/Option.h>
+#include <abstraction/common/AlgorithmCategories.hpp>
+#include <exception/CommonException.h>
+
+namespace cli {
+
+class CategoryOption final : public Option {
+	std::string m_key;
+
+public:
+	CategoryOption ( std::string key ) : m_key ( std::move ( key ) ) {
+	}
+
+	virtual void eval ( SingleStatement & statement ) const override {
+		statement.setCategory ( abstraction::AlgorithmCategories::algorithmCategory ( m_key ) );
+	}
+};
+
+} /* namespace cli */
+
+#endif /* _CLI_CATEGORY_OPTION_H_ */
diff --git a/alib2cli/src/ast/options/HL3Option.h b/alib2cli/src/ast/options/HL3Option.h
index 90b3bea7de..1a362e520f 100644
--- a/alib2cli/src/ast/options/HL3Option.h
+++ b/alib2cli/src/ast/options/HL3Option.h
@@ -7,8 +7,8 @@ namespace cli {
 
 class HL3Option final : public Option {
 public:
-	virtual void eval ( SingleStatement & statement ) const override {
-		statement.setHL3 ( );
+	virtual void eval ( SingleStatement & ) const override {
+		std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl;
 	}
 };
 
diff --git a/alib2cli/src/ast/statements/SingleStatement.cpp b/alib2cli/src/ast/statements/SingleStatement.cpp
index c8d0e1f89b..832b24924f 100644
--- a/alib2cli/src/ast/statements/SingleStatement.cpp
+++ b/alib2cli/src/ast/statements/SingleStatement.cpp
@@ -6,7 +6,7 @@
 
 namespace cli {
 
-SingleStatement::SingleStatement ( std::unique_ptr < Arg > name, ext::vector < std::unique_ptr < Param > > params, ext::vector < std::unique_ptr < Option > > options ) : m_name ( std::move ( name ) ), m_params ( std::move ( params ) ), m_options ( std::move ( options ) ) {
+SingleStatement::SingleStatement ( std::unique_ptr < Arg > name, ext::vector < std::unique_ptr < Param > > params, ext::vector < std::unique_ptr < Option > > options ) : m_name ( std::move ( name ) ), m_params ( std::move ( params ) ), m_options ( std::move ( options ) ), m_category ( abstraction::AlgorithmCategories::AlgorithmCategory::NONE ) {
 	for ( const std::unique_ptr < Option > & option : m_options ) {
 		option->eval ( * this );
 	}
@@ -25,7 +25,11 @@ std::shared_ptr < abstraction::OperationAbstraction > SingleStatement::translate
 
 	std::string name = m_name->eval ( environment );
 
-	return abstraction::AlgorithmHelper::eval ( name, params, moves, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT );
+	return abstraction::AlgorithmHelper::eval ( name, params, moves, m_category );
+}
+
+void SingleStatement::setCategory ( abstraction::AlgorithmCategories::AlgorithmCategory category ) {
+	m_category = category;
 }
 
 } /* namespace cli */
diff --git a/alib2cli/src/ast/statements/SingleStatement.h b/alib2cli/src/ast/statements/SingleStatement.h
index 3697c03beb..87ab9f9213 100644
--- a/alib2cli/src/ast/statements/SingleStatement.h
+++ b/alib2cli/src/ast/statements/SingleStatement.h
@@ -5,6 +5,7 @@
 #include <abstraction/Registry.h>
 #include <exception/CommonException.h>
 #include <iostream>
+#include <abstraction/common/AlgorithmCategories.hpp>
 
 namespace cli {
 
@@ -13,14 +14,14 @@ class SingleStatement final : public Statement {
 	ext::vector < std::unique_ptr < Param > > m_params;
 	ext::vector < std::unique_ptr < Option > > m_options;
 
+	abstraction::AlgorithmCategories::AlgorithmCategory m_category;
+
 public:
 	SingleStatement ( std::unique_ptr < cli::Arg > name, ext::vector < std::unique_ptr < Param > > params, ext::vector < std::unique_ptr < Option > > options );
 
 	virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > & prev, Environment & environment ) const override;
 
-	void setHL3 ( ) {
-		std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl;
-	}
+	void setCategory ( abstraction::AlgorithmCategories::AlgorithmCategory category );
 };
 
 } /* namespace cli */
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index b5544c541d..bdce7cfa47 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -31,19 +31,30 @@
 #include <command/SetCommand.h>
 
 #include <ast/options/HL3Option.h>
+#include <ast/options/CategoryOption.h>
 
 #include <primitive/Integer.h>
 #include <primitive/String.h>
 
 namespace cli {
 
+std::unique_ptr < Option > Parser::category_option ( ) {
+	if ( check_nonreserved_kw ( "default", "test", "efficient", "student" ) ) {
+		std::string value = getTokenValue ( );
+		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER );
+		return std::make_unique < CategoryOption > ( value );
+	} else {
+		return nullptr;
+	}
+}
+
 std::unique_ptr < Option > Parser::option ( ) {
 	match ( cli::Lexer::TokenType::COLON_SIGN );
 	if ( check_nonreserved_kw ( "hl3" ) ) {
 		match_nonreserved_kw ( "hl3" );
 		return std::make_unique < HL3Option > ( );
 	} else {
-		throw exception::CommonException ( "Mismatched set while expanding option rule." );
+		return nullptr;
 	}
 }
 
@@ -178,7 +189,13 @@ std::shared_ptr < Statement > Parser::single_statement ( ) {
 		std::unique_ptr < Arg > name = std::make_unique < ImmediateArg > ( matchIdentifier ( ) );
 		ext::vector < std::unique_ptr < Option > > options;
 		while ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) {
-			options.emplace_back ( option ( ) );
+			match ( cli::Lexer::TokenType::COLON_SIGN );
+			std::unique_ptr < Option > res = category_option ( );
+			if ( ! res )
+				res = option ( );
+			if ( ! res )
+				throw exception::CommonException ( "Option not recognised" );
+			options.emplace_back ( std::move ( res ) );
 		}
 		ext::vector < std::unique_ptr < Param > > params;
 		while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::END ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) ) {
diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h
index 79d88125e6..8d6a709b6d 100644
--- a/alib2cli/src/parser/Parser.h
+++ b/alib2cli/src/parser/Parser.h
@@ -32,8 +32,9 @@ public:
 		return ext::orAll ( m_current.m_type == tokens ... );
 	}
 
-	bool check_nonreserved_kw ( const std::string & kw ) const {
-		return m_current.m_type == Lexer::TokenType::IDENTIFIER && m_current.m_value == kw;
+	template < class ... NonreservedTokens >
+	bool check_nonreserved_kw ( const NonreservedTokens & ... kw ) const {
+		return m_current.m_type == Lexer::TokenType::IDENTIFIER && ext::orAll ( m_current.m_value == kw ... );
 	}
 
 	template < class ... Tokens >
@@ -79,6 +80,7 @@ public:
 		return m_current.m_value;
 	}
 
+	std::unique_ptr < Option > category_option ( );
 	std::unique_ptr < Option > option ( );
 
 	std::unique_ptr < Arg > arg ( );
diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp
index 98a1e32981..e86f8daf2d 100644
--- a/alib2cli/test-src/cli/CliTest.cpp
+++ b/alib2cli/test-src/cli/CliTest.cpp
@@ -237,4 +237,3 @@ void CliTest::testConstRvalueReferencePassing ( ) {
 	cli::Parser parser ( cli::Lexer ( "execute ConstRvalueReferenceProvider | ConstRvalueReferenceAcceptor ^ - >" ) );
 	parser.parse ( )->run ( environment );
 }
-
-- 
GitLab