diff --git a/alib2cli/src/ast/command/CommandResult.h b/alib2cli/src/ast/command/CommandResult.h index afa6d05bf89de1db20aa4b0b56678d7871a3ba51..65282cd23a6ff2ac2dec3bf71d9176f2a30bb2e7 100644 --- a/alib2cli/src/ast/command/CommandResult.h +++ b/alib2cli/src/ast/command/CommandResult.h @@ -6,6 +6,7 @@ namespace cli { enum class CommandResult { OK, QUIT, + RETURN, EXCEPTION, ERROR, EOT diff --git a/alib2cli/src/ast/command/InterpretCommand.h b/alib2cli/src/ast/command/InterpretCommand.h index afd07d79fa8a2f4968684c93cf81d88de5ca81d2..ca3be1733c48e9358e1c62af7c7a0fedcbbebf76 100644 --- a/alib2cli/src/ast/command/InterpretCommand.h +++ b/alib2cli/src/ast/command/InterpretCommand.h @@ -24,7 +24,7 @@ public: CommandResult state = environment.execute ( std::make_shared < cli::IstreamLineInterface < std::ifstream > > ( cli::IstreamLineInterface < std::ifstream > ( std::move ( ifs ) ) ) ); - if ( state != cli::CommandResult::QUIT ) + if ( state != cli::CommandResult::QUIT && state != cli::CommandResult::RETURN ) state = cli::CommandResult::OK; return state; diff --git a/alib2cli/src/ast/command/ReturnCommand.h b/alib2cli/src/ast/command/ReturnCommand.h new file mode 100644 index 0000000000000000000000000000000000000000..9b9de6bcebba6d477e6fc096fba2c7c6eb8afa92 --- /dev/null +++ b/alib2cli/src/ast/command/ReturnCommand.h @@ -0,0 +1,27 @@ +#ifndef _CLI_RETURN_COMMAND_H_ +#define _CLI_RETURN_COMMAND_H_ + +#include <ast/Command.h> +#include <environment/Environment.h> +#include <ast/Statement.h> + +namespace cli { + +class ReturnCommand : public Command { + std::shared_ptr < Statement > m_command; + +public: + ReturnCommand ( std::shared_ptr < Statement > command ) : m_command ( std::move ( command ) ) { + } + + CommandResult run ( Environment & environment ) const override { + if ( m_command ) + environment.setResult ( m_command->translateAndEval ( nullptr, environment ) ); + + return CommandResult::RETURN; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_RETURN_COMMAND_H_ */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 28390505728e46bc2a103cf7da026c617df86c44..cdb6a08063c53a6dcc55cbba2c18acae774d6492 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -34,6 +34,7 @@ #include <ast/command/EvalCommand.h> #include <ast/command/InterpretCommand.h> #include <ast/command/IfCommand.h> +#include <ast/command/ReturnCommand.h> #include <ast/expression/BinaryExpression.h> #include <ast/expression/PrefixExpression.h> @@ -400,6 +401,14 @@ std::unique_ptr < Command > Parser::command ( ) { res = statement_list ( ); return std::make_unique < QuitCommand > ( res ); + } else if ( check_nonreserved_kw ( "return" ) ) { + match_nonreserved_kw ( "return" ); + + std::shared_ptr < StatementList > res; + if ( ! check ( cli::Lexer::TokenType::EOS, cli::Lexer::TokenType::EOT, cli::Lexer::TokenType::SEMICOLON_SIGN ) ) + res = statement_list ( ); + + return std::make_unique < ReturnCommand > ( res ); } else if ( check_nonreserved_kw ( "help" ) ) { match_nonreserved_kw ( "help" ); std::unique_ptr < cli::Arg > command = optional_arg ( ); diff --git a/aql2/src/aql.cpp b/aql2/src/aql.cpp index 28afac30ae1626dc45759b035de56e4c07bf8cd6..9ea7e17add3df37c7a978b786833f7e5eeb22e06 100644 --- a/aql2/src/aql.cpp +++ b/aql2/src/aql.cpp @@ -162,9 +162,9 @@ int main ( int argc, char * argv[] ) { /* --------------------------------------------------------------------------------------------------------- */ - if ( res == cli::CommandResult::QUIT ) + if ( res == cli::CommandResult::QUIT || res == cli::CommandResult::RETURN ) return cli::ResultInterpret::cli ( Prompt::getPrompt ( ).getEnvironment ( ).getResult ( ) ); - else if ( res == cli::CommandResult::EOT ) + else if ( res == cli::CommandResult::EOT || res == cli::CommandResult::OK ) return 0; else return 4; diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp index 926b13a4f139189f6c3c467a20de757ad671cd3c..f7e26beb4e4bde39c8008c9f9f1f197d983e611a 100644 --- a/aql2/src/prompt/Prompt.cpp +++ b/aql2/src/prompt/Prompt.cpp @@ -11,15 +11,19 @@ Prompt::Prompt ( cli::Environment environment ) : m_environment ( std::move ( en } cli::CommandResult Prompt::run ( ) { + cli::CommandResult res = cli::CommandResult::OK; + while ( ! m_lineInterfaces.empty ( ) ) { cli::CommandResult state = getEnvironment ( ).execute ( m_lineInterfaces.front ( ) ); if ( state == cli::CommandResult::QUIT ) return state; + if ( state == cli::CommandResult::RETURN ) + res = cli::CommandResult::RETURN; m_lineInterfaces.pop_front ( ); } - return cli::CommandResult::OK; + return res; }