#include #include #include #include #include "expression.hpp" template concept Dereferenceable = requires(T t) { {(bool)t}; {*t}; }; namespace { bool print_result(Dereferenceable auto&& value, std::ostream& out) { if (value) { out << *value << std::endl; return true; } return false; } bool print_result(auto&& value, std::ostream& out) { out << value << std::endl; return true; } void program_loop(std::istream& in, std::ostream& out, std::ostream& err) { std::string line; while (std::getline(in, line)) { if (line == "exit") { break; } auto e = parse_expression(line); // or change this to parser.parse_expression(line); if (!e) { err << "Parsing failed" << std::endl; continue; } auto result = e->evaluate(); if (!print_result(result, out)) err << "Evaluation failed" << std::endl; } } } // namespace int main(int argc, char* argv[]) try { std::vector args(argv + 1, argv + argc); if (args.empty()) { program_loop(std::cin, std::cout, std::cerr); } else { for (const auto& arg : args) { std::ifstream file(arg); if (file) { program_loop(file, std::cout, std::cerr); } else { std::cerr << "Failed to open file: " << arg << std::endl; } } } return 0; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } catch (...) { std::cerr << "Unknown error" << std::endl; return 2; }