From 72355b2352f19f67398849f3f3bbb27b977ee769 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 14 Nov 2019 08:15:17 +0100 Subject: [PATCH] if command --- alib2cli/src/ast/command/IfCommand.h | 36 ++++++++++++++++++++++++++++ alib2cli/src/parser/Parser.cpp | 19 +++++++++++++++ alib2cli/src/parser/Parser.h | 4 ++++ 3 files changed, 59 insertions(+) create mode 100644 alib2cli/src/ast/command/IfCommand.h diff --git a/alib2cli/src/ast/command/IfCommand.h b/alib2cli/src/ast/command/IfCommand.h new file mode 100644 index 0000000000..a0375242ea --- /dev/null +++ b/alib2cli/src/ast/command/IfCommand.h @@ -0,0 +1,36 @@ +#ifndef _CLI_IF_COMMAND_H_ +#define _CLI_IF_COMMAND_H_ + +#include <ast/Command.h> +#include <environment/Environment.h> +#include <ast/Statement.h> +#include <common/CastHelper.h> + +namespace cli { + +class IfCommand : public Command { + std::unique_ptr < Expression > m_condition; + std::unique_ptr < Command > m_thenBranch; + std::unique_ptr < Command > m_elseBranch; + +public: + IfCommand ( std::unique_ptr < Expression > condition, std::unique_ptr < Command > thenBranch, std::unique_ptr < Command > elseBranch ) : m_condition ( std::move ( condition ) ), m_thenBranch ( std::move ( thenBranch ) ), m_elseBranch ( std::move ( elseBranch ) ) { + } + + CommandResult run ( Environment & environment ) const override { + std::shared_ptr < abstraction::Value > conditionResult = m_condition->translateAndEval ( environment ); + + std::shared_ptr < abstraction::Value > castedResult = abstraction::CastHelper::eval ( environment, conditionResult, "bool" ); + + if ( std::static_pointer_cast < abstraction::ValueHolderInterface < bool > > ( castedResult )->getValue ( ) ) + return m_thenBranch->run ( environment ); + else if ( m_elseBranch != nullptr ) + return m_elseBranch->run ( environment ); + + return cli::CommandResult::OK; + } +}; + +} /* namespace cli */ + +#endif /* _CLI_IF_COMMAND_H_ */ diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp index 2d62f5eea7..2839050572 100644 --- a/alib2cli/src/parser/Parser.cpp +++ b/alib2cli/src/parser/Parser.cpp @@ -33,6 +33,7 @@ #include <ast/command/BlockCommand.h> #include <ast/command/EvalCommand.h> #include <ast/command/InterpretCommand.h> +#include <ast/command/IfCommand.h> #include <ast/expression/BinaryExpression.h> #include <ast/expression/PrefixExpression.h> @@ -450,6 +451,24 @@ std::unique_ptr < Command > Parser::command ( ) { match ( cli::Lexer::TokenType::FILE, cli::Lexer::TokenType::STRING ); return std::make_unique < InterpretCommand > ( std::move ( fileName ) ); + } else if ( check_nonreserved_kw ( "if" ) ) { + if ( globalScope ( ) ) + throw exception::CommonException ( "Statement not available in global scope." ); + match_nonreserved_kw ( "if" ); + match ( cli::Lexer::TokenType::LEFT_PAREN ); + std::unique_ptr < Expression > condition = assign_expression ( ); + match ( cli::Lexer::TokenType::RIGHT_PAREN ); + + match_nonreserved_kw ( "then" ); + std::unique_ptr < Command > thenBranch = semicolon_command ( ); + + std::unique_ptr < Command > elseBranch; + if ( check_nonreserved_kw ( "else" ) ) { + match_nonreserved_kw ( "else" ); + elseBranch = semicolon_command ( ); + } + + return std::make_unique < IfCommand > ( std::move ( condition ), std::move ( thenBranch ), std::move ( elseBranch ) ); } else { throw exception::CommonException ( "Mismatched set " + ext::to_string ( getCheckOptions ( ) ) + " while expanding parse rule. Token is " + ( ( std::string ) m_current ) + "." ); } diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h index c7a97844fe..d5770d3a10 100644 --- a/alib2cli/src/parser/Parser.h +++ b/alib2cli/src/parser/Parser.h @@ -149,6 +149,10 @@ public: -- m_forceLexerReadNext; } + bool globalScope ( ) { + return m_forceLexerReadNext == 0; + } + std::unique_ptr < Expression > assign_expression ( ); std::unique_ptr < Expression > or_expression ( ); -- GitLab