diff --git a/alib2cli/src/command/CommandList.h b/alib2cli/src/command/CommandList.h new file mode 100644 index 0000000000000000000000000000000000000000..ecfb42f0f81b9ea29f69958fc1c49f57ee76c4e2 --- /dev/null +++ b/alib2cli/src/command/CommandList.h @@ -0,0 +1,34 @@ +#ifndef _CLI_COMMAND_LIST_H_ +#define _CLI_COMMAND_LIST_H_ + +#include <command/Command.h> + +namespace cli { + +class CommandList final : public Command { + ext::vector < std::unique_ptr < Command > > m_commands; + +public: + CommandList ( ext::vector < std::unique_ptr < Command > > commands ) : m_commands ( std::move ( commands ) ) { + } + + Command::Result run ( Environment & environment ) const override { + if ( m_commands.empty ( ) ) + throw std::invalid_argument ( "Command list can't be empty" ); + + Command::Result res = Command::Result::OK; + for ( size_t i = 0; i < m_commands.size ( ) && res == Command::Result::OK; ++ i ) + res = m_commands [ i ]->run ( environment ); + + return res; + } + + void append ( std::unique_ptr < Command > command ) { + m_commands.emplace_back ( std::move ( command ) ); + } + +}; + +} /* namespace cli */ + +#endif /* _CLI_COMMAND_LIST_H_ */ diff --git a/alib2cli/src/lexer/Lexer.cpp b/alib2cli/src/lexer/Lexer.cpp index 48e23090c6da64e5bc1e05db175b3b1b42f94500..2c44d09b3c73e46747928c91d4f3b25abb0a3049 100644 --- a/alib2cli/src/lexer/Lexer.cpp +++ b/alib2cli/src/lexer/Lexer.cpp @@ -113,6 +113,12 @@ q0: if ( m_source->isEndOfTransmition ( ) ) { res.m_type = TokenType::COLON_SIGN; return res; } + if ( m_source->getCharacter ( ) == ';' ) { + res.m_raw += m_source->getCharacter ( ); + m_source->advance ( readNextLine ); + res.m_type = TokenType::SEMICOLON_SIGN; + return res; + } if ( m_source->getCharacter ( ) == '=' ) { res.m_raw += m_source->getCharacter ( ); m_source->advance ( readNextLine ); diff --git a/alib2cli/src/lexer/Lexer.h b/alib2cli/src/lexer/Lexer.h index ff23c37e27e048cd0cbe4932231517fd25bda6d4..9a6c9baf9f0f71346428d0d180fb0c2ddbe50264 100644 --- a/alib2cli/src/lexer/Lexer.h +++ b/alib2cli/src/lexer/Lexer.h @@ -44,6 +44,7 @@ public: PIPE_SIGN, CARET_SIGN, COLON_SIGN, + SEMICOLON_SIGN, DASH_SIGN, EQUAL_SIGN, HASH_SIGN, @@ -90,6 +91,8 @@ public: return "caret_sign"; case TokenType::COLON_SIGN : return "colon_sign"; + case TokenType::SEMICOLON_SIGN : + return "semicolon_sign"; case TokenType::DASH_SIGN : return "dash_sign"; case TokenType::EQUAL_SIGN : diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index ca72b598bd71c62d3af8e6baf4117e918edb45d5..48e51675b27cced3ec35f11ae988108d86e352b6 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -240,7 +240,7 @@ std::shared_ptr < Statement > Parser::statement ( ) { std::unique_ptr < CategoryOption > category = category_option ( ); ext::vector < std::shared_ptr < Statement > > params; ext::vector < bool > moves; - while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::EOS ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) ) { + while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::EOS ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) && ! check ( cli::Lexer::TokenType::SEMICOLON_SIGN ) ) { moves.push_back ( move_arg ( ) ); params.emplace_back ( param ( ) ); } @@ -266,7 +266,7 @@ std::shared_ptr < StatementList > Parser::statement_list ( ) { match ( cli::Lexer::TokenType::PIPE_SIGN ); list.emplace_back ( statement ( ) ); } - return std::make_shared < StatementList > ( list ); + return std::make_shared < StatementList > ( std::move ( list ) ); } void Parser::out_redirect_file ( std::shared_ptr < StatementList > & list ) { @@ -286,7 +286,7 @@ void Parser::out_redirect ( std::shared_ptr < StatementList > & list ) { 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 ) ) { + } else if ( check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) { return; } else { out_redirect_file ( list ); @@ -297,7 +297,7 @@ void Parser::result ( std::shared_ptr < StatementList > & list ) { if ( check ( cli::Lexer::TokenType::OUT_REDIRECT ) ) { match ( cli::Lexer::TokenType::OUT_REDIRECT ); out_redirect ( list ); - } else if ( check ( cli::Lexer::TokenType::EOS ) ) { + } else if ( check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) { list->append ( std::make_unique < ResultPrintStatement > ( ) ); } else { return; @@ -359,40 +359,46 @@ std::unique_ptr < Command > Parser::introspect_command ( ) { } } -std::unique_ptr < Command > Parser::parse ( ) { +std::unique_ptr < CommandList > Parser::parse ( ) { + ext::vector < std::unique_ptr < Command > > list; + list.emplace_back ( command ( ) ); + while ( check ( cli::Lexer::TokenType::SEMICOLON_SIGN ) ) { + match ( cli::Lexer::TokenType::SEMICOLON_SIGN ); + list.emplace_back ( command ( ) ); + } + match ( cli::Lexer::TokenType::EOS ); + return std::make_unique < CommandList > ( std::move ( list ) ); +} + +std::unique_ptr < Command > Parser::command ( ) { if ( check_nonreserved_kw ( "execute" ) ) { match_nonreserved_kw ( "execute" ); std::shared_ptr < StatementList > res = statement_list ( ); result ( res ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < ExecuteCommand > ( res ); } else if ( check_nonreserved_kw ( "quit" ) ) { match_nonreserved_kw ( "quit" ); std::shared_ptr < StatementList > res; - if ( ! check ( cli::Lexer::TokenType::EOS ) ) + if ( ! check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) res = statement_list ( ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < QuitCommand > ( res ); } else if ( check_nonreserved_kw ( "exit" ) ) { match_nonreserved_kw ( "exit" ); std::shared_ptr < StatementList > res; - if ( ! check ( cli::Lexer::TokenType::EOS ) ) + if ( ! check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) res = statement_list ( ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < QuitCommand > ( res ); } else if ( check_nonreserved_kw ( "help" ) ) { match_nonreserved_kw ( "help" ); std::unique_ptr < cli::Arg > command = optional_arg ( ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < HelpCommand > ( std::move ( command ) ); } else if ( check_nonreserved_kw ( "introspect" ) ) { match_nonreserved_kw ( "introspect" ); std::unique_ptr < Command > command = introspect_command ( ); - match ( cli::Lexer::TokenType::EOS ); return command; } else if ( check_nonreserved_kw ( "set" ) ) { match_nonreserved_kw ( "set" ); @@ -400,19 +406,16 @@ std::unique_ptr < Command > Parser::parse ( ) { match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER ); std::string value = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < SetCommand > ( std::move ( param ), std::move ( value ) ); } else if ( check_nonreserved_kw ( "load" ) ) { match_nonreserved_kw ( "load" ); std::string libraryName = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < LoadCommand > ( std::move ( libraryName ) ); } else if ( check_nonreserved_kw ( "unload" ) ) { match_nonreserved_kw ( "unload" ); std::string libraryName = getTokenValue ( ); match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING ); - match ( cli::Lexer::TokenType::EOS ); return std::make_unique < UnloadCommand > ( std::move ( libraryName ) ); } else if ( check ( cli::Lexer::TokenType::EOT ) ) { return std::make_unique < QuitCommand > ( nullptr ); diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index 3e5695c4b1bda39ad68ac510f7593ec9a7e7675d..d0f63a0cb7f8d904f80b3a6e1a92c4f3a4afa357 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -8,7 +8,7 @@ #include <ast/options/TypeOption.h> #include <ast/options/CategoryOption.h> -#include <command/Command.h> +#include <command/CommandList.h> #include <ast/statements/StatementList.h> @@ -152,7 +152,9 @@ public: std::unique_ptr < Command > introspect_command ( ); - std::unique_ptr < Command > parse ( ); + std::unique_ptr < Command > command ( ); + + std::unique_ptr < CommandList > parse ( ); };