From 501b847551a259484ef0c9d9f6237aa4819c3772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Tr=C3=A1vn=C3=AD=C4=8Dek?= <jan.travnicek@fit.cvut.cz> Date: Wed, 5 Jan 2022 12:34:58 +0100 Subject: [PATCH] cli: delegate value interpretation in if and while to the result interpreter --- alib2cli/src/ast/command/IfCommand.h | 3 +- alib2cli/src/ast/command/WhileCommand.h | 3 +- alib2cli/src/common/ResultInterpret.h | 45 ++++++++++++++++++------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/alib2cli/src/ast/command/IfCommand.h b/alib2cli/src/ast/command/IfCommand.h index 144c5294e7..7fc5cc197e 100644 --- a/alib2cli/src/ast/command/IfCommand.h +++ b/alib2cli/src/ast/command/IfCommand.h @@ -4,6 +4,7 @@ #include <environment/Environment.h> #include <ast/Statement.h> #include <common/CastHelper.h> +#include <common/ResultInterpret.h> namespace cli { @@ -21,7 +22,7 @@ public: std::shared_ptr < abstraction::Value > castedResult = abstraction::CastHelper::eval ( environment, conditionResult, "bool" ); - if ( std::static_pointer_cast < abstraction::ValueHolderInterface < bool > > ( castedResult )->getValue ( ) ) + if ( cli::ResultInterpret::value < bool > ( castedResult ) ) return m_thenBranch->run ( environment ); else if ( m_elseBranch != nullptr ) return m_elseBranch->run ( environment ); diff --git a/alib2cli/src/ast/command/WhileCommand.h b/alib2cli/src/ast/command/WhileCommand.h index 359844f9aa..adf9a7005f 100644 --- a/alib2cli/src/ast/command/WhileCommand.h +++ b/alib2cli/src/ast/command/WhileCommand.h @@ -4,6 +4,7 @@ #include <environment/Environment.h> #include <ast/Statement.h> #include <common/CastHelper.h> +#include <common/ResultInterpret.h> namespace cli { @@ -22,7 +23,7 @@ public: std::shared_ptr < abstraction::Value > castedResult = abstraction::CastHelper::eval ( environment, conditionResult, "bool" ); - if ( ! std::static_pointer_cast < abstraction::ValueHolderInterface < bool > > ( castedResult )->getValue ( ) ) + if ( ! cli::ResultInterpret::value < bool > ( castedResult ) ) break; res = m_body->run ( environment ); diff --git a/alib2cli/src/common/ResultInterpret.h b/alib2cli/src/common/ResultInterpret.h index fea7f077ff..a2ffea34cd 100644 --- a/alib2cli/src/common/ResultInterpret.h +++ b/alib2cli/src/common/ResultInterpret.h @@ -7,25 +7,46 @@ namespace cli { class ResultInterpret { + template < class T > + static std::optional < T > tryInterpretation ( std::shared_ptr < abstraction::Value > result ) { + std::shared_ptr < abstraction::ValueHolderInterface < T > > ptr = std::dynamic_pointer_cast < abstraction::ValueHolderInterface < T > > ( result ); + if ( ptr ) + return ptr->getValue ( ); + else + return std::nullopt; + } + public: static int cli ( const std::shared_ptr < abstraction::Value > & result ) { if ( result ) { - std::shared_ptr < abstraction::ValueHolderInterface < int > > ptr1 = std::dynamic_pointer_cast < abstraction::ValueHolderInterface < int > > ( result ); - if ( ptr1 ) - return ptr1->getValue ( ); - std::shared_ptr < abstraction::ValueHolderInterface < unsigned > > ptr2 = std::dynamic_pointer_cast < abstraction::ValueHolderInterface < unsigned > > ( result ); - if ( ptr2 ) - return static_cast < int > ( ptr2->getValue ( ) ); - std::shared_ptr < abstraction::ValueHolderInterface < bool > > ptr3 = std::dynamic_pointer_cast < abstraction::ValueHolderInterface < bool > > ( result ); - if ( ptr3 ) - return static_cast < int > ( ! ptr3->getValue ( ) ); - - throw exception::CommonException ( "Invalid result type. Provided: " + result->getType ( ) ); + std::optional < int > res1 = tryInterpretation < int > ( result ); + if ( res1 ) + return res1.value ( ); + + std::optional < bool > res2 = tryInterpretation < bool > ( result ); + if ( res2 ) + return static_cast < int > ( ! res2.value ( ) ); + + std::optional < unsigned > res3 = tryInterpretation < unsigned > ( result ); + if ( res3 ) + return static_cast < int > ( res3.value ( ) ); + + throw exception::CommonException ( "Invalid result type. Provided: " + ext::to_string ( result->getType ( ) ) ); } else { return 0; } } + + template < class T > + static T value ( std::shared_ptr < abstraction::Value > result ) { + if ( result ) { + std::optional < T > res = tryInterpretation < T > ( result ); + if ( res ) + return res.value ( ); + } + + throw exception::CommonException ( "Type " + ext::to_string < T > ( ) + " not provided, instead " + ext::to_string ( result->getType ( ) ) + " provided." ); + } }; } /* namespace cli */ - -- GitLab