From a81219a232cbb74e00c42006fb619c345f58002d Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 7 Sep 2017 20:46:34 +0200 Subject: [PATCH] add support for type hinting in file statement --- alib2cli/src/ast/Option.h | 2 ++ alib2cli/src/ast/options/CategoryOption.h | 4 +++ alib2cli/src/ast/options/HL3Option.h | 4 +++ alib2cli/src/ast/options/TypeOption.h | 4 +++ .../ast/statements/ContainerFileStatement.h | 1 - .../src/ast/statements/ContainerStatement.cpp | 2 ++ .../src/ast/statements/ContainerStatement.h | 3 -- alib2cli/src/ast/statements/FileStatement.cpp | 29 +++++++++++++++++++ alib2cli/src/ast/statements/FileStatement.h | 17 +++++------ alib2cli/src/parser/Parser.cpp | 13 ++++++++- alib2cli/test-src/cli/CliTest.cpp | 3 ++ .../src/abstraction/PrimitiveRegistrator.cpp | 3 ++ .../src/abstraction/XmlParserRegistry.hpp | 8 +++-- 13 files changed, 77 insertions(+), 16 deletions(-) create mode 100644 alib2cli/src/ast/statements/FileStatement.cpp diff --git a/alib2cli/src/ast/Option.h b/alib2cli/src/ast/Option.h index 8e3febebbf..32b9916620 100644 --- a/alib2cli/src/ast/Option.h +++ b/alib2cli/src/ast/Option.h @@ -5,6 +5,7 @@ #include <ast/statements/SingleStatement.h> #include <ast/statements/ContainerStatement.h> #include <ast/statements/ContainerFileStatement.h> +#include <ast/statements/FileStatement.h> namespace cli { @@ -16,6 +17,7 @@ public: virtual void eval ( SingleStatement & statement ) const = 0; virtual void eval ( ContainerStatement & statement ) const = 0; virtual void eval ( ContainerFileStatement & statement ) const = 0; + virtual void eval ( FileStatement & statement ) const = 0; }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/CategoryOption.h b/alib2cli/src/ast/options/CategoryOption.h index defe21f658..85d8bf3dbe 100644 --- a/alib2cli/src/ast/options/CategoryOption.h +++ b/alib2cli/src/ast/options/CategoryOption.h @@ -25,6 +25,10 @@ public: virtual void eval ( ContainerFileStatement & ) const override { throw exception::CommonException ( "ContainerFileStatement cannot be categorized." ); } + + virtual void eval ( FileStatement & ) const override { + throw exception::CommonException ( "FileStatement cannot be categorized." ); + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/HL3Option.h b/alib2cli/src/ast/options/HL3Option.h index 405e63ba48..6dba5a8131 100644 --- a/alib2cli/src/ast/options/HL3Option.h +++ b/alib2cli/src/ast/options/HL3Option.h @@ -18,6 +18,10 @@ public: virtual void eval ( ContainerFileStatement & ) const override { std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl; } + + virtual void eval ( FileStatement & ) const override { + std::cout << "The cake is a lie, as well as the release date of HL3. GLaDOS told me." << std::endl; + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/options/TypeOption.h b/alib2cli/src/ast/options/TypeOption.h index f9f06d8cb9..f70d309500 100644 --- a/alib2cli/src/ast/options/TypeOption.h +++ b/alib2cli/src/ast/options/TypeOption.h @@ -24,6 +24,10 @@ public: virtual void eval ( ContainerFileStatement & statement ) const override { statement.setType ( m_type ); } + + virtual void eval ( FileStatement & statement ) const override { + statement.setType ( m_type ); + } }; } /* namespace cli */ diff --git a/alib2cli/src/ast/statements/ContainerFileStatement.h b/alib2cli/src/ast/statements/ContainerFileStatement.h index 962eec43b7..e2e2d88c31 100644 --- a/alib2cli/src/ast/statements/ContainerFileStatement.h +++ b/alib2cli/src/ast/statements/ContainerFileStatement.h @@ -2,7 +2,6 @@ #define _CLI_CONTAINER_FILE_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> namespace cli { diff --git a/alib2cli/src/ast/statements/ContainerStatement.cpp b/alib2cli/src/ast/statements/ContainerStatement.cpp index 4b14caf0d0..9751550f2a 100644 --- a/alib2cli/src/ast/statements/ContainerStatement.cpp +++ b/alib2cli/src/ast/statements/ContainerStatement.cpp @@ -3,6 +3,8 @@ #include <ast/Param.h> #include <ast/Arg.h> #include <abstraction/common/CastHelper.h> +#include <exception/CommonException.h> +#include <iostream> namespace cli { diff --git a/alib2cli/src/ast/statements/ContainerStatement.h b/alib2cli/src/ast/statements/ContainerStatement.h index 83930e6aff..35b97849d3 100644 --- a/alib2cli/src/ast/statements/ContainerStatement.h +++ b/alib2cli/src/ast/statements/ContainerStatement.h @@ -2,9 +2,6 @@ #define _CLI_CONTAINER_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> -#include <exception/CommonException.h> -#include <iostream> namespace cli { diff --git a/alib2cli/src/ast/statements/FileStatement.cpp b/alib2cli/src/ast/statements/FileStatement.cpp new file mode 100644 index 0000000000..9b8768ab8d --- /dev/null +++ b/alib2cli/src/ast/statements/FileStatement.cpp @@ -0,0 +1,29 @@ +#include <ast/statements/FileStatement.h> +#include <ast/Statement.h> +#include <ast/Option.h> +#include <ast/Arg.h> +#include <abstraction/Registry.h> + +namespace cli { + +FileStatement::FileStatement ( ext::vector < std::unique_ptr < Option > > options, std::unique_ptr < Arg > file ) : m_file ( std::move ( file ) ), m_options ( std::move ( options ) ) { + for ( const std::unique_ptr < Option > & option : m_options ) { + option->eval ( * this ); + } +} + +std::shared_ptr < abstraction::OperationAbstraction > FileStatement::translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const { + ext::deque < sax::Token > tokens = sax::FromXMLParserHelper::parseInput ( m_file->eval ( environment ) ); + + std::string type = m_type; + if ( type == "" ) + type = tokens [ 0 ].getData ( ); + + return abstraction::Registry::getXmlParserAbstraction ( type, tokens ); +} + +void FileStatement::setType ( std::string type ) { + m_type = std::move ( type ); +} + +} /* namespace cli */ diff --git a/alib2cli/src/ast/statements/FileStatement.h b/alib2cli/src/ast/statements/FileStatement.h index a430175887..cc3828577e 100644 --- a/alib2cli/src/ast/statements/FileStatement.h +++ b/alib2cli/src/ast/statements/FileStatement.h @@ -2,22 +2,21 @@ #define _CLI_FILE_STATEMENT_H_ #include <ast/Statement.h> -#include <abstraction/Registry.h> namespace cli { class FileStatement final : public Statement { std::unique_ptr < cli::Arg > m_file; + ext::vector < std::unique_ptr < Option > > m_options; + + std::string m_type; public: - FileStatement ( std::unique_ptr < Arg > file ) : m_file ( std::move ( file ) ) { - } - - virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const override { - ext::deque < sax::Token > tokens = sax::FromXMLParserHelper::parseInput ( m_file->eval ( environment ) ); - std::string type = tokens [ 0 ].getData ( ); - return abstraction::Registry::getXmlParserAbstraction ( type, tokens ); - } + FileStatement ( ext::vector < std::unique_ptr < Option > > options, std::unique_ptr < Arg > file ); + + virtual std::shared_ptr < abstraction::OperationAbstraction > translateAndEval ( const std::shared_ptr < abstraction::OperationAbstraction > &, Environment & environment ) const override; + + void setType ( std::string type ); }; } /* namespace cli */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 69e808981c..b153b061ca 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -200,8 +200,19 @@ std::shared_ptr < Statement > Parser::in_redirect_statement ( ) { std::unique_ptr < Arg > file = arg ( ); return std::make_shared < ContainerFileStatement > ( "Set", std::move ( options ), std::move ( file ) ); } else { + ext::vector < std::unique_ptr < Option > > options; + while ( check ( cli::Lexer::TokenType::COLON_SIGN ) ) { + match ( cli::Lexer::TokenType::COLON_SIGN ); + std::unique_ptr < Option > res = type_option ( ); + if ( ! res ) + res = option ( ); + if ( ! res ) + throw exception::CommonException ( "Option not recognised" ); + options.emplace_back ( std::move ( res ) ); + } + std::unique_ptr < Arg > file = arg ( ); - return std::make_shared < FileStatement > ( std::move ( file ) ); + return std::make_shared < FileStatement > ( std::move ( options ), std::move ( file ) ); } } diff --git a/alib2cli/test-src/cli/CliTest.cpp b/alib2cli/test-src/cli/CliTest.cpp index c7e34789d3..7aac735909 100644 --- a/alib2cli/test-src/cli/CliTest.cpp +++ b/alib2cli/test-src/cli/CliTest.cpp @@ -96,6 +96,9 @@ void CliTest::testCreateUnique ( ) { parser = cli::Parser ( cli::Lexer ( "execute One | Add <( Add (int) <#2 <(One) ) - | Neg (double) - | Divide (double) - <(One | (double) Add <(One) - )" ) ); parser.parse ( )->run ( environment ); + parser = cli::Parser ( cli::Lexer ( "execute <:type int #2" ) ); + parser.parse ( )->run ( environment ); + parser = cli::Parser ( cli::Lexer ( "execute One > $res" ) ); parser.parse ( )->run ( environment ); diff --git a/alib2common/src/abstraction/PrimitiveRegistrator.cpp b/alib2common/src/abstraction/PrimitiveRegistrator.cpp index c02d2f8471..7752bd3166 100644 --- a/alib2common/src/abstraction/PrimitiveRegistrator.cpp +++ b/alib2common/src/abstraction/PrimitiveRegistrator.cpp @@ -7,6 +7,7 @@ #include <abstraction/CastRegistry.hpp> #include <abstraction/XmlFileWriterRegistry.hpp> +#include <abstraction/XmlParserRegistry.hpp> #include <abstraction/NormalizeRegistry.hpp> #include <abstraction/ValuePrinterRegistry.hpp> #include <abstraction/ImmediateRegistry.hpp> @@ -44,6 +45,8 @@ public: abstraction::ContainerRegistry::registerSet < int > ( ); + abstraction::XmlParserRegistry::registerXmlParser < int > ( "int" ); + abstraction::XmlFileWriterRegistry::registerXmlFileWriter < int > ( ); abstraction::XmlFileWriterRegistry::registerXmlFileWriter < double > ( ); abstraction::XmlFileWriterRegistry::registerXmlFileWriter < std::string > ( ); diff --git a/alib2common/src/abstraction/XmlParserRegistry.hpp b/alib2common/src/abstraction/XmlParserRegistry.hpp index 7adf27a9d0..eef86abb62 100644 --- a/alib2common/src/abstraction/XmlParserRegistry.hpp +++ b/alib2common/src/abstraction/XmlParserRegistry.hpp @@ -38,11 +38,15 @@ class XmlParserRegistry { } public: + template < class ReturnType > + static void registerXmlParser ( std::string result ) { + getEntries ( ).insert ( std::make_pair ( result, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) ); + } + template < class ReturnType > static void registerXmlParser ( ) { std::string ret = alib::xmlApi < ReturnType >::xmlTagName ( ); - - getEntries ( ).insert ( std::make_pair ( ret, std::unique_ptr < Entry > ( new EntryImpl < ReturnType > ( ) ) ) ); + registerXmlParser < ReturnType > ( ret ); } static std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( const std::string & typeName, ext::deque < sax::Token > tokens ); -- GitLab