diff options
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | clc.cc | 120 |
2 files changed, 115 insertions, 14 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index dabc978..763be29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ add_library( ) add_executable( - test + tests test.cc ) @@ -26,7 +26,7 @@ add_executable( ) target_link_libraries( - test + tests SimpleParser gtest ) @@ -34,9 +34,10 @@ target_link_libraries( target_link_libraries( clc SimpleParser + boost_program_options ) add_custom_command( - TARGET test - POST_BUILD COMMAND ./test + TARGET tests + POST_BUILD COMMAND ./tests ) @@ -1,22 +1,122 @@ +#include <boost/optional.hpp> +#include <boost/program_options.hpp> + #include <iostream> #include <limits> #include "src/parser.h" -typedef std::numeric_limits<double> dbl; +boost::optional<boost::program_options::variables_map> input( + int argc, + char** argv +) { + boost::program_options::options_description optionDescription( + "Supported options" + ); + + optionDescription.add_options() + ( + "input", + boost::program_options::value<std::vector<std::string>>(), + "terms to be evaluated" + ) + ( + "tree", + boost::program_options::value<bool>()->implicit_value(true), + "return the binary expression tree instead of evaluating" + ) + ; + + boost::program_options::variables_map variables; + + try { + boost::program_options::store( + boost::program_options::parse_command_line( + argc, argv, optionDescription + ), + variables + ); + + boost::program_options::notify(variables); + } + catch ( const std::exception& exception ) { + std::cerr << exception.what() << std::endl; + std::cout << optionDescription << std::endl; + + return boost::optional<boost::program_options::variables_map>(); + } + + return boost::make_optional(variables); +} + +bool process(const boost::program_options::variables_map& variables) { + const bool replMode{ variables.count("input") == 0 }; + const bool treeMode{ variables.count("tree") ? variables["tree"].as<bool>() + : false }; + + if ( replMode ) { + std::cout.precision( + std::numeric_limits<double>::digits10 + ); + + std::string term; + + while ( std::cin >> term ) { + try { + if ( treeMode) { + std::cout << SimpleParser::print(term); + } else { + std::cout << SimpleParser::calculate(term); + } + + std::cout << std::endl; + } + catch ( std::exception &exception ) { + std::cerr << exception.what() << std::endl; + } + } + + return true; + } else { + const std::vector<std::string> inputTerms{ + variables["input"].as<std::vector<std::string>>() + }; -int main() { - std::string inputTerm; - std::cout.precision(dbl::digits10); - - while ( std::cin >> inputTerm ) { try { - std::cout << SimpleParser::calculate(inputTerm) << std::endl; + std::for_each( + inputTerms.cbegin(), + inputTerms.cend(), + [treeMode](const std::string& term) { + if ( treeMode) { + std::cout << SimpleParser::print(term); + } else { + std::cout << term + << " = " + << SimpleParser::calculate(term); + } + + std::cout << std::endl; + } + ); } - catch ( std::exception &e ) { - std::cerr << e.what() << std::endl; + catch ( std::exception &exception ) { + std::cerr << exception.what() << std::endl; + + return false; } + + return true; } +} - return 0; +int main(int argc, char** argv) { + if ( auto variables = input(argc, argv) ) { + if ( process(*variables) ) { + return 0; + } else { + return 1; + } + } else { + return 1; + } } |