From 76c79971d6adfa6d09a7d70010c0429a5adf03ae Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 17 Aug 2017 09:31:24 +0200 Subject: [PATCH] more complex introspection command --- ...and.h => AlgorithmsIntrospectionCommand.h} | 12 ++--- .../src/command/CastsIntrospectionCommand.h | 31 ++++++++++++ .../command/DataTypesIntrospectionCommand.h | 30 ++++++++++++ alib2cli/src/command/HelpCommand.h | 2 +- alib2cli/src/parser/Parser.cpp | 48 +++++++++++++++++-- alib2cli/src/parser/Parser.h | 4 ++ alib2common/src/abstraction/CastRegistry.hpp | 28 +++++++++++ alib2common/src/abstraction/Registry.cpp | 18 ++++++- alib2common/src/abstraction/Registry.h | 8 +++- .../src/abstraction/XmlFileWriterRegistry.hpp | 13 +++++ 10 files changed, 181 insertions(+), 13 deletions(-) rename alib2cli/src/command/{IntrospectionCommand.h => AlgorithmsIntrospectionCommand.h} (57%) create mode 100644 alib2cli/src/command/CastsIntrospectionCommand.h create mode 100644 alib2cli/src/command/DataTypesIntrospectionCommand.h diff --git a/alib2cli/src/command/IntrospectionCommand.h b/alib2cli/src/command/AlgorithmsIntrospectionCommand.h similarity index 57% rename from alib2cli/src/command/IntrospectionCommand.h rename to alib2cli/src/command/AlgorithmsIntrospectionCommand.h index bd3599f5f3..7fb1c2f979 100644 --- a/alib2cli/src/command/IntrospectionCommand.h +++ b/alib2cli/src/command/AlgorithmsIntrospectionCommand.h @@ -1,23 +1,23 @@ -#ifndef _CLI_INTROSPECTION_COMMAND_H_ -#define _CLI_INTROSPECTION_COMMAND_H_ +#ifndef _CLI_ALGORITHMS_INTROSPECTION_COMMAND_H_ +#define _CLI_ALGORITHMS_INTROSPECTION_COMMAND_H_ #include <command/Command.h> #include <environment/Environment.h> namespace cli { -class IntrospectionCommand : public Command { +class AlgorithmsIntrospectionCommand : public Command { std::string m_param; public: - IntrospectionCommand ( std::string param ) : m_param ( std::move ( param ) ) { + AlgorithmsIntrospectionCommand ( std::string param ) : m_param ( std::move ( param ) ) { } virtual Command::Result run ( Environment & ) const override { if ( m_param == "" ) { abstraction::Registry::listAlgorithms ( ); } else if ( m_param.find ( "::", m_param.size ( ) - 2 ) != std::string::npos ) { - abstraction::Registry::listGroup ( m_param ); + abstraction::Registry::listAlgorithmGroup ( m_param ); } else { abstraction::Registry::listAlgorithmOverloads ( m_param ); } @@ -27,4 +27,4 @@ public: } /* namespace cli */ -#endif /* _CLI_INTROSPECTION_COMMAND_H_ */ +#endif /* _CLI_ALGORITHMS_INTROSPECTION_COMMAND_H_ */ diff --git a/alib2cli/src/command/CastsIntrospectionCommand.h b/alib2cli/src/command/CastsIntrospectionCommand.h new file mode 100644 index 0000000000..72fee3f740 --- /dev/null +++ b/alib2cli/src/command/CastsIntrospectionCommand.h @@ -0,0 +1,31 @@ +#ifndef _CLI_CAST_INTROSPECTION_COMMAND_H_ +#define _CLI_CAST_INTROSPECTION_COMMAND_H_ + +#include <command/Command.h> +#include <environment/Environment.h> + +namespace cli { + +class CastsIntrospectionCommand : public Command { + std::string m_param; + bool m_from; + bool m_to; + +public: + CastsIntrospectionCommand ( std::string param, bool from, bool to ) : m_param ( std::move ( param ) ), m_from ( from ), m_to ( to ) { + } + + virtual Command::Result run ( Environment & ) const override { + if ( m_from ) + abstraction::Registry::listCastsFrom ( m_param ); + + if ( m_to ) + abstraction::Registry::listCastsTo ( m_param ); + + return Command::Result::OK; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_CAST_INTROSPECTION_COMMAND_H_ */ diff --git a/alib2cli/src/command/DataTypesIntrospectionCommand.h b/alib2cli/src/command/DataTypesIntrospectionCommand.h new file mode 100644 index 0000000000..0eb6686fee --- /dev/null +++ b/alib2cli/src/command/DataTypesIntrospectionCommand.h @@ -0,0 +1,30 @@ +#ifndef _CLI_DATA_TYPE_INTROSPECTION_COMMAND_H_ +#define _CLI_DATA_TYPE_INTROSPECTION_COMMAND_H_ + +#include <command/Command.h> +#include <environment/Environment.h> + +namespace cli { + +class DataTypesIntrospectionCommand : public Command { + std::string m_param; + +public: + DataTypesIntrospectionCommand ( std::string param ) : m_param ( std::move ( param ) ) { + } + + virtual Command::Result run ( Environment & ) const override { + if ( m_param == "" ) { + abstraction::Registry::listDataTypes ( ); + } else if ( m_param.find ( "::", m_param.size ( ) - 2 ) != std::string::npos ) { + abstraction::Registry::listDataTypeGroup ( m_param ); + } else { + throw exception::CommonException ( "Invalid DataType introspection param" ); + } + return Command::Result::OK; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_DATA_TYPE_INTROSPECTION_COMMAND_H_ */ diff --git a/alib2cli/src/command/HelpCommand.h b/alib2cli/src/command/HelpCommand.h index 28c34aa388..b88e3f835d 100644 --- a/alib2cli/src/command/HelpCommand.h +++ b/alib2cli/src/command/HelpCommand.h @@ -58,7 +58,7 @@ public: std::cout << "" << std::endl; std::cout << "command quit: quits the processor." << std::endl; std::cout << "command help: shows this help." << std::endl; - std::cout << "command introspect: prints available algorithms and algorithm overloads." << std::endl; + std::cout << "command introspect: prints available algorithms, algorithm overloads, casts, and datatypes." << std::endl; std::cout << "command execute: executes statements" << std::endl; std::cout << "" << std::endl; std::cout << "for details use help of individual command" << std::endl; diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index aa853d2b60..1645afcea0 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -23,7 +23,9 @@ #include <command/ExecuteCommand.h> #include <command/QuitCommand.h> #include <command/HelpCommand.h> -#include <command/IntrospectionCommand.h> +#include <command/AlgorithmsIntrospectionCommand.h> +#include <command/DataTypesIntrospectionCommand.h> +#include <command/CastsIntrospectionCommand.h> #include <command/SetCommand.h> #include <ast/options/HL3Option.h> @@ -184,6 +186,46 @@ std::string Parser::optional_identifier ( ) { } } +std::pair < bool, bool > Parser::introspect_cast_from_to ( ) { + bool from; + bool to; + while ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { + match ( cli::Lexer::TokenType::COLON_SIGN ); + if ( check_nonreserved_kw ( "from" ) ) { + match_nonreserved_kw ( "from" ); + from = true; + } else if ( check_nonreserved_kw ( "to" ) ) { + match_nonreserved_kw ( "to" ); + from = true; + } else { + throw exception::CommonException ( "Mismatched set while expanding param introspect_cast_from_to." ); + } + } + return std::make_pair ( from, to ); +} + +std::unique_ptr < Command > Parser::introspect_command ( ) { + if ( check_nonreserved_kw ( "algorithms" ) ) { + match_nonreserved_kw ( "algorithms" ); + std::string param = optional_identifier ( ); + match ( cli::Lexer::TokenType::END ); + return std::make_unique < AlgorithmsIntrospectionCommand > ( std::move ( param ) ); + } else if ( check_nonreserved_kw ( "datatypes" ) ) { + match_nonreserved_kw ( "datatypes" ); + std::string param = optional_identifier ( ); + match ( cli::Lexer::TokenType::END ); + return std::make_unique < DataTypesIntrospectionCommand > ( std::move ( param ) ); + } else if ( check_nonreserved_kw ( "casts" ) ) { + match_nonreserved_kw ( "casts" ); + std::pair < bool, bool > from_to = introspect_cast_from_to ( ); + std::string param = optional_identifier ( ); + match ( cli::Lexer::TokenType::END ); + return std::make_unique < CastsIntrospectionCommand > ( std::move ( param ), from_to.first, from_to.second ); + } else { + throw exception::CommonException ( "Mismatched set while expanding param introspect_command." ); + } +} + std::unique_ptr < Command > Parser::parse ( ) { if ( check_nonreserved_kw ( "execute" ) ) { match_nonreserved_kw ( "execute" ); @@ -202,9 +244,7 @@ std::unique_ptr < Command > Parser::parse ( ) { return std::make_unique < HelpCommand > ( std::move ( command ) ); } else if ( check_nonreserved_kw ( "introspect" ) ) { match_nonreserved_kw ( "introspect" ); - std::string command = optional_identifier ( ); - match ( cli::Lexer::TokenType::END ); - return std::make_unique < IntrospectionCommand > ( std::move ( command ) ); + return introspect_command ( ); } else if ( check_nonreserved_kw ( "set" ) ) { match_nonreserved_kw ( "set" ); std::string param = matchIdentifier ( ); diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index fba9a74222..4fce5ef617 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -91,6 +91,10 @@ public: std::string optional_identifier ( ); + std::pair < bool, bool > introspect_cast_from_to ( ); + + std::unique_ptr < Command > introspect_command ( ); + std::unique_ptr < Command > parse ( ); }; diff --git a/alib2common/src/abstraction/CastRegistry.hpp b/alib2common/src/abstraction/CastRegistry.hpp index c038829132..0e7ea037c8 100644 --- a/alib2common/src/abstraction/CastRegistry.hpp +++ b/alib2common/src/abstraction/CastRegistry.hpp @@ -138,6 +138,34 @@ public: return getAbstraction ( target, param, normalize ); } + static void listFrom ( const std::string & type ) { + std::set < std::string > sourceTypes; + if ( alib::namingApi::hasTypes ( type ) ) + sourceTypes = ext::transform < std::string > ( alib::namingApi::getTypes ( type ), [ ] ( const ext::type_index & type ) { return ext::to_string ( type ); } ); + else + sourceTypes.insert ( type ); + + for ( const std::pair < const std::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry : getEntries ( ) ) { + if ( sourceTypes.count ( entry.first.first ) ) { + std::cout << entry.first.second << std::endl; + } + } + } + + static void listTo ( const std::string & type ) { + std::set < std::string > targetTypes; + if ( alib::namingApi::hasTypes ( type ) ) + targetTypes = ext::transform < std::string > ( alib::namingApi::getTypes ( type ), [ ] ( const ext::type_index & type ) { return ext::to_string ( type ); } ); + else + targetTypes.insert ( type ); + + for ( const std::pair < const std::pair < std::string, std::string >, std::unique_ptr < Entry > > & entry : getEntries ( ) ) { + if ( targetTypes.count ( entry.first.second ) ) { + std::cout << entry.first.first << std::endl; + } + } + } + }; } /* namespace abstraction */ diff --git a/alib2common/src/abstraction/Registry.cpp b/alib2common/src/abstraction/Registry.cpp index a997f9a36b..179b436b1e 100644 --- a/alib2common/src/abstraction/Registry.cpp +++ b/alib2common/src/abstraction/Registry.cpp @@ -18,7 +18,7 @@ namespace abstraction { -void Registry::listGroup ( const std::string & group ) { +void Registry::listAlgorithmGroup ( const std::string & group ) { AlgorithmRegistry::listGroup ( group ); } @@ -30,6 +30,22 @@ void Registry::listAlgorithms ( ) { AlgorithmRegistry::list ( ); } +void Registry::listDataTypes ( ) { + XmlFileWriterRegistry::list ( ); +} + +void Registry::listDataTypeGroup ( const std::string & group ) { + XmlFileWriterRegistry::listGroup ( group ); +} + +void Registry::listCastsFrom ( const std::string & type ) { + CastRegistry::listFrom ( type ); +} + +void Registry::listCastsTo ( const std::string & type ) { + CastRegistry::listTo ( type ); +} + std::shared_ptr < abstraction::OperationAbstraction > Registry::getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes ) { return AlgorithmRegistry::getAbstraction ( name, paramTypes ); } diff --git a/alib2common/src/abstraction/Registry.h b/alib2common/src/abstraction/Registry.h index 4b096583fb..677da32a05 100644 --- a/alib2common/src/abstraction/Registry.h +++ b/alib2common/src/abstraction/Registry.h @@ -14,10 +14,16 @@ namespace abstraction { class Registry { public: - static void listGroup ( const std::string & algorithm ); + static void listAlgorithmGroup ( const std::string & group ); static void listAlgorithmOverloads ( const std::string & algorithm ); static void listAlgorithms ( ); + static void listDataTypes ( ); + static void listDataTypeGroup ( const std::string & group ); + + static void listCastsFrom ( const std::string & type ); + static void listCastsTo ( const std::string & type ); + static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes ); static std::shared_ptr < abstraction::OperationAbstraction > getAlgorithmAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, bool & unwrap, bool & normalize ); static std::shared_ptr < abstraction::OperationAbstraction > getCastAbstraction ( const std::string & target, const std::string & param, bool & normalize ); diff --git a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp index f603838df5..963639dbec 100644 --- a/alib2common/src/abstraction/XmlFileWriterRegistry.hpp +++ b/alib2common/src/abstraction/XmlFileWriterRegistry.hpp @@ -56,6 +56,19 @@ public: return res->second->getAbstraction ( std::move ( filename ) ); } + + static void listGroup ( const std::string & group ) { + for ( const std::pair < const std::string, std::unique_ptr < Entry > > & entry : getEntries ( ) ) { + if ( entry.first.find ( group ) == 0 ) //found at the begining + std::cout << entry.first << std::endl; + } + } + + static void list ( ) { + for ( const std::pair < const std::string, std::unique_ptr < Entry > > & entry : getEntries ( ) ) { + std::cout << entry.first << std::endl; + } + } }; } /* namespace abstraction */ -- GitLab