aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--clc.cc120
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
)
diff --git a/clc.cc b/clc.cc
index 5eb0d9e..9c029e4 100644
--- a/clc.cc
+++ b/clc.cc
@@ -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;
+ }
}